jest-html-reporter 4.2.0 → 4.3.0
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 +2 -0
- package/dist/index.js +1 -1
- package/package.json +3 -2
- package/style/darkTheme.css +277 -0
package/README.md
CHANGED
|
@@ -92,6 +92,7 @@ or via adding a key to `package.json` named "jest-html-reporter":
|
|
|
92
92
|
| **`customScriptPath`** | `string` | `null` | Path to an external script file injected into the report. |
|
|
93
93
|
| **`dateFormat`** | `string` | `yyyy-mm-dd HH:MM:ss` | Date format for timestamps. See [documentation](https://github.com/Hargne/jest-html-reporter/wiki/Date-Format) for available formats. |
|
|
94
94
|
| **`executionTimeWarningThreshold`** | `number` | `5` | Warn if a test suite exceeds this execution time (in seconds). |
|
|
95
|
+
| **`hideConsoleLogOrigin`** | `boolean` | `true` | Hide `console.log` origin (stack trace) in the report (**requires** `--verbose=false`). |
|
|
95
96
|
| **`includeConsoleLog`** | `boolean` | `false` | Include `console.log` outputs in the report (**requires** `--verbose=false`). |
|
|
96
97
|
| **`includeFailureMsg`** | `boolean` | `false` | Show detailed error messages for failed tests. |
|
|
97
98
|
| **`includeStackTrace`** | `boolean` | `true` | Show stack traces for failed tests. |
|
|
@@ -104,6 +105,7 @@ or via adding a key to `package.json` named "jest-html-reporter":
|
|
|
104
105
|
| **`statusIgnoreFilter`** | `string` | `null` | **Comma-separated** list of statuses to exclude: `"passed"`, `"pending"`, `"failed"`. |
|
|
105
106
|
| **`styleOverridePath`** | `string` | `null` | Path to a CSS file to override default styles. |
|
|
106
107
|
| **`useCssFile`** | `boolean` | `false` | Link to the CSS file instead of inlining styles. |
|
|
108
|
+
| **`theme`** | `string` | `defaultTheme` | Theme that you are able to set to report (defaultTheme or darkTheme) |
|
|
107
109
|
|
|
108
110
|
## Continuous Integration
|
|
109
111
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("dateformat"),t=require("fs"),s=require("mkdirp"),i=require("path"),n=require("xmlbuilder"),o=require("strip-ansi");function a(e,t){const s={default:"[37m%s[0m",success:"[32m%s[0m",error:"[31m%s[0m"},i=s[e]?s[e]:s.default,n=`jest-html-reporter >> ${t}`;return void 0===process.env.JEST_WORKER_ID&&console.log(i,n),{logColor:i,logMsg:n}}function r(e){return a("error",e instanceof Error?e.message:"An error occurred")}function l(e){if("string"!=typeof e)throw new TypeError("Input must be a string");return o(e).replace(/[^\t\n\r\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/gu,"")}function u(e,t){if("string"!=typeof e||"string"!=typeof t)throw new TypeError("Both rootDir and filePath must be strings.");return t.startsWith("<rootDir>")?i.resolve(e,i.normalize(`./${t.slice(9)}`)):t}function c(e,t,s=!1){return!s&&e<t||s&&e>t?-1:!s&&e>t||s&&e<t?1:0}function d(e){return"boolean"==typeof e?e:"string"==typeof e&&"true"===e}function h(e){if("string"==typeof e)return e}const g=["pending","failed","passed"];const f=(e,t)=>{const s={pending:[],failed:[],passed:[]},i=[];e.forEach((e=>{const t=[],n=[],o=[],a=[];e.testResults.forEach((e=>{"pending"===e.status?t.push(e):"failed"===e.status?n.push(e):"passed"===e.status?o.push(e):a.push(e)})),t.length>0&&s.pending.push({...e,testResults:t}),n.length>0&&s.failed.push({...e,testResults:n}),o.length>0&&s.passed.push({...e,testResults:o}),a.length>0&&i.push({...e,testResults:a})}));const n=[...t||[],...["pending","failed","passed"].filter((e=>!(t||[]).includes(e)))],o=Object.entries(s).sort((([e],[t])=>n.indexOf(e)-n.indexOf(t))).flatMap((([,e])=>e));return[...o,...i]},p=e=>(e&&e.sort(((e,t)=>t.perfStats.end-t.perfStats.start-(e.perfStats.end-e.perfStats.start))),e),m=e=>(e&&e.sort(((e,t)=>e.perfStats.end-e.perfStats.start-(t.perfStats.end-t.perfStats.start))),e),y=e=>{if(e){const t=e.sort(((e,t)=>c(e.testFilePath,t.testFilePath,!0)));return t.forEach((e=>{e.testResults.sort(((e,t)=>c(e.ancestorTitles.join(" "),t.ancestorTitles.join(" "),!0))),e.testResults.sort(((e,t)=>c(e.title,t.title,!0)))})),t}return e},v=e=>{if(e){const t=e.sort(((e,t)=>c(e.testFilePath,t.testFilePath)));return t.forEach((e=>{e.testResults.sort(((e,t)=>c(e.ancestorTitles.join(" "),t.ancestorTitles.join(" ")))),e.testResults.sort(((e,t)=>c(e.title,t.title)))})),t}return e},S={additionalInformation:[],append:!1,boilerplate:void 0,collapseSuitesByDefault:!1,customScriptPath:void 0,dateFormat:"yyyy-mm-dd HH:MM:ss",executionTimeWarningThreshold:5,includeConsoleLog:!1,includeFailureMsg:!1,includeStackTrace:!0,includeSuiteFailure:!1,includeObsoleteSnapshots:!1,logo:void 0,outputPath:i.join(process.cwd(),"test-report.html"),pageTitle:"Test Report",sort:void 0,statusIgnoreFilter:void 0,styleOverridePath:void 0,theme:"defaultTheme",useCssFile:!1};function T(e){try{if(t.existsSync(e))return JSON.parse(t.readFileSync(e,"utf8"))}catch{return{}}return{}}const C={additionalInformation:(F=function(e){return"object"==typeof e&&null!==e&&"string"==typeof e.label&&"string"==typeof e.value},e=>Array.isArray(e)?e.filter(F):[]),append:d,boilerplate:h,collapseSuitesByDefault:d,customScriptPath:h,dateFormat:h,executionTimeWarningThreshold:function(e){return"number"==typeof e?e:"string"==typeof e?Number(e):NaN},includeConsoleLog:d,includeFailureMsg:d,includeStackTrace:d,includeSuiteFailure:d,includeObsoleteSnapshots:d,logo:h,outputPath:h,pageTitle:h,sort:h,statusIgnoreFilter:h,styleOverridePath:h,theme:h,useCssFile:d};var F;function D(e){return"object"!=typeof e||null===e?{}:Object.keys(S).reduce(((t,s)=>{const i=C[s];if(i&&"function"==typeof i&&s in e){const n=i(e[s]);if(void 0!==n)return{...t,[s]:n}}return t}),{})}class b{testData;consoleLogList;jestConfig;config;constructor(e){this.testData=e.testData,this.jestConfig=e.jestConfig,this.consoleLogList=e.consoleLogs||[],this.config=function(e){const t=Object.keys(S).reduce(((e,t)=>{const s=function(e){return`JEST_HTML_REPORTER_${e.replace(/([a-z])([A-Z])/g,"$1_$2").toUpperCase()}`}(t);return void 0!==process.env[s]?{...e,[t]:process.env[s]}:e}),{}),s=T(i.join(process.cwd(),"jesthtmlreporter.config.json")),n=T(i.join(process.cwd(),"package.json"))["jest-html-reporter"]||{};return{...S,...D(n),...D(s),...D(e),...D(t)}}(e.options)}async generate(){try{const e=await this.renderTestReport(),n=u(this.jestConfig?this.jestConfig.rootDir:"",this.getConfigValue("outputPath"));await s(i.dirname(n));let o=!0;if(this.getConfigValue("append")){t.existsSync(n)&&(await async function(e,s){try{await t.promises.access(e);const i=await t.promises.readFile(e,"utf8"),n=/<body>(.*?)<\/body>/s.exec(s),o=n?n[1]:s,a=/<\/body>/i.exec(i),r=a?a.index:0,l=[i.slice(0,r),o,i.slice(r)].join("");await t.promises.writeFile(e,l,"utf8")}catch(e){let t="An unknown error occurred while appending to the file";throw e instanceof Error&&(t=e.message),new Error(t)}}(n,e.content.toString()),o=!1)}return o&&t.writeFileSync(n,e.fullHtml.toString()),a("success",`Report generated (${n})`),e.fullHtml}catch(e){r(e)}}async renderTestReport(){const e=await this.renderTestReportContent();if(this.getConfigValue("boilerplate")){const s=u(this.jestConfig?this.jestConfig.rootDir:"",this.getConfigValue("boilerplate")),i=t.readFileSync(s,"utf8"),n=e?e.toString():"";return{content:n,fullHtml:i.replace("{jesthtmlreporter-content}",n)}}const s=n.create({html:{}}),o=s.ele("head");o.ele("meta",{charset:"utf-8"}),o.ele("title",{},this.getConfigValue("pageTitle"));let a=i.join(__dirname,`../style/${this.getConfigValue("theme")}.css`);this.getConfigValue("styleOverridePath")&&(a=this.getConfigValue("styleOverridePath"));if(!this.getConfigValue("useCssFile")&&!this.getConfigValue("styleOverridePath")){const e=t.readFileSync(a,"utf8");o.raw(`<style type="text/css">${e}</style>`)}else o.ele("link",{rel:"stylesheet",type:"text/css",href:a});const r=s.ele("body");return e&&r.raw(e.toString()),this.getConfigValue("customScriptPath")&&r.raw(`<script src="${this.getConfigValue("customScriptPath")}"><\/script>`),{fullHtml:s.toString(),content:e?e.toString():""}}renderTestSuiteHeader(e,t){const s=e.ele("summary",{class:"suite-info"});s.ele("div",{class:"suite-path"},t.testFilePath);const i=(t.perfStats.end-t.perfStats.start)/1e3,n=["suite-time"];i>this.getConfigValue("executionTimeWarningThreshold")&&n.push("warn"),s.ele("div",{class:n.join(" ")},`${i}s`)}async renderTestReportContent(){try{if(!this.testData||0===Object.entries(this.testData).length)throw Error("No test data provided");const t=n.begin().element("main",{class:"jesthtml-content"}),s=t.ele("header");s.ele("h1",{id:"title"},this.getConfigValue("pageTitle"));const i=this.getConfigValue("logo");i&&s.ele("img",{id:"logo",src:i});const o=t.ele("section",{id:"metadata-container"});if(this.testData.startTime&&!isNaN(this.testData.startTime)){const t=new Date(this.testData.startTime);if(t){const s=e(t,this.getConfigValue("dateFormat"));o.ele("div",{id:"timestamp"},`Started: ${s}`)}}this.renderAdditionalInformation(o);const a=o.ele("div",{id:"summary"}),r=a.ele("div",{id:"suite-summary"}),u=(e,t)=>[`summary-${e}`,t>0?"":" summary-empty"].join(" ");r.ele("div",{class:"summary-total"},`Suites (${this.testData.numTotalTestSuites})`),r.ele("div",{class:u("passed",this.testData.numPassedTestSuites)},`${this.testData.numPassedTestSuites} passed`),r.ele("div",{class:u("failed",this.testData.numFailedTestSuites)},`${this.testData.numFailedTestSuites} failed`),r.ele("div",{class:u("pending",this.testData.numPendingTestSuites)},`${this.testData.numPendingTestSuites} pending`),this.testData.snapshot&&this.testData.snapshot.unchecked>0&&this.getConfigValue("includeObsoleteSnapshots")&&r.ele("div",{class:"summary-obsolete-snapshots"},`${this.testData.snapshot.unchecked} obsolete snapshots`);const c=a.ele("div",{id:"test-summary"});c.ele("div",{class:"summary-total"},`Tests (${this.testData.numTotalTests})`),c.ele("div",{class:u("passed",this.testData.numPassedTests)},`${this.testData.numPassedTests} passed`),c.ele("div",{class:u("failed",this.testData.numFailedTests)},`${this.testData.numFailedTests} failed`),c.ele("div",{class:u("pending",this.testData.numPendingTests)},`${this.testData.numPendingTests} pending`);const d=((e,t)=>{const{sortType:s,params:i}=function(e){if(!e)return{sortType:null};const[t,s]=e.split(":").map((e=>e.trim())),i=s?.split(",").map((e=>e.trim()));if(!["status","executiondesc","executionasc","titledesc","titleasc"].includes(t.toLowerCase()))return{sortType:null};return{sortType:t.toLowerCase(),params:i}}(t);switch(s){case"status":{const t=i?.every((e=>g.includes(e)))?i:void 0;return f(e,t)}case"executiondesc":return p(e);case"executionasc":return m(e);case"titledesc":return y(e);case"titleasc":return v(e);default:return e}})(this.testData.testResults,this.getConfigValue("sort")),h=this.getConfigValue("statusIgnoreFilter");let S=[];return h&&(S=h.replace(/\s/g,"").toLowerCase().split(",")),d&&d.forEach(((e,s)=>{const i=t.ele("details",{id:`suite-${s+1}`,class:"suite-container",open:this.getConfigValue("collapseSuitesByDefault")?void 0:""});this.renderTestSuiteHeader(i,e);const n=i.ele("div",{class:"suite-tests"});if(!e.testResults||e.testResults.length<=0){if(e.failureMessage&&this.getConfigValue("includeSuiteFailure")){n.ele("div",{class:"test-result failed"}).ele("div",{class:"failureMessages suiteFailure"}," ").ele("pre",{class:"failureMsg"},l(e.failureMessage))}}else e.testResults.filter((e=>!S.includes(e.status))).forEach((async e=>{const t=n.ele("div",{class:`test-result ${e.status}`}),s=t.ele("div",{class:"test-info"});if(s.ele("div",{class:"test-suitename"},e.ancestorTitles&&e.ancestorTitles.length>0?e.ancestorTitles.join(" > "):" "),s.ele("div",{class:"test-title"},e.title),s.ele("div",{class:"test-status"},e.status),s.ele("div",{class:"test-duration"},e.duration?e.duration/1e3+"s":" "),e.failureMessages&&e.failureMessages.length>0&&this.getConfigValue("includeFailureMsg")){const s=t.ele("div",{class:"failureMessages"}," ");e.failureMessages.map((e=>this.getConfigValue("includeStackTrace")?e:e.split(/\n\s+at/)[0].trim().replace(/\n+$/,""))).forEach((e=>{s.ele("pre",{class:"failureMsg"},l(e))}))}})),this.consoleLogList&&this.consoleLogList.length>0&&this.getConfigValue("includeConsoleLog")&&this.renderSuiteConsoleLogs(e,i),e.snapshot&&e.snapshot.unchecked>0&&this.getConfigValue("includeObsoleteSnapshots")&&this.renderSuiteObsoleteSnapshots(i,e)})),t}catch(e){r(e)}}renderSuiteConsoleLogs(e,t){const s=this.consoleLogList.find((t=>t.filePath===e.testFilePath));if(s&&s.logs.length>0){const e=t.ele("div",{class:"suite-consolelog"});e.ele("div",{class:"suite-consolelog-header"},"Console Log"),s.logs.forEach((t=>{const s=e.ele("div",{class:"suite-consolelog-item"});s.ele("pre",{class:"suite-consolelog-item-origin"},l(t.origin)),s.ele("pre",{class:"suite-consolelog-item-message"},l(t.message))}))}}renderSuiteObsoleteSnapshots(e,t){const s=e.ele("div",{class:"suite-obsolete-snapshots"});s.ele("div",{class:"suite-obsolete-snapshots-header"},"Obsolete snapshots");s.ele("div",{class:"suite-obsolete-snapshots-item"}).ele("pre",{class:"suite-obsolete-snapshots-item-message"},t.snapshot.uncheckedKeys.join("\n"))}renderAdditionalInformation(e){const t=this.getConfigValue("additionalInformation");if(t&&Array.isArray(t)&&t.length>0){const s=e.ele("div",{class:"additional-information-container"});for(const e of t)s.ele("div",{class:"additional-information"},`${e.label}: ${e.value}`);return s}}getConfigValue(e){return this.config[e]}}const j=e=>new b(e).generate();module.exports=function(e,t){const s=[];if(Object.prototype.hasOwnProperty.call(e,"testResults")){const s=e;return j({testData:s,options:t}),s}this.onTestResult=(e,t)=>{t.console&&s.push({filePath:t.testFilePath,logs:t.console})},this.onRunComplete=(i,n)=>j({testData:n,options:t,jestConfig:e,consoleLogs:s})};
|
|
1
|
+
"use strict";var e=require("dateformat"),t=require("fs"),s=require("mkdirp"),i=require("path"),n=require("xmlbuilder"),o=require("strip-ansi");function a(e,t){const s={default:"[37m%s[0m",success:"[32m%s[0m",error:"[31m%s[0m"},i=s[e]?s[e]:s.default,n=`jest-html-reporter >> ${t}`;return void 0===process.env.JEST_WORKER_ID&&console.log(i,n),{logColor:i,logMsg:n}}function r(e){return a("error",e instanceof Error?e.message:"An error occurred")}function l(e){if("string"!=typeof e)throw new TypeError("Input must be a string");return o(e).replace(/[^\t\n\r\x20-\uD7FF\uE000-\uFFFD\u{10000}-\u{10FFFF}]/gu,"")}function u(e,t){if("string"!=typeof e||"string"!=typeof t)throw new TypeError("Both rootDir and filePath must be strings.");return t.startsWith("<rootDir>")?i.resolve(e,i.normalize(`./${t.slice(9)}`)):t}function c(e,t,s=!1){return!s&&e<t||s&&e>t?-1:!s&&e>t||s&&e<t?1:0}function d(e){return"boolean"==typeof e?e:"string"==typeof e&&"true"===e}function h(e){if("string"==typeof e)return e}const g=["pending","failed","passed"];const f=(e,t)=>{const s={pending:[],failed:[],passed:[]},i=[];e.forEach((e=>{const t=[],n=[],o=[],a=[];e.testResults.forEach((e=>{"pending"===e.status?t.push(e):"failed"===e.status?n.push(e):"passed"===e.status?o.push(e):a.push(e)})),t.length>0&&s.pending.push({...e,testResults:t}),n.length>0&&s.failed.push({...e,testResults:n}),o.length>0&&s.passed.push({...e,testResults:o}),a.length>0&&i.push({...e,testResults:a})}));const n=[...t||[],...["pending","failed","passed"].filter((e=>!(t||[]).includes(e)))],o=Object.entries(s).sort((([e],[t])=>n.indexOf(e)-n.indexOf(t))).flatMap((([,e])=>e));return[...o,...i]},p=e=>(e&&e.sort(((e,t)=>t.perfStats.end-t.perfStats.start-(e.perfStats.end-e.perfStats.start))),e),m=e=>(e&&e.sort(((e,t)=>e.perfStats.end-e.perfStats.start-(t.perfStats.end-t.perfStats.start))),e),y=e=>{if(e){const t=e.sort(((e,t)=>c(e.testFilePath,t.testFilePath,!0)));return t.forEach((e=>{e.testResults.sort(((e,t)=>c(e.ancestorTitles.join(" "),t.ancestorTitles.join(" "),!0))),e.testResults.sort(((e,t)=>c(e.title,t.title,!0)))})),t}return e},S=e=>{if(e){const t=e.sort(((e,t)=>c(e.testFilePath,t.testFilePath)));return t.forEach((e=>{e.testResults.sort(((e,t)=>c(e.ancestorTitles.join(" "),t.ancestorTitles.join(" ")))),e.testResults.sort(((e,t)=>c(e.title,t.title)))})),t}return e},T={additionalInformation:[],append:!1,boilerplate:void 0,collapseSuitesByDefault:!1,customScriptPath:void 0,dateFormat:"yyyy-mm-dd HH:MM:ss",executionTimeWarningThreshold:5,includeConsoleLog:!1,hideConsoleLogOrigin:!1,includeFailureMsg:!1,includeStackTrace:!0,includeSuiteFailure:!1,includeObsoleteSnapshots:!1,logo:void 0,outputPath:i.join(process.cwd(),"test-report.html"),pageTitle:"Test Report",sort:void 0,statusIgnoreFilter:void 0,styleOverridePath:void 0,theme:"defaultTheme",useCssFile:!1};function v(e){try{if(t.existsSync(e))return JSON.parse(t.readFileSync(e,"utf8"))}catch{return{}}return{}}const C={additionalInformation:(F=function(e){return"object"==typeof e&&null!==e&&"string"==typeof e.label&&"string"==typeof e.value},e=>Array.isArray(e)?e.filter(F):[]),append:d,boilerplate:h,collapseSuitesByDefault:d,customScriptPath:h,dateFormat:h,executionTimeWarningThreshold:function(e){return"number"==typeof e?e:"string"==typeof e?Number(e):NaN},includeConsoleLog:d,hideConsoleLogOrigin:d,includeFailureMsg:d,includeStackTrace:d,includeSuiteFailure:d,includeObsoleteSnapshots:d,logo:h,outputPath:h,pageTitle:h,sort:h,statusIgnoreFilter:h,styleOverridePath:h,theme:h,useCssFile:d};var F;function D(e){return"object"!=typeof e||null===e?{}:Object.keys(T).reduce(((t,s)=>{const i=C[s];if(i&&"function"==typeof i&&s in e){const n=i(e[s]);if(void 0!==n)return{...t,[s]:n}}return t}),{})}class b{testData;consoleLogList;jestConfig;config;constructor(e){this.testData=e.testData,this.jestConfig=e.jestConfig,this.consoleLogList=e.consoleLogs||[],this.config=function(e){const t=Object.keys(T).reduce(((e,t)=>{const s=function(e){return`JEST_HTML_REPORTER_${e.replace(/([a-z])([A-Z])/g,"$1_$2").toUpperCase()}`}(t);return void 0!==process.env[s]?{...e,[t]:process.env[s]}:e}),{}),s=v(i.join(process.cwd(),"jesthtmlreporter.config.json")),n=v(i.join(process.cwd(),"package.json"))["jest-html-reporter"]||{};return{...T,...D(n),...D(s),...D(e),...D(t)}}(e.options)}async generate(){try{const e=await this.renderTestReport(),n=u(this.jestConfig?this.jestConfig.rootDir:"",this.getConfigValue("outputPath"));await s(i.dirname(n));let o=!0;if(this.getConfigValue("append")){t.existsSync(n)&&(await async function(e,s){try{await t.promises.access(e);const i=await t.promises.readFile(e,"utf8"),n=/<body>(.*?)<\/body>/s.exec(s),o=n?n[1]:s,a=/<\/body>/i.exec(i),r=a?a.index:0,l=[i.slice(0,r),o,i.slice(r)].join("");await t.promises.writeFile(e,l,"utf8")}catch(e){let t="An unknown error occurred while appending to the file";throw e instanceof Error&&(t=e.message),new Error(t)}}(n,e.content.toString()),o=!1)}return o&&t.writeFileSync(n,e.fullHtml.toString()),a("success",`Report generated (${n})`),e.fullHtml}catch(e){r(e)}}async renderTestReport(){const e=await this.renderTestReportContent();if(this.getConfigValue("boilerplate")){const s=u(this.jestConfig?this.jestConfig.rootDir:"",this.getConfigValue("boilerplate")),i=t.readFileSync(s,"utf8"),n=e?e.toString():"";return{content:n,fullHtml:i.replace("{jesthtmlreporter-content}",n)}}const s=n.create({html:{}}),o=s.ele("head");o.ele("meta",{charset:"utf-8"}),o.ele("title",{},this.getConfigValue("pageTitle"));let a=i.join(__dirname,`../style/${this.getConfigValue("theme")}.css`);this.getConfigValue("styleOverridePath")&&(a=this.getConfigValue("styleOverridePath"));if(!this.getConfigValue("useCssFile")){const e=t.readFileSync(a,"utf8");o.raw(`<style type="text/css">${e}</style>`)}else o.ele("link",{rel:"stylesheet",type:"text/css",href:a});const r=s.ele("body");return e&&r.raw(e.toString()),this.getConfigValue("customScriptPath")&&r.raw(`<script src="${this.getConfigValue("customScriptPath")}"><\/script>`),{fullHtml:s.toString(),content:e?e.toString():""}}renderTestSuiteHeader(e,t){const s=e.ele("summary",{class:"suite-info"});s.ele("div",{class:"suite-path"},t.testFilePath);const i=(t.perfStats.end-t.perfStats.start)/1e3,n=["suite-time"];i>this.getConfigValue("executionTimeWarningThreshold")&&n.push("warn"),s.ele("div",{class:n.join(" ")},`${i}s`)}async renderTestReportContent(){try{if(!this.testData||0===Object.entries(this.testData).length)throw Error("No test data provided");const t=n.begin().element("main",{class:"jesthtml-content"}),s=t.ele("header");s.ele("h1",{id:"title"},this.getConfigValue("pageTitle"));const i=this.getConfigValue("logo");i&&s.ele("img",{id:"logo",src:i});const o=t.ele("section",{id:"metadata-container"});if(this.testData.startTime&&!isNaN(this.testData.startTime)){const t=new Date(this.testData.startTime);if(t){const s=e(t,this.getConfigValue("dateFormat"));o.ele("div",{id:"timestamp"},`Started: ${s}`)}}this.renderAdditionalInformation(o);const a=o.ele("div",{id:"summary"}),r=a.ele("div",{id:"suite-summary"}),u=(e,t)=>[`summary-${e}`,t>0?"":" summary-empty"].join(" ");r.ele("div",{class:"summary-total"},`Suites (${this.testData.numTotalTestSuites})`),r.ele("div",{class:u("passed",this.testData.numPassedTestSuites)},`${this.testData.numPassedTestSuites} passed`),r.ele("div",{class:u("failed",this.testData.numFailedTestSuites)},`${this.testData.numFailedTestSuites} failed`),r.ele("div",{class:u("pending",this.testData.numPendingTestSuites)},`${this.testData.numPendingTestSuites} pending`),this.testData.snapshot&&this.testData.snapshot.unchecked>0&&this.getConfigValue("includeObsoleteSnapshots")&&r.ele("div",{class:"summary-obsolete-snapshots"},`${this.testData.snapshot.unchecked} obsolete snapshots`);const c=a.ele("div",{id:"test-summary"});c.ele("div",{class:"summary-total"},`Tests (${this.testData.numTotalTests})`),c.ele("div",{class:u("passed",this.testData.numPassedTests)},`${this.testData.numPassedTests} passed`),c.ele("div",{class:u("failed",this.testData.numFailedTests)},`${this.testData.numFailedTests} failed`),c.ele("div",{class:u("pending",this.testData.numPendingTests)},`${this.testData.numPendingTests} pending`);const d=((e,t)=>{const{sortType:s,params:i}=function(e){if(!e)return{sortType:null};const[t,s]=e.split(":").map((e=>e.trim())),i=s?.split(",").map((e=>e.trim()));if(!["status","executiondesc","executionasc","titledesc","titleasc"].includes(t.toLowerCase()))return{sortType:null};return{sortType:t.toLowerCase(),params:i}}(t);switch(s){case"status":{const t=i?.every((e=>g.includes(e)))?i:void 0;return f(e,t)}case"executiondesc":return p(e);case"executionasc":return m(e);case"titledesc":return y(e);case"titleasc":return S(e);default:return e}})(this.testData.testResults,this.getConfigValue("sort")),h=this.getConfigValue("statusIgnoreFilter");let T=[];return h&&(T=h.replace(/\s/g,"").toLowerCase().split(",")),d&&d.forEach(((e,s)=>{const i=t.ele("details",{id:`suite-${s+1}`,class:"suite-container",open:this.getConfigValue("collapseSuitesByDefault")?void 0:""});this.renderTestSuiteHeader(i,e);const n=i.ele("div",{class:"suite-tests"});if(!e.testResults||e.testResults.length<=0){if(e.failureMessage&&this.getConfigValue("includeSuiteFailure")){n.ele("div",{class:"test-result failed"}).ele("div",{class:"failureMessages suiteFailure"}," ").ele("pre",{class:"failureMsg"},l(e.failureMessage))}}else e.testResults.filter((e=>!T.includes(e.status))).forEach((async e=>{const t=n.ele("div",{class:`test-result ${e.status}`}),s=t.ele("div",{class:"test-info"});if(s.ele("div",{class:"test-suitename"},e.ancestorTitles&&e.ancestorTitles.length>0?e.ancestorTitles.join(" > "):" "),s.ele("div",{class:"test-title"},e.title),s.ele("div",{class:"test-status"},e.status),s.ele("div",{class:"test-duration"},e.duration?e.duration/1e3+"s":" "),e.failureMessages&&e.failureMessages.length>0&&this.getConfigValue("includeFailureMsg")){const s=t.ele("div",{class:"failureMessages"}," ");e.failureMessages.map((e=>this.getConfigValue("includeStackTrace")?e:e.split(/\n\s+at/)[0].trim().replace(/\n+$/,""))).forEach((e=>{s.ele("pre",{class:"failureMsg"},l(e))}))}})),this.consoleLogList&&this.consoleLogList.length>0&&this.getConfigValue("includeConsoleLog")&&this.renderSuiteConsoleLogs(e,i),e.snapshot&&e.snapshot.unchecked>0&&this.getConfigValue("includeObsoleteSnapshots")&&this.renderSuiteObsoleteSnapshots(i,e)})),t}catch(e){r(e)}}renderSuiteConsoleLogs(e,t){const s=this.consoleLogList.find((t=>t.filePath===e.testFilePath));if(s&&s.logs.length>0){const e=t.ele("div",{class:"suite-consolelog"});e.ele("div",{class:"suite-consolelog-header"},"Console Log"),s.logs.forEach((t=>{const s=e.ele("div",{class:"suite-consolelog-item"});this.getConfigValue("hideConsoleLogOrigin")||s.ele("pre",{class:"suite-consolelog-item-origin"},l(t.origin)),s.ele("pre",{class:"suite-consolelog-item-message"},l(t.message))}))}}renderSuiteObsoleteSnapshots(e,t){const s=e.ele("div",{class:"suite-obsolete-snapshots"});s.ele("div",{class:"suite-obsolete-snapshots-header"},"Obsolete snapshots");s.ele("div",{class:"suite-obsolete-snapshots-item"}).ele("pre",{class:"suite-obsolete-snapshots-item-message"},t.snapshot.uncheckedKeys.join("\n"))}renderAdditionalInformation(e){const t=this.getConfigValue("additionalInformation");if(t&&Array.isArray(t)&&t.length>0){const s=e.ele("div",{class:"additional-information-container"});for(const e of t)s.ele("div",{class:"additional-information"},`${e.label}: ${e.value}`);return s}}getConfigValue(e){return this.config[e]}}const j=e=>new b(e).generate();module.exports=function(e,t){const s=[];if(Object.prototype.hasOwnProperty.call(e,"testResults")){const s=e;return j({testData:s,options:t}),s}this.onTestResult=(e,t)=>{t.console&&s.push({filePath:t.testFilePath,logs:t.console})},this.onRunComplete=(i,n)=>j({testData:n,options:t,jestConfig:e,consoleLogs:s})};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-html-reporter",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "Jest test results processor for generating a summary in HTML",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"unpkg": "dist/index.js",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"test": "npm run lint && npm run jest",
|
|
16
16
|
"test:watch": "npm run jest -- --watch --no-coverage",
|
|
17
17
|
"bundle": "rollup -c",
|
|
18
|
-
"build": "npm run test && npm run bundle"
|
|
18
|
+
"build": "npm run test && npm run bundle",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
19
20
|
},
|
|
20
21
|
"repository": {
|
|
21
22
|
"type": "git",
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--text-primary: #eee;
|
|
3
|
+
--text-secondary: #aaa;
|
|
4
|
+
--success: #2ecc71;
|
|
5
|
+
--success-bright: #1e3d2a;
|
|
6
|
+
--danger: #e74c3c;
|
|
7
|
+
--danger-bright: #3d1e1e;
|
|
8
|
+
--warning: #f39c12;
|
|
9
|
+
--warning-bright: #3d2c1e;
|
|
10
|
+
--panel: #1f1f1f;
|
|
11
|
+
--border: #444;
|
|
12
|
+
--disabled: #666;
|
|
13
|
+
background-color: #121212;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
html,
|
|
17
|
+
body {
|
|
18
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
19
|
+
font-size: 16px;
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
color: var(--text-primary);
|
|
23
|
+
}
|
|
24
|
+
body {
|
|
25
|
+
padding: 2rem 1rem;
|
|
26
|
+
}
|
|
27
|
+
.jesthtml-content {
|
|
28
|
+
margin: 0 auto;
|
|
29
|
+
max-width: 70rem;
|
|
30
|
+
}
|
|
31
|
+
header {
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
}
|
|
35
|
+
#title {
|
|
36
|
+
margin: 0;
|
|
37
|
+
flex-grow: 1;
|
|
38
|
+
}
|
|
39
|
+
#logo {
|
|
40
|
+
height: 4rem;
|
|
41
|
+
}
|
|
42
|
+
#timestamp {
|
|
43
|
+
color: var(--text-secondary);
|
|
44
|
+
margin-top: 0.5rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#metadata-container {
|
|
48
|
+
display: flex;
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
gap: 2rem;
|
|
51
|
+
margin-bottom: 2rem;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.additional-information-container {
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-direction: column;
|
|
57
|
+
gap: 0.5rem;
|
|
58
|
+
color: var(--text-secondary);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** SUMMARY */
|
|
62
|
+
#summary {
|
|
63
|
+
color: var(--text-primary);
|
|
64
|
+
display: flex;
|
|
65
|
+
font-family: monospace;
|
|
66
|
+
font-size: 1rem;
|
|
67
|
+
}
|
|
68
|
+
#summary > div {
|
|
69
|
+
margin-right: 0.5rem;
|
|
70
|
+
background: var(--panel);
|
|
71
|
+
padding: 1rem;
|
|
72
|
+
min-width: 15rem;
|
|
73
|
+
}
|
|
74
|
+
#summary > div:last-child {
|
|
75
|
+
margin-right: 0;
|
|
76
|
+
}
|
|
77
|
+
@media only screen and (max-width: 720px) {
|
|
78
|
+
#summary {
|
|
79
|
+
flex-direction: column;
|
|
80
|
+
}
|
|
81
|
+
#summary > div {
|
|
82
|
+
margin-right: 0;
|
|
83
|
+
margin-top: 1rem;
|
|
84
|
+
}
|
|
85
|
+
#summary > div:first-child {
|
|
86
|
+
margin-top: 0;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.summary-total {
|
|
91
|
+
font-weight: bold;
|
|
92
|
+
margin-bottom: 0.5rem;
|
|
93
|
+
}
|
|
94
|
+
.summary-passed {
|
|
95
|
+
color: var(--success);
|
|
96
|
+
border-left: 0.4rem solid var(--success);
|
|
97
|
+
padding-left: 0.5rem;
|
|
98
|
+
margin-bottom: 0.15rem;
|
|
99
|
+
}
|
|
100
|
+
.summary-failed,
|
|
101
|
+
.summary-obsolete-snapshots {
|
|
102
|
+
color: var(--danger);
|
|
103
|
+
border-left: 0.4rem solid var(--danger);
|
|
104
|
+
padding-left: 0.5rem;
|
|
105
|
+
margin-bottom: 0.15rem;
|
|
106
|
+
}
|
|
107
|
+
.summary-pending {
|
|
108
|
+
color: var(--warning);
|
|
109
|
+
border-left: 0.4rem solid var(--warning);
|
|
110
|
+
padding-left: 0.5rem;
|
|
111
|
+
margin-bottom: 0.15rem;
|
|
112
|
+
}
|
|
113
|
+
.summary-empty {
|
|
114
|
+
color: var(--disabled);
|
|
115
|
+
border-left: 0.4rem solid var(--disabled);
|
|
116
|
+
margin-bottom: 0.15rem;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.test-result {
|
|
120
|
+
padding: 1rem;
|
|
121
|
+
margin-bottom: 0.25rem;
|
|
122
|
+
}
|
|
123
|
+
.test-result:last-child {
|
|
124
|
+
border: 0;
|
|
125
|
+
}
|
|
126
|
+
.test-result.passed {
|
|
127
|
+
background-color: var(--success-bright);
|
|
128
|
+
color: var(--success);
|
|
129
|
+
}
|
|
130
|
+
.test-result.failed {
|
|
131
|
+
background-color: var(--danger-bright);
|
|
132
|
+
color: var(--danger);
|
|
133
|
+
}
|
|
134
|
+
.test-result.pending {
|
|
135
|
+
background-color: var(--warning-bright);
|
|
136
|
+
color: var(--warning);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.test-info {
|
|
140
|
+
display: flex;
|
|
141
|
+
justify-content: space-between;
|
|
142
|
+
}
|
|
143
|
+
.test-suitename {
|
|
144
|
+
width: 20%;
|
|
145
|
+
text-align: left;
|
|
146
|
+
font-weight: bold;
|
|
147
|
+
word-break: break-word;
|
|
148
|
+
}
|
|
149
|
+
.test-title {
|
|
150
|
+
width: 40%;
|
|
151
|
+
text-align: left;
|
|
152
|
+
font-style: italic;
|
|
153
|
+
}
|
|
154
|
+
.test-status {
|
|
155
|
+
width: 20%;
|
|
156
|
+
text-align: right;
|
|
157
|
+
}
|
|
158
|
+
.test-duration {
|
|
159
|
+
width: 10%;
|
|
160
|
+
text-align: right;
|
|
161
|
+
font-size: 0.85rem;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.failureMessages {
|
|
165
|
+
padding: 0 1rem;
|
|
166
|
+
margin-top: 1rem;
|
|
167
|
+
border-top: 1px dashed var(--danger);
|
|
168
|
+
}
|
|
169
|
+
.failureMessages.suiteFailure {
|
|
170
|
+
border-top: none;
|
|
171
|
+
}
|
|
172
|
+
.failureMsg {
|
|
173
|
+
white-space: pre-wrap;
|
|
174
|
+
white-space: -moz-pre-wrap;
|
|
175
|
+
white-space: -pre-wrap;
|
|
176
|
+
white-space: -o-pre-wrap;
|
|
177
|
+
word-wrap: break-word;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.suite-container {
|
|
181
|
+
margin-bottom: 1rem;
|
|
182
|
+
}
|
|
183
|
+
.suite-info {
|
|
184
|
+
padding: 1rem;
|
|
185
|
+
background-color: var(--panel);
|
|
186
|
+
color: var(--text-secondary);
|
|
187
|
+
border: 0.15rem solid;
|
|
188
|
+
border-color: var(--panel);
|
|
189
|
+
display: flex;
|
|
190
|
+
align-items: center;
|
|
191
|
+
margin-bottom: 0.25rem;
|
|
192
|
+
}
|
|
193
|
+
.suite-info:hover {
|
|
194
|
+
border-color: var(--border);
|
|
195
|
+
cursor: pointer;
|
|
196
|
+
}
|
|
197
|
+
.suite-info .suite-path {
|
|
198
|
+
word-break: break-all;
|
|
199
|
+
flex-grow: 1;
|
|
200
|
+
font-family: monospace;
|
|
201
|
+
font-size: 1rem;
|
|
202
|
+
}
|
|
203
|
+
.suite-info .suite-time {
|
|
204
|
+
margin-left: 1rem;
|
|
205
|
+
padding: 0.2rem 0.3rem;
|
|
206
|
+
font-size: 0.85rem;
|
|
207
|
+
}
|
|
208
|
+
.suite-info .suite-time.warn {
|
|
209
|
+
background-color: var(--danger);
|
|
210
|
+
color: #fff;
|
|
211
|
+
}
|
|
212
|
+
.suite-info:before {
|
|
213
|
+
content: "\2303";
|
|
214
|
+
display: inline-block;
|
|
215
|
+
margin-right: 1rem;
|
|
216
|
+
transform: rotate(180deg) translateY(0.15rem);
|
|
217
|
+
}
|
|
218
|
+
.suite-container[open] .suite-info:before {
|
|
219
|
+
transform: rotate(0deg) translateY(0.15rem);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* CONSOLE LOGS */
|
|
223
|
+
.suite-consolelog {
|
|
224
|
+
margin-bottom: 0.25rem;
|
|
225
|
+
padding: 1rem;
|
|
226
|
+
background-color: var(--panel);
|
|
227
|
+
}
|
|
228
|
+
.suite-consolelog-header {
|
|
229
|
+
font-weight: bold;
|
|
230
|
+
}
|
|
231
|
+
.suite-consolelog-item {
|
|
232
|
+
padding: 0.5rem;
|
|
233
|
+
}
|
|
234
|
+
.suite-consolelog-item pre {
|
|
235
|
+
margin: 0.5rem 0;
|
|
236
|
+
white-space: pre-wrap;
|
|
237
|
+
white-space: -moz-pre-wrap;
|
|
238
|
+
white-space: -pre-wrap;
|
|
239
|
+
white-space: -o-pre-wrap;
|
|
240
|
+
word-wrap: break-word;
|
|
241
|
+
}
|
|
242
|
+
.suite-consolelog-item-origin {
|
|
243
|
+
color: var(--text-secondary);
|
|
244
|
+
font-weight: bold;
|
|
245
|
+
}
|
|
246
|
+
.suite-consolelog-item-message {
|
|
247
|
+
color: var(--text-primary);
|
|
248
|
+
font-size: 1rem;
|
|
249
|
+
padding: 0 0.5rem;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* OBSOLETE SNAPSHOTS */
|
|
253
|
+
.suite-obsolete-snapshots {
|
|
254
|
+
margin-bottom: 0.25rem;
|
|
255
|
+
padding: 1rem;
|
|
256
|
+
background-color: var(--danger-bright);
|
|
257
|
+
color: var(--danger);
|
|
258
|
+
}
|
|
259
|
+
.suite-obsolete-snapshots-header {
|
|
260
|
+
font-weight: bold;
|
|
261
|
+
}
|
|
262
|
+
.suite-obsolete-snapshots-item {
|
|
263
|
+
padding: 0.5rem;
|
|
264
|
+
}
|
|
265
|
+
.suite-obsolete-snapshots-item pre {
|
|
266
|
+
margin: 0.5rem 0;
|
|
267
|
+
white-space: pre-wrap;
|
|
268
|
+
white-space: -moz-pre-wrap;
|
|
269
|
+
white-space: -pre-wrap;
|
|
270
|
+
white-space: -o-pre-wrap;
|
|
271
|
+
word-wrap: break-word;
|
|
272
|
+
}
|
|
273
|
+
.suite-obsolete-snapshots-item-message {
|
|
274
|
+
color: var(--text-primary);
|
|
275
|
+
font-size: 1rem;
|
|
276
|
+
padding: 0 0.5rem;
|
|
277
|
+
}
|