Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jest-html-reporter

Package Overview
Dependencies
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jest-html-reporter - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

121

index.js

@@ -6,3 +6,2 @@ const path = require('path');

const stripAnsi = require('strip-ansi');
const defaultStylesheet = require('./style');

@@ -21,3 +20,2 @@

}
/**

@@ -28,29 +26,20 @@ * Creates a file at the given destination

*/
const writeFile = (filePath, content) => mkdirp(path.dirname(filePath), (err) => {
if (err) {
return console.log(`Jest-HTML-Reporter: Something went wrong when creating the file: ${err}`);
}
return fs.writeFile(filePath, content);
const writeFile = (filePath, content) => new Promise((resolve, reject) => {
mkdirp(path.dirname(filePath), (err) => !err ? resolve(fs.writeFile(filePath, content)) : reject(`Something went wrong when creating the file: ${err}`));
});
/**
* Fetches the stylesheet to be imported in the test report.
* If the styleOverridePath fil cannot be found, it will respond with the default stylesheet.
* Returns the stylesheet to be imported in the test report.
* If styleOverridePath is not defined, it will return the default stylesheet (style.js).
* @param {String} filePath
* @return {Promise}
*/
const getStylesheet = () => {
return new Promise((resolve, reject) => {
// If the styleOverridePath has not been set, return the default stylesheet.
if (!config.styleOverridePath) { resolve(defaultStylesheet); }
// Attempt to read the given file
fs.readFile(config.styleOverridePath, 'utf8', (err, content) => {
// If there were no errors, return the content of the given file.
// Otherwise resolve the promise with the default stylesheet.
const response = !err ? content : defaultStylesheet;
resolve(response);
});
const getStylesheet = () => new Promise((resolve, reject) => {
// If the styleOverridePath has not been set, return the default stylesheet (style.js).
if (!config.styleOverridePath) { return resolve(defaultStylesheet); }
// Attempt to read the given file
fs.readFile(config.styleOverridePath, 'utf8', (err, content) => {
// If there were no errors, return the content of the given file.
return !err ? resolve(content) : reject(`Could not find the specified styleOverridePath: '${config.styleOverridePath}'`);
});
};
});
/**

@@ -72,30 +61,27 @@ * Sets up a basic HTML page to apply the content to

});
/**
* Returns a HTML containing the test report.
* @param {String} stylesheet
* @param {Object} data The test result data
* @param {Object} testData The test result data
* @return {xmlbuilder}
*/
const renderHTMLReport = ({ stylesheet, data }) => {
// Create HTML and Body tags
const renderHTMLReport = (testData, stylesheet) => new Promise((resolve, reject) => {
// Create an xmlbuilder object with HTML and Body tags
const htmlOutput = createHtml(stylesheet);
// Timestamp
htmlOutput.ele('div', { id: 'timestamp' }, `
Start: ${(new Date(data.startTime)).toLocaleString()}
`);
htmlOutput.ele('div', { id: 'timestamp' }, `Start: ${(new Date(testData.startTime)).toLocaleString()}`);
// Test Summary
htmlOutput.ele('div', { id: 'summary' }, `
${data.numTotalTests} tests /
${data.numPassedTests} passed /
${data.numFailedTests} failed /
${data.numPendingTests} skipped
${testData.numTotalTests} tests /
${testData.numPassedTests} passed /
${testData.numFailedTests} failed /
${testData.numPendingTests} pending
`);
// Loop through each suite
data.testResults.forEach((suite) => {
if (suite.testResults.length <= 0) { return; }
// Suite File Path
// Loop through each test suite
testData.testResults.forEach((suite) => {
if (!suite.testResults || suite.testResults.length <= 0) { return; }
// Suite filepath location
htmlOutput.ele('div', { class: 'suite-info' }, `
${suite.testFilePath}
(${(suite.perfStats.end - suite.perfStats.start) / 1000}s)
${suite.testFilePath} (${(suite.perfStats.end - suite.perfStats.start) / 1000}s)
`);

@@ -107,24 +93,22 @@ // Suite Test Table

const testTr = suiteTable.ele('tr', { class: test.status });
// Suite Name(s)
testTr.ele('td', { class: 'suite' }, test.ancestorTitles.join(' > '));
// Test name
const testTitleTd = testTr.ele('td', { class: 'test' }, test.title);
// Test Failure Messages
if (test.failureMessages && config.includeFailureMsg) {
failureMsgDiv = testTitleTd.ele('div', { class: 'failureMessages' })
test.failureMessages.forEach((failureMsg) => {
failureMsgDiv.ele('p', { class: 'failureMsg' }, stripAnsi(failureMsg));
});
}
// Test Result
testTr.ele('td', { class: 'result' }, (test.status === 'passed') ?
`${test.status} in ${test.duration / 1000}s`
: test.status
);
// Suite Name(s)
testTr.ele('td', { class: 'suite' }, test.ancestorTitles.join(' > '));
// Test name
const testTitleTd = testTr.ele('td', { class: 'test' }, test.title);
// Test Failure Messages
if (test.failureMessages && config.includeFailureMsg) {
failureMsgDiv = testTitleTd.ele('div', { class: 'failureMessages' })
test.failureMessages.forEach((failureMsg) => {
failureMsgDiv.ele('p', { class: 'failureMsg' }, stripAnsi(failureMsg));
});
}
// Test Result
testTr.ele('td', { class: 'result' }, (test.status === 'passed') ?
`${test.status} in ${test.duration / 1000}s`
: test.status
);
});
});
// Send back the rendered HTML
return htmlOutput;
};
return resolve(htmlOutput);
});
/**

@@ -134,11 +118,10 @@ * Main Export

module.exports = (testResult) => {
getStylesheet().then(stylesheet => {
// Render the HTML report
const htmlReport = renderHTMLReport({ stylesheet, data: testResult });
// Write the report to the destination file
writeFile(config.outputPath || path.join(process.cwd(), 'test-report.html'), htmlReport);
// Finish up
console.log('Jest HTML report generated.');
return testResult;
});
// Define location for report output
const reportOutputLocation = config.outputPath || path.join(process.cwd(), 'test-report.html');
// Run
getStylesheet()
.then(renderHTMLReport.bind(null, testResult))
.then(writeFile.bind(null, reportOutputLocation))
.then(() => console.log('\x1b[32m', `jest-html-reporter >> Report generated (${reportOutputLocation})`))
.catch(error => console.log('\x1b[31m', `jest-html-reporter [error] >> ${error}`));
};
{
"name": "jest-html-reporter",
"version": "0.2.0",
"version": "0.3.0",
"description": "Jest test results processor for generating a summary in HTML",

@@ -17,2 +17,3 @@ "main": "index.js",

"reporter",
"report",
"plugin"

@@ -28,3 +29,3 @@ ],

"mkdirp": "0.5.1",
"strip-ansi": "^3.0.1",
"strip-ansi": "3.0.1",
"xmlbuilder": "8.2.2"

@@ -31,0 +32,0 @@ },

@@ -1,70 +0,17 @@

module.exports = () => `
html, body {
font-family: Arial, Helvetica, sans-serif;
font-size: 1rem;
margin: 0;
padding: 0;
color: #333;
}
body {
padding: 1rem 2rem;
font-size: 0.85rem;
}
#timestamp {
font-weight: bold;
color: #666;
margin-bottom: 0.5rem;
}
#summary {
color: #999;
margin-bottom: 1em;
}
.suite-info {
padding: 1em;
background-color: #eee;
border-bottom: 2px solid #999;
font-weight: bold;
color: #999;
}
.suite-table {
width: 100%;
font-size: 0.85rem;
margin-bottom: 1em;
}
.suite-table td {
padding: 0.5rem;
}
.suite-table tr.passed {
background-color: #DFF2BF;
color: #4F8A10;
}
.suite-table tr.pending {
background-color: #FEEFB3;
color: #9F6000;
}
.suite-table tr.failed {
background-color: #FFBABA;
color: #D8000C;
}
.suite-table td {
font-size: 0.85rem;
border-bottom: 1px solid #aaa;
vertical-align: top;
}
.suite-table td.suite {
font-weight: bold;
width: 20%;
}
.suite-table td.test {
font-style: italic;
width: 60%;
}
.suite-table td.test .failureMsg {
font-weight: bold;
font-size: 0.7rem;
}
.suite-table td.result {
width: 20%;
text-align: right;
}
module.exports = () =>`
html,body {font-family:Arial,Helvetica,sans-serif;font-size:1rem;margin:0;padding:0;color:#333;}
body {padding:1rem;2rem;font-size:0.85rem;}
#timestamp {font-weight:bold;color:#666;margin-bottom:0.5rem;}
#summary {color:#999;margin-bottom:1em;}
.suite-info {padding:1em;background-color:#eee;border-bottom:2px solid #999;font-weight:bold;color:#999;}
.suite-table {width:100%;font-size:0.85rem;margin-bottom:1em;}
.suite-table td {padding:0.5rem;}
.suite-table tr.passed {background-color:#DFF2BF;color:#4F8A10;}
.suite-table tr.pending {background-color:#FEEFB3;color:#9F6000;}
.suite-table tr.failed {background-color:#FFBABA;color:#D8000C;}
.suite-table td {font-size:0.85rem;border-bottom:1px solid #aaa;vertical-align:top;}
.suite-table td.suite {font-weight:bold;width:20%;}
.suite-table td.test {font-style:italic;width:60%;}
.suite-table td.test .failureMsg {font-weight:bold;font-size:0.7rem;}
.suite-table td.result {width:20%;text-align:right;}
`;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc