jest-html-reporter 2.2.0 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,29 +28,29 @@ npm install jest-html-reporter --save-dev
28
28
  ```
29
29
 
30
30
  ## Usage
31
- Configure Jest to process the test results by adding the following entry to the Jest config (jest.config.js):
31
+ Configure Jest to process the test results by adding the following entry to the Jest config (jest.config.json):
32
32
  ```JSON
33
- {
34
- "testResultsProcessor": "./node_modules/jest-html-reporter"
35
- }
36
- ```
37
- Then when you run Jest from within the terminal, a file called *test-report.html* will be created within your root folder containing information about your tests.
38
-
39
- #### Alternative usage with package.json
40
- Although jest.config.js is specifically created for configuring Jest (and not this plugin), it is possible to configure Jest from within package.json by adding the following as a new line:
41
- ```JSON
42
- "jest": {"testResultsProcessor": "./node_modules/jest-html-reporter" }
33
+ "reporters": [
34
+ "default",
35
+ ["./node_modules/jest-html-reporter", {
36
+ "pageTitle": "Test Report"
37
+ }]
38
+ ]
43
39
  ```
40
+ As you run Jest from within the terminal, a file called *test-report.html* will be created within your root folder containing information about your tests.
44
41
 
45
- ### Run as a Custom Reporter
46
- It is also possible to run jest-html-reporter as a custom reporter within Jest. This allows the plugin to be run in parallel with Jest instead of after a test run, and will guarantee that the test report is generated even if Jest is run with options such as `--forceExit`.
47
-
48
- Add the following entry to the Jest config (jest.config.js):
42
+ There are multiple configuration options available. To read more about these, please refer to the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/configuration).
49
43
 
44
+ ### Alternative Usage as a Test Results Processor
45
+ To run the reporter as a test results processor (after Jest is complete instead of running in parallel), add the following entry to the Jest config (jest.config.json):
50
46
  ```JSON
51
- "reporters": ["default", "./node_modules/jest-html-reporter"]
52
- ```
53
- Please note that you need to add the `"executionMode": "reporter"` configuration within jesthtmlreporter.config.json in order for this to work (more information on configuration can be found within the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/configuration)).
47
+ {
48
+ "testResultsProcessor": "./node_modules/jest-html-reporter"
49
+ }
50
+ ```
51
+
52
+ **Note:** When running as a testResultsProcessor, the configuration needs be placed within a new file named `jesthtmlreporter.config.json` residing in the root folder.
53
+ More information about this can be found in the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/configuration).
54
54
 
55
55
 
56
56
  ## Node Compatibility
@@ -59,48 +59,23 @@ This plugin is compatible with Node version `^4.8.3`
59
59
  ---
60
60
 
61
61
  ## Configuration
62
- To configure this plugin, create a file named `jesthtmlreporter.config.json` in the root folder of the project. Please note that all configuration properties are optional.
62
+ Please note that all configuration properties are optional.
63
63
 
64
64
  | Property | Type | Description | Default
65
65
  |--|--|--|--|
66
66
  | `pageTitle` | `STRING` | The title of the document. This string will also be outputted on the top of the page. | `"Test Suite"`
67
67
  | `outputPath` | `STRING` | The path to where the plugin will output the HTML report. The path must include the filename and end with .html | `"./test-report.html"`
68
68
  | `includeFailureMsg` | `BOOLEAN` | If this setting is set to true, this will output the detailed failure message for each failed test. | `false`
69
+ | `includeConsoleLog` | `BOOLEAN` | If set to true, this will output all triggered console logs for each test suite. | `false`
69
70
  | `styleOverridePath` | `STRING` | The path to a file containing CSS styles that should override the default styling.* | `null`
70
71
  | `customScriptPath` | `STRING` | Path to a javascript file that should be injected into the test report | `null`
71
- | `theme` | `STRING` | The name of the reporter themes to use when rendering the report. You can find the available themes in the [Documentation](https://github.com/Hargne/jest-html-reporter/wiki/Test-Report-Themes) | `"defaultTheme"`
72
+ | `theme` | `STRING` | The name of the reporter themes to use when rendering the report. You can find the available themes in the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/Test-Report-Themes) | `"defaultTheme"`
72
73
  | `logo` | `STRING` | Path to a logo that will be included in the header of the report | `null`
73
74
  | `executionTimeWarningThreshold` | `NUMBER` | The threshold for test execution time (in seconds) in each test suite that will render a warning on the report page. 5 seconds is the default timeout in Jest. | `5`
74
- | `dateFormat` | `STRING` | The format in which date/time should be formatted in the test report. Have a look in the [Documentation](https://github.com/Hargne/jest-html-reporter/wiki/Date-Format) for the available date format variables. | `"yyyy-mm-dd HH:MM:ss"`
75
- | `sort` | `STRING` | Sorts the test results using the given method. Available sorting methods can be found in the [Documentation](https://github.com/Hargne/jest-html-reporter/wiki/Sorting-Methods). | `"default"`
76
- | `executionMode` | `STRING` | Defines the execution mode. Avaiable modes are: `reporter`, `testResultsProcessor` | `"testResultsProcessor"`
75
+ | `dateFormat` | `STRING` | The format in which date/time should be formatted in the test report. Have a look in the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/Date-Format) for the available date format variables. | `"yyyy-mm-dd HH:MM:ss"`
76
+ | `sort` | `STRING` | Sorts the test results using the given method. Available sorting methods can be found in the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/Sorting-Methods). | `"default"`
77
77
 
78
- #### *A note on styleOverridePath
79
- The plugin will search for the file from the root directory, therefore there is no need to prepend the string with `./` or `../`. Please have a look at the default styling (located within *style/defaultTheme.css*) for a reference of the elements available for styling.
80
-
81
- ### Example Configuration
82
-
83
- ```
84
- {
85
- "pageTitle": "Your test suite",
86
- "outputPath": "test-report/index.html",
87
- "includeFailureMsg": true,
88
- "styleOverridePath": "src/teststyle.css"
89
- }
90
- ```
91
-
92
- #### Alternative configuration with package.json
93
- Add an entry named *"jest-html-reporter"* to your package.json
94
- ```
95
- {
96
- ...
97
- "jest-html-reporter": {
98
- "pageTitle": "Your test suite",
99
- "outputPath": "test-report.html",
100
- "includeFailureMsg": true
101
- }
102
- }
103
- ```
78
+ > *The plugin will search for the *styleOverridePath* from the root directory, therefore there is no need to prepend the string with `./` or `../` - You can read more about the themes in the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/Test-Report-Themes).
104
79
 
105
80
  ---
106
81
 
@@ -118,5 +93,5 @@ export JEST_HTML_REPORTER_PAGE_TITLE="$BRANCH_NAME"\ Test\ Report
118
93
  ```
119
94
 
120
95
  ### Configuration Environment Variables
121
- The environment variables reflect the properties set in the JSON configuration file. Please read the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/configuration#configuration-environment-variables) for more information on these variables.
96
+ The environment variables reflect the configuration options available in JSON format. Please read the [documentation](https://github.com/Hargne/jest-html-reporter/wiki/configuration#configuration-environment-variables) for more information on these variables.
122
97
 
package/dist/main.js CHANGED
@@ -367,11 +367,26 @@ class ReportGenerator {
367
367
  // Append data to <tr>
368
368
  testTr.ele('td', { class: 'result' }, (test.status === 'passed') ? `${test.status} in ${test.duration / 1000}s` : test.status);
369
369
  });
370
+
371
+ // Test Suite console.logs
372
+ if (suite.console && suite.console.length > 0 && (this.config.shouldIncludeConsoleLog())) {
373
+ // Console Log Container
374
+ const consoleLogContainer = htmlOutput.ele('div', { class: 'suite-consolelog' });
375
+ // Console Log Header
376
+ consoleLogContainer.ele('div', { class: 'suite-consolelog-header' }, 'Console Log');
377
+
378
+ // Logs
379
+ suite.console.forEach((log) => {
380
+ const logElement = consoleLogContainer.ele('div', { class: 'suite-consolelog-item' });
381
+ logElement.ele('pre', { class: 'suite-consolelog-item-origin' }, stripAnsi(log.origin));
382
+ logElement.ele('pre', { class: 'suite-consolelog-item-message' }, stripAnsi(log.message));
383
+ });
384
+ }
370
385
  });
371
386
  // Custom Javascript
372
387
  const customScript = this.config.getCustomScriptFilepath();
373
388
  if (customScript) {
374
- htmlOutput.ele('script', { src: customScript });
389
+ htmlOutput.raw(`<script src="${customScript}"></script>`);
375
390
  }
376
391
  return resolve(htmlOutput);
377
392
  });
@@ -457,6 +472,13 @@ const getLogo = () =>
457
472
  const shouldIncludeFailureMessages = () =>
458
473
  process.env.JEST_HTML_REPORTER_INCLUDE_FAILURE_MSG || config.includeFailureMsg || false;
459
474
 
475
+ /**
476
+ * Returns whether the report should contain console.logs or not
477
+ * @return {Boolean}
478
+ */
479
+ const shouldIncludeConsoleLog = () =>
480
+ process.env.JEST_HTML_REPORTER_INCLUDE_CONSOLE_LOG || config.includeConsoleLog || false;
481
+
460
482
  /**
461
483
  * Returns the configured threshold (in seconds) when to apply a warning
462
484
  * @return {Number}
@@ -479,13 +501,6 @@ const getDateFormat = () =>
479
501
  const getSort = () =>
480
502
  process.env.JEST_HTML_REPORTER_SORT || config.sort || 'default';
481
503
 
482
- /**
483
- * Returns the configured mode of execution ('testResultsProcessor' or 'reporters')
484
- * @return {String}
485
- */
486
- const getExecutionMode = () =>
487
- process.env.JEST_HTML_REPORTER_EXECUTION_MODE || config.executionMode || 'testResultsProcessor';
488
-
489
504
  module.exports = {
490
505
  config,
491
506
  setup,
@@ -496,11 +511,11 @@ module.exports = {
496
511
  getPageTitle,
497
512
  getLogo,
498
513
  shouldIncludeFailureMessages,
514
+ shouldIncludeConsoleLog,
499
515
  getExecutionTimeWarningThreshold,
500
516
  getTheme,
501
517
  getDateFormat,
502
518
  getSort,
503
- getExecutionMode,
504
519
  };
505
520
  });
506
521
 
@@ -513,45 +528,48 @@ var config_7 = config_1.getCustomScriptFilepath;
513
528
  var config_8 = config_1.getPageTitle;
514
529
  var config_9 = config_1.getLogo;
515
530
  var config_10 = config_1.shouldIncludeFailureMessages;
516
- var config_11 = config_1.getExecutionTimeWarningThreshold;
517
- var config_12 = config_1.getTheme;
518
- var config_13 = config_1.getDateFormat;
519
- var config_14 = config_1.getSort;
520
- var config_15 = config_1.getExecutionMode;
521
-
522
- var src = createCommonjsModule(function (module) {
523
- // Initiate the config and the Report Generator class
524
- config_1.setup();
525
- const reportGenerator$$1 = new reportGenerator(config_1);
531
+ var config_11 = config_1.shouldIncludeConsoleLog;
532
+ var config_12 = config_1.getExecutionTimeWarningThreshold;
533
+ var config_13 = config_1.getTheme;
534
+ var config_14 = config_1.getDateFormat;
535
+ var config_15 = config_1.getSort;
526
536
 
527
- /**
528
- * Usage as TestResultsProcessor
529
- * @param {Object} testResult Jest test result data
530
- */
531
- const TestResultsProcessor = (testResult) => {
532
- // Generate Report
533
- reportGenerator$$1.generate({ data: testResult });
534
- // Return the results as required by Jest
535
- return testResult;
536
- };
537
+ function JestHtmlReporter(globalConfig, options) {
538
+ // Initiate the config and setup the Generator class
539
+ config_1.setup();
540
+ const reportGenerator$$1 = new reportGenerator(config_1);
537
541
 
538
- /**
539
- * Usage as Custom Reporter
540
- */
541
- class CustomReporter {
542
- constructor(globalConfig, options) {
543
- this.jestConfig = globalConfig;
544
- this.jestOptions = options;
542
+ /**
543
+ * If the first parameter has a property named 'testResults',
544
+ * the script is being run as a 'testResultsProcessor'.
545
+ * We then need to return the test results as they were received from Jest
546
+ * https://facebook.github.io/jest/docs/en/configuration.html#testresultsprocessor-string
547
+ */
548
+ if (Object.prototype.hasOwnProperty.call(globalConfig, 'testResults')) {
549
+ // Generate Report
550
+ reportGenerator$$1.generate({ data: globalConfig });
551
+ // Return the results as required by Jest
552
+ return globalConfig;
545
553
  }
546
554
 
547
- onRunComplete(contexts, testResult) {
548
- this.testResult = testResult;
555
+ /**
556
+ * The default behaviour - run as Custom Reporter, in parallel with Jest.
557
+ * This should eventually be turned into a proper class (whenever the testResultsProcessor option is phased out)
558
+ * https://facebook.github.io/jest/docs/en/configuration.html#reporters-array-modulename-modulename-options
559
+ */
560
+ this.jestConfig = globalConfig;
561
+ this.jestOptions = options;
562
+
563
+ this.onRunComplete = (contexts, testResult) => {
564
+ // Apply the configuration within jest.config.json to the current config
565
+ config_1.setConfigData(this.jestOptions);
566
+ // Apply the updated config
567
+ reportGenerator$$1.config = config_1;
549
568
  // Generate Report
550
569
  return reportGenerator$$1.generate({ data: testResult });
551
- }
570
+ };
552
571
  }
553
572
 
554
- module.exports = (config_1.getExecutionMode() === 'reporter') ? CustomReporter : TestResultsProcessor;
555
- });
573
+ var src = JestHtmlReporter;
556
574
 
557
575
  module.exports = src;
package/dist/main.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var fs=_interopDefault(require("fs")),path=_interopDefault(require("path")),mkdirp=_interopDefault(require("mkdirp")),xmlbuilder=_interopDefault(require("xmlbuilder")),dateformat=_interopDefault(require("dateformat")),stripAnsi=_interopDefault(require("strip-ansi"));function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}var utils=createCommonjsModule(function(e){e.exports={logMessage:({type:e,msg:t,ignoreConsole:s})=>{const r={default:"%s",success:"%s",error:"%s"},o=r[e]?r[e]:r.default,n=`jest-html-reporter >> ${t}`;return s||console.log(o,n),{logColor:o,logMsg:n}},writeFile:({filePath:e,content:t})=>new Promise((s,r)=>{mkdirp(path.dirname(e),o=>o?r(new Error(`Something went wrong when creating the folder: ${o}`)):fs.writeFile(e,t,t=>t?r(new Error(`Something went wrong when creating the file: ${t}`)):s(e)))}),createHtmlBase:({pageTitle:e,stylesheet:t})=>xmlbuilder.create({html:{head:{meta:{"@charset":"utf-8"},title:{"#text":e},style:{"@type":"text/css","#text":t}}}}),sortAlphabetically:({a:e,b:t,reversed:s})=>!s&&e<t||s&&e>t?-1:!s&&e>t||s&&e<t?1:0}}),utils_1=utils.logMessage,utils_2=utils.writeFile,utils_3=utils.createHtmlBase,utils_4=utils.sortAlphabetically,sorting=createCommonjsModule(function(e){e.exports={sortSuiteResults:({testData:e,sortMethod:t})=>{if(t)switch(t.toLowerCase()){case"status":return(e=>{const t=[],s=[],r=[];return e.forEach(e=>{const o=[],n=[],i=[];e.testResults.forEach(e=>{"pending"===e.status?o.push(e):"failed"===e.status?n.push(e):i.push(e)}),o.length&&t.push(Object.assign({},e,{testResults:o})),n.length&&s.push(Object.assign({},e,{testResults:n})),i.length&&r.push(Object.assign({},e,{testResults:i}))}),[].concat(t,s,r)})(e);case"executiondesc":return(e=>(e&&e.sort((e,t)=>t.perfStats.end-t.perfStats.start-(e.perfStats.end-e.perfStats.start)),e))(e);case"executionasc":return(e=>(e&&e.sort((e,t)=>e.perfStats.end-e.perfStats.start-(t.perfStats.end-t.perfStats.start)),e))(e);case"titledesc":return(e=>{if(e){const t=e.sort((e,t)=>utils.sortAlphabetically({a:e.testFilePath,b:t.testFilePath,reversed:!0}));return t.forEach(e=>{e.testResults.sort((e,t)=>utils.sortAlphabetically({a:e.ancestorTitles.join(" "),b:t.ancestorTitles.join(" "),reversed:!0}))}),t}return e})(e);case"titleasc":return(e=>{if(e){const t=e.sort((e,t)=>utils.sortAlphabetically({a:e.testFilePath,b:t.testFilePath}));return t.forEach(e=>{e.testResults.sort((e,t)=>utils.sortAlphabetically({a:e.ancestorTitles.join(" "),b:t.ancestorTitles.join(" ")}))}),t}return e})(e);default:return e}return e}}}),sorting_1=sorting.sortSuiteResults;class ReportGenerator{constructor(e){this.config=e}generate({data:e,ignoreConsole:t}){const s=this.config.getOutputFilepath();return this.getStylesheetContent().then(t=>this.renderHtmlReport({data:e,stylesheet:t})).then(e=>utils.writeFile({filePath:s,content:e})).then(()=>utils.logMessage({type:"success",msg:`Report generated (${s})`,ignoreConsole:t})).catch(e=>utils.logMessage({type:"error",msg:e,ignoreConsole:t}))}getStylesheetContent(){const e=this.config.getStylesheetFilepath();return new Promise((t,s)=>{fs.readFile(e,"utf8",(r,o)=>r?s(new Error(`Could not locate the stylesheet: '${e}': ${r}`)):t(o))})}renderHtmlReport({data:e,stylesheet:t}){return new Promise((s,r)=>{if(!e)return r(new Error("Test data missing or malformed"));const o=this.config.getPageTitle(),n=utils.createHtmlBase({pageTitle:o,stylesheet:t}),i=n.ele("header");i.ele("h1",{id:"title"},o);const a=this.config.getLogo();a&&i.ele("img",{id:"logo",src:a});const l=n.ele("div",{id:"metadata-container"}),c=new Date(e.startTime);l.ele("div",{id:"timestamp"},`Start: ${dateformat(c,this.config.getDateFormat())}`),l.ele("div",{id:"summary"},`\n\t\t\t\t${e.numTotalTests} tests --\n\t\t\t\t${e.numPassedTests} passed /\n\t\t\t\t${e.numFailedTests} failed /\n\t\t\t\t${e.numPendingTests} pending\n\t\t\t`),sorting.sortSuiteResults({testData:e.testResults,sortMethod:this.config.getSort()}).forEach(e=>{if(!e.testResults||e.testResults.length<=0)return;const t=n.ele("div",{class:"suite-info"});t.ele("div",{class:"suite-path"},e.testFilePath);const s=(e.perfStats.end-e.perfStats.start)/1e3;t.ele("div",{class:`suite-time${s>5?" warn":""}`},`${s}s`);const r=n.ele("table",{class:"suite-table",cellspacing:"0",cellpadding:"0"});e.testResults.forEach(e=>{const t=r.ele("tr",{class:e.status});t.ele("td",{class:"suite"},e.ancestorTitles.join(" > "));const s=t.ele("td",{class:"test"},e.title);if(e.failureMessages&&this.config.shouldIncludeFailureMessages()){const t=s.ele("div",{class:"failureMessages"});e.failureMessages.forEach(e=>{t.ele("pre",{class:"failureMsg"},stripAnsi(e))})}t.ele("td",{class:"result"},"passed"===e.status?`${e.status} in ${e.duration/1e3}s`:e.status)})});const u=this.config.getCustomScriptFilepath();return u&&n.ele("script",{src:u}),s(n)})}}var reportGenerator=ReportGenerator,config_1=createCommonjsModule(function(e){const t={},s=e=>Object.assign(t,e),r=()=>process.env.JEST_HTML_REPORTER_THEME||t.theme||"defaultTheme";e.exports={config:t,setup:()=>{try{const e=fs.readFileSync(path.join(process.cwd(),"jesthtmlreporter.config.json"),"utf8");if(e)return s(JSON.parse(e))}catch(e){}try{const e=fs.readFileSync(path.join(process.cwd(),"package.json"),"utf8");if(e)return s(JSON.parse(e)["jest-html-reporter"])}catch(e){}return t},setConfigData:s,getOutputFilepath:()=>process.env.JEST_HTML_REPORTER_OUTPUT_PATH||t.outputPath||path.join(process.cwd(),"test-report.html"),getStylesheetFilepath:()=>process.env.JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH||t.styleOverridePath||path.join(__dirname,`../style/${r()}.css`),getCustomScriptFilepath:()=>process.env.JEST_HTML_REPORTER_CUSTOM_SCRIPT_PATH||t.customScriptPath||null,getPageTitle:()=>process.env.JEST_HTML_REPORTER_PAGE_TITLE||t.pageTitle||"Test report",getLogo:()=>process.env.JEST_HTML_REPORTER_LOGO||t.logo||null,shouldIncludeFailureMessages:()=>process.env.JEST_HTML_REPORTER_INCLUDE_FAILURE_MSG||t.includeFailureMsg||!1,getExecutionTimeWarningThreshold:()=>process.env.JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD||t.executionTimeWarningThreshold||5,getTheme:r,getDateFormat:()=>process.env.JEST_HTML_REPORTER_DATE_FORMAT||t.dateFormat||"yyyy-mm-dd HH:MM:ss",getSort:()=>process.env.JEST_HTML_REPORTER_SORT||t.sort||"default",getExecutionMode:()=>process.env.JEST_HTML_REPORTER_EXECUTION_MODE||t.executionMode||"testResultsProcessor"}}),config_2=config_1.config,config_3=config_1.setup,config_4=config_1.setConfigData,config_5=config_1.getOutputFilepath,config_6=config_1.getStylesheetFilepath,config_7=config_1.getCustomScriptFilepath,config_8=config_1.getPageTitle,config_9=config_1.getLogo,config_10=config_1.shouldIncludeFailureMessages,config_11=config_1.getExecutionTimeWarningThreshold,config_12=config_1.getTheme,config_13=config_1.getDateFormat,config_14=config_1.getSort,config_15=config_1.getExecutionMode,src=createCommonjsModule(function(e){config_1.setup();const t=new reportGenerator(config_1);e.exports="reporter"===config_1.getExecutionMode()?class{constructor(e,t){this.jestConfig=e,this.jestOptions=t}onRunComplete(e,s){return this.testResult=s,t.generate({data:s})}}:e=>(t.generate({data:e}),e)});module.exports=src;
1
+ "use strict";function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var fs=_interopDefault(require("fs")),path=_interopDefault(require("path")),mkdirp=_interopDefault(require("mkdirp")),xmlbuilder=_interopDefault(require("xmlbuilder")),dateformat=_interopDefault(require("dateformat")),stripAnsi=_interopDefault(require("strip-ansi"));function createCommonjsModule(e,t){return e(t={exports:{}},t.exports),t.exports}var utils=createCommonjsModule(function(e){e.exports={logMessage:({type:e,msg:t,ignoreConsole:s})=>{const o={default:"%s",success:"%s",error:"%s"},r=o[e]?o[e]:o.default,i=`jest-html-reporter >> ${t}`;return s||console.log(r,i),{logColor:r,logMsg:i}},writeFile:({filePath:e,content:t})=>new Promise((s,o)=>{mkdirp(path.dirname(e),r=>r?o(new Error(`Something went wrong when creating the folder: ${r}`)):fs.writeFile(e,t,t=>t?o(new Error(`Something went wrong when creating the file: ${t}`)):s(e)))}),createHtmlBase:({pageTitle:e,stylesheet:t})=>xmlbuilder.create({html:{head:{meta:{"@charset":"utf-8"},title:{"#text":e},style:{"@type":"text/css","#text":t}}}}),sortAlphabetically:({a:e,b:t,reversed:s})=>!s&&e<t||s&&e>t?-1:!s&&e>t||s&&e<t?1:0}}),utils_1=utils.logMessage,utils_2=utils.writeFile,utils_3=utils.createHtmlBase,utils_4=utils.sortAlphabetically,sorting=createCommonjsModule(function(e){e.exports={sortSuiteResults:({testData:e,sortMethod:t})=>{if(t)switch(t.toLowerCase()){case"status":return(e=>{const t=[],s=[],o=[];return e.forEach(e=>{const r=[],i=[],n=[];e.testResults.forEach(e=>{"pending"===e.status?r.push(e):"failed"===e.status?i.push(e):n.push(e)}),r.length&&t.push(Object.assign({},e,{testResults:r})),i.length&&s.push(Object.assign({},e,{testResults:i})),n.length&&o.push(Object.assign({},e,{testResults:n}))}),[].concat(t,s,o)})(e);case"executiondesc":return(e=>(e&&e.sort((e,t)=>t.perfStats.end-t.perfStats.start-(e.perfStats.end-e.perfStats.start)),e))(e);case"executionasc":return(e=>(e&&e.sort((e,t)=>e.perfStats.end-e.perfStats.start-(t.perfStats.end-t.perfStats.start)),e))(e);case"titledesc":return(e=>{if(e){const t=e.sort((e,t)=>utils.sortAlphabetically({a:e.testFilePath,b:t.testFilePath,reversed:!0}));return t.forEach(e=>{e.testResults.sort((e,t)=>utils.sortAlphabetically({a:e.ancestorTitles.join(" "),b:t.ancestorTitles.join(" "),reversed:!0}))}),t}return e})(e);case"titleasc":return(e=>{if(e){const t=e.sort((e,t)=>utils.sortAlphabetically({a:e.testFilePath,b:t.testFilePath}));return t.forEach(e=>{e.testResults.sort((e,t)=>utils.sortAlphabetically({a:e.ancestorTitles.join(" "),b:t.ancestorTitles.join(" ")}))}),t}return e})(e);default:return e}return e}}}),sorting_1=sorting.sortSuiteResults;class ReportGenerator{constructor(e){this.config=e}generate({data:e,ignoreConsole:t}){const s=this.config.getOutputFilepath();return this.getStylesheetContent().then(t=>this.renderHtmlReport({data:e,stylesheet:t})).then(e=>utils.writeFile({filePath:s,content:e})).then(()=>utils.logMessage({type:"success",msg:`Report generated (${s})`,ignoreConsole:t})).catch(e=>utils.logMessage({type:"error",msg:e,ignoreConsole:t}))}getStylesheetContent(){const e=this.config.getStylesheetFilepath();return new Promise((t,s)=>{fs.readFile(e,"utf8",(o,r)=>o?s(new Error(`Could not locate the stylesheet: '${e}': ${o}`)):t(r))})}renderHtmlReport({data:e,stylesheet:t}){return new Promise((s,o)=>{if(!e)return o(new Error("Test data missing or malformed"));const r=this.config.getPageTitle(),i=utils.createHtmlBase({pageTitle:r,stylesheet:t}),n=i.ele("header");n.ele("h1",{id:"title"},r);const l=this.config.getLogo();l&&n.ele("img",{id:"logo",src:l});const a=i.ele("div",{id:"metadata-container"}),c=new Date(e.startTime);a.ele("div",{id:"timestamp"},`Start: ${dateformat(c,this.config.getDateFormat())}`),a.ele("div",{id:"summary"},`\n\t\t\t\t${e.numTotalTests} tests --\n\t\t\t\t${e.numPassedTests} passed /\n\t\t\t\t${e.numFailedTests} failed /\n\t\t\t\t${e.numPendingTests} pending\n\t\t\t`),sorting.sortSuiteResults({testData:e.testResults,sortMethod:this.config.getSort()}).forEach(e=>{if(!e.testResults||e.testResults.length<=0)return;const t=i.ele("div",{class:"suite-info"});t.ele("div",{class:"suite-path"},e.testFilePath);const s=(e.perfStats.end-e.perfStats.start)/1e3;t.ele("div",{class:`suite-time${s>5?" warn":""}`},`${s}s`);const o=i.ele("table",{class:"suite-table",cellspacing:"0",cellpadding:"0"});if(e.testResults.forEach(e=>{const t=o.ele("tr",{class:e.status});t.ele("td",{class:"suite"},e.ancestorTitles.join(" > "));const s=t.ele("td",{class:"test"},e.title);if(e.failureMessages&&this.config.shouldIncludeFailureMessages()){const t=s.ele("div",{class:"failureMessages"});e.failureMessages.forEach(e=>{t.ele("pre",{class:"failureMsg"},stripAnsi(e))})}t.ele("td",{class:"result"},"passed"===e.status?`${e.status} in ${e.duration/1e3}s`:e.status)}),e.console&&e.console.length>0&&this.config.shouldIncludeConsoleLog()){const t=i.ele("div",{class:"suite-consolelog"});t.ele("div",{class:"suite-consolelog-header"},"Console Log"),e.console.forEach(e=>{const s=t.ele("div",{class:"suite-consolelog-item"});s.ele("pre",{class:"suite-consolelog-item-origin"},stripAnsi(e.origin)),s.ele("pre",{class:"suite-consolelog-item-message"},stripAnsi(e.message))})}});const u=this.config.getCustomScriptFilepath();return u&&i.raw(`<script src="${u}"><\/script>`),s(i)})}}var reportGenerator=ReportGenerator,config_1=createCommonjsModule(function(e){const t={},s=e=>Object.assign(t,e),o=()=>process.env.JEST_HTML_REPORTER_THEME||t.theme||"defaultTheme";e.exports={config:t,setup:()=>{try{const e=fs.readFileSync(path.join(process.cwd(),"jesthtmlreporter.config.json"),"utf8");if(e)return s(JSON.parse(e))}catch(e){}try{const e=fs.readFileSync(path.join(process.cwd(),"package.json"),"utf8");if(e)return s(JSON.parse(e)["jest-html-reporter"])}catch(e){}return t},setConfigData:s,getOutputFilepath:()=>process.env.JEST_HTML_REPORTER_OUTPUT_PATH||t.outputPath||path.join(process.cwd(),"test-report.html"),getStylesheetFilepath:()=>process.env.JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH||t.styleOverridePath||path.join(__dirname,`../style/${o()}.css`),getCustomScriptFilepath:()=>process.env.JEST_HTML_REPORTER_CUSTOM_SCRIPT_PATH||t.customScriptPath||null,getPageTitle:()=>process.env.JEST_HTML_REPORTER_PAGE_TITLE||t.pageTitle||"Test report",getLogo:()=>process.env.JEST_HTML_REPORTER_LOGO||t.logo||null,shouldIncludeFailureMessages:()=>process.env.JEST_HTML_REPORTER_INCLUDE_FAILURE_MSG||t.includeFailureMsg||!1,shouldIncludeConsoleLog:()=>process.env.JEST_HTML_REPORTER_INCLUDE_CONSOLE_LOG||t.includeConsoleLog||!1,getExecutionTimeWarningThreshold:()=>process.env.JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD||t.executionTimeWarningThreshold||5,getTheme:o,getDateFormat:()=>process.env.JEST_HTML_REPORTER_DATE_FORMAT||t.dateFormat||"yyyy-mm-dd HH:MM:ss",getSort:()=>process.env.JEST_HTML_REPORTER_SORT||t.sort||"default"}}),config_2=config_1.config,config_3=config_1.setup,config_4=config_1.setConfigData,config_5=config_1.getOutputFilepath,config_6=config_1.getStylesheetFilepath,config_7=config_1.getCustomScriptFilepath,config_8=config_1.getPageTitle,config_9=config_1.getLogo,config_10=config_1.shouldIncludeFailureMessages,config_11=config_1.shouldIncludeConsoleLog,config_12=config_1.getExecutionTimeWarningThreshold,config_13=config_1.getTheme,config_14=config_1.getDateFormat,config_15=config_1.getSort;function JestHtmlReporter(e,t){config_1.setup();const s=new reportGenerator(config_1);if(Object.prototype.hasOwnProperty.call(e,"testResults"))return s.generate({data:e}),e;this.jestConfig=e,this.jestOptions=t,this.onRunComplete=((e,t)=>(config_1.setConfigData(this.jestOptions),s.config=config_1,s.generate({data:t})))}var src=JestHtmlReporter;module.exports=src;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jest-html-reporter",
3
- "version": "2.2.0",
3
+ "version": "2.4.2",
4
4
  "description": "Jest test results processor for generating a summary in HTML",
5
5
  "main": "dist/main",
6
6
  "unpkg": "dist/main.min.js",
@@ -10,7 +10,8 @@
10
10
  ],
11
11
  "scripts": {
12
12
  "eslint": "./node_modules/.bin/eslint ./src/**/*.js",
13
- "test": "npm run eslint && jest --no-cache --config=jest.config.json",
13
+ "jest": "jest --no-cache --config=jest.config.json",
14
+ "test": "npm run eslint && npm run jest",
14
15
  "bundle": "rollup -c rollup.config.js",
15
16
  "bundle:minified": "rollup -c rollup.config.js --environment BUILD:minified",
16
17
  "bundle:all": "npm run bundle && npm run bundle:minified",
@@ -43,16 +44,18 @@
43
44
  "xmlbuilder": "8.2.2"
44
45
  },
45
46
  "peerDependencies": {
46
- "jest": "19.x - 22.x"
47
+ "jest": "19.x - 23.x"
47
48
  },
48
49
  "devDependencies": {
49
- "eslint": "^4.16.0",
50
+ "eslint": "^4.19.1",
50
51
  "eslint-config-airbnb-base": "^12.1.0",
51
- "eslint-plugin-import": "^2.8.0",
52
+ "eslint-plugin-import": "^2.13.0",
52
53
  "jest": "^21.2.1",
53
- "rollup": "^0.55.2",
54
- "rollup-plugin-commonjs": "^8.3.0",
55
- "rollup-plugin-node-resolve": "^3.0.2",
56
- "rollup-plugin-uglify": "^3.0.0"
54
+ "rollup": "^0.55.5",
55
+ "rollup-plugin-commonjs": "^8.4.1",
56
+ "rollup-plugin-node-resolve": "^3.3.0",
57
+ "rollup-plugin-uglify": "^3.0.0",
58
+ "istanbul-api": "1.2.2",
59
+ "istanbul-reports": "1.1.4"
57
60
  }
58
61
  }
@@ -122,3 +122,28 @@ header {
122
122
  width: 20%;
123
123
  text-align: right;
124
124
  }
125
+
126
+ /* CONSOLE LOGS */
127
+ .suite-consolelog {
128
+ margin-bottom: 2rem;
129
+ padding: 1rem;
130
+ border-left: 0.5rem solid #999;
131
+ color: #999;
132
+ }
133
+ .suite-consolelog-header {
134
+ font-weight: bold;
135
+ }
136
+ .suite-consolelog-item {
137
+ padding: 0.5rem;
138
+ }
139
+ .suite-consolelog-item pre {
140
+ margin: 0;
141
+ }
142
+ .suite-consolelog-item-origin {
143
+ color: #555;
144
+ font-weight: bold;
145
+ }
146
+ .suite-consolelog-item-message {
147
+ font-size: 1rem;
148
+ padding: 0 0.5rem;
149
+ }
@@ -96,3 +96,28 @@ header {
96
96
  width: 20%;
97
97
  text-align: right;
98
98
  }
99
+
100
+ /* CONSOLE LOGS */
101
+ .suite-consolelog {
102
+ margin-bottom: 2rem;
103
+ padding: 1rem;
104
+ background-color: #efefef;
105
+ }
106
+ .suite-consolelog-header {
107
+ font-weight: bold;
108
+ }
109
+ .suite-consolelog-item {
110
+ padding: 0.5rem;
111
+ }
112
+ .suite-consolelog-item pre {
113
+ margin: 0;
114
+ }
115
+ .suite-consolelog-item-origin {
116
+ color: #777;
117
+ font-weight: bold;
118
+ }
119
+ .suite-consolelog-item-message {
120
+ color: #000;
121
+ font-size: 1rem;
122
+ padding: 0 0.5rem;
123
+ }
@@ -121,3 +121,29 @@ header {
121
121
  width: 20%;
122
122
  text-align: right;
123
123
  }
124
+
125
+ /* CONSOLE LOGS */
126
+ .suite-consolelog {
127
+ margin-bottom: 2rem;
128
+ padding: 1rem;
129
+ border-left: 0.5rem solid #666;
130
+ color: #666;
131
+ box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.3);
132
+ }
133
+ .suite-consolelog-header {
134
+ font-weight: bold;
135
+ }
136
+ .suite-consolelog-item {
137
+ padding: 0.5rem;
138
+ }
139
+ .suite-consolelog-item pre {
140
+ margin: 0;
141
+ }
142
+ .suite-consolelog-item-origin {
143
+ color: #aaa;
144
+ font-weight: bold;
145
+ }
146
+ .suite-consolelog-item-message {
147
+ font-size: 1rem;
148
+ padding: 0 0.5rem;
149
+ }