jest-html-reporter 3.10.2 โ 4.0.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 +31 -44
- package/dist/index.js +1 -1
- package/package.json +25 -22
- package/style/defaultTheme.css +60 -56
package/README.md
CHANGED
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
<h3 align="center">jest-html-reporter</h3>
|
|
4
4
|
<p align="center">
|
|
5
5
|
A <a href="https://github.com/facebook/jest">Jest</a> test results processor for generating a summary in HTML.
|
|
6
|
-
<br>
|
|
7
|
-
<a href="https://github.com/Hargne/jest-html-reporter/wiki"><strong>Documentation ยป</strong></a>
|
|
8
6
|
<br />
|
|
9
7
|
<br />
|
|
10
8
|
<img src="https://img.shields.io/npm/v/jest-html-reporter?style=flat-square">
|
|
9
|
+
<img src="https://img.shields.io/node/v/jest-html-reporter?style=flat-square">
|
|
11
10
|
<img src="https://img.shields.io/npm/dm/jest-html-reporter?style=flat-square">
|
|
12
|
-
<img src="https://img.shields.io/github/actions/workflow/status/Hargne/jest-html-reporter/main.yml?branch=master&style=flat-square">
|
|
13
11
|
<br />
|
|
14
12
|
<br />
|
|
15
13
|
<small>Inspired by <a href="https://github.com/matthias-schuetz/karma-htmlfile-reporter">karma-htmlfile-reporter</a></small>
|
|
@@ -52,7 +50,7 @@ Configure Jest to process the test results by adding the following entry to the
|
|
|
52
50
|
|
|
53
51
|
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.
|
|
54
52
|
|
|
55
|
-
There are multiple configuration options available.
|
|
53
|
+
There are multiple configuration options available. Read more about these further down in this document.
|
|
56
54
|
|
|
57
55
|
#### Alternative Usage as a Test Results Processor
|
|
58
56
|
|
|
@@ -64,47 +62,40 @@ To run the reporter as a test results processor (after Jest is complete instead
|
|
|
64
62
|
}
|
|
65
63
|
```
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
***Note:** When running as a testResultsProcessor, the configuration needs be placed within a new file named `jesthtmlreporter.config.json` residing in the root folder.*
|
|
66
|
+
|
|
67
|
+
## ๐ Configuration Options (All Optional)
|
|
68
|
+
|
|
69
|
+
| Option | Type | Default | Description |
|
|
70
|
+
| ----------------------------------- | --------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
71
|
+
| **`append`** | `boolean` | `false` | Append test results to an existing report. |
|
|
72
|
+
| **`boilerplate`** | `string` | `null` | Path to an HTML boilerplate file. The `{jesthtmlreporter-content}` variable will be replaced with test results. |
|
|
73
|
+
| **`collapseSuitesByDefault`** | `boolean` | `false` | Collapse test suites (accordions) by default. |
|
|
74
|
+
| **`customScriptPath`** | `string` | `null` | Path to an external script file injected into the report. |
|
|
75
|
+
| **`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. |
|
|
76
|
+
| **`executionTimeWarningThreshold`** | `number` | `5` | Warn if a test suite exceeds this execution time (in seconds). |
|
|
77
|
+
| **`includeConsoleLog`** | `boolean` | `false` | Include `console.log` outputs in the report (**requires** `--verbose=false`). |
|
|
78
|
+
| **`includeFailureMsg`** | `boolean` | `false` | Show detailed error messages for failed tests. |
|
|
79
|
+
| **`includeStackTrace`** | `boolean` | `true` | Show stack traces for failed tests. |
|
|
80
|
+
| **`includeSuiteFailure`** | `boolean` | `false` | Show detailed errors for entire failed test suites. |
|
|
81
|
+
| **`includeObsoleteSnapshots`** | `boolean` | `false` | Show obsolete snapshot names. |
|
|
82
|
+
| **`logo`** | `string` | `null` | Path to an image file to display in the report header. |
|
|
83
|
+
| **`outputPath`** | `string` | `./test-report.html` | Full path for the output report file (**must end in `.html`**). |
|
|
84
|
+
| **`pageTitle`** | `string` | `"Test Report"` | Title of the document and top-level heading. |
|
|
85
|
+
| **`sort`** | `string` | `null` | Sort test results by a specific method. Available values:<br> โค **`status`** โ Sorts by test status (**pending โ failed โ passed**).<br> โค **`status:{custom-order}`** โ Custom status order (e.g., `"status:failed,passed,pending"`).<br> โค **`executionasc`** โ Sorts by execution time **ascending**.<br> โค **`executiondesc`** โ Sorts by execution time **descending**.<br> โค **`titleasc`** โ Sorts by suite filename/test name **ascending**.<br> โค **`titledesc`** โ Sorts by suite filename/test name **descending**. |
|
|
86
|
+
| **`statusIgnoreFilter`** | `string` | `null` | **Comma-separated** list of statuses to exclude: `"passed"`, `"pending"`, `"failed"`. |
|
|
87
|
+
| **`styleOverridePath`** | `string` | `null` | Path to a CSS file to override default styles. |
|
|
88
|
+
| **`useCssFile`** | `boolean` | `false` | Link to the CSS file instead of inlining styles. |
|
|
69
89
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<img src="https://img.shields.io/node/v/jest-html-reporter?style=flat-square">
|
|
73
|
-
|
|
74
|
-
This plugin is compatible with Node version `^4.8.3`
|
|
75
|
-
|
|
76
|
-
## Configuration
|
|
77
|
-
|
|
78
|
-
Please note that all configuration properties are optional.
|
|
79
|
-
|
|
80
|
-
| Property | Type | Description | Default |
|
|
81
|
-
| ------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
82
|
-
| `append` | `BOOLEAN` | If set to true, new test results will be appended to the existing test report | `false` |
|
|
83
|
-
| `boilerplate` | `STRING` | The path to a boilerplate file that should be used to render the body of the test results into. `{jesthtmlreporter-content}` within the boilerplate will be replaced with the test results | `null` |
|
|
84
|
-
| `collapseSuitesByDefault` | `BOOLEAN` | Whether to collapse test suites by default or not | `false` |
|
|
85
|
-
| `customScriptPath` | `STRING` | Path to a javascript file that should be injected into the test report | `null` |
|
|
86
|
-
| `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"` |
|
|
87
|
-
| `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` |
|
|
88
|
-
| `includeConsoleLog` | `BOOLEAN` | If set to true, this will output all triggered console logs for each test suite. Please note that you have to run Jest together with `--verbose=false` in order to have Jest catch any logs during the tests. | `false` |
|
|
89
|
-
| `includeFailureMsg` | `BOOLEAN` | If this setting is set to true, this will output the detailed failure message for each failed test. | `false` |
|
|
90
|
-
| `includeStackTrace` | `BOOLEAN` | Turning this option off will cut the stack trace from the failure messages. | `true` |
|
|
91
|
-
| `includeSuiteFailure` | `BOOLEAN` | If set to true, this will output the detailed failure message for complete suite failures. | `false` |
|
|
92
|
-
| `includeObsoleteSnapshots` | `BOOLEAN` | If set to true, this will output obsolete snapshot names. | `false` |
|
|
93
|
-
| `logo` | `STRING` | Path to a logo that will be included in the header of the report | `null` |
|
|
94
|
-
| `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"` |
|
|
95
|
-
| `pageTitle` | `STRING` | The title of the document. This string will also be outputted on the top of the page. | `"Test Suite"` |
|
|
96
|
-
| `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"` |
|
|
97
|
-
| `statusIgnoreFilter` | `STRING` | A comma-separated string of the test result statuses that should be ignored when rendering the report. Available statuses are: `"passed"`, `"pending"`, `"failed"` | `null` |
|
|
98
|
-
| `styleOverridePath` | `STRING` | The path to a file containing CSS styles that should override the default styling.\* | `null` |
|
|
99
|
-
| `useCssFile` | `BOOLEAN` | If set to true, the CSS styles will link in the current theme's .css file instead of inlining its content on the page | `false` |
|
|
90
|
+
## Continuous Integration
|
|
100
91
|
|
|
101
|
-
|
|
92
|
+
All the configuration options provided in the table above are available via environment variables and follows the pattern of snake case in uppercase prepended with `JEST_HTML_REPORTER_`
|
|
102
93
|
|
|
103
|
-
|
|
94
|
+
**Example:** `customScriptPath` -> `JEST_HTML_REPORTER_CUSTOM_SCRIPT_PATH`
|
|
104
95
|
|
|
105
|
-
|
|
96
|
+
***NOTE:** Environment variables will take precedence over configurations set in jesthtmlreporter.config.json and package.json*
|
|
106
97
|
|
|
107
|
-
|
|
98
|
+
### CI Example
|
|
108
99
|
|
|
109
100
|
Here is an example of dynamically naming your output file and test report title to match your current branch that one might see in a automated deployment pipeline before running their tests.
|
|
110
101
|
|
|
@@ -113,7 +104,3 @@ export BRANCH_NAME=`git symbolic-ref HEAD 2>/dev/null | cut -d"/" -f 3`
|
|
|
113
104
|
export JEST_HTML_REPORTER_OUTPUT_PATH=/home/username/jest-test-output/test-reports/"$BRANCH_NAME".html
|
|
114
105
|
export JEST_HTML_REPORTER_PAGE_TITLE="$BRANCH_NAME"\ Test\ Report
|
|
115
106
|
```
|
|
116
|
-
|
|
117
|
-
#### Configuration Environment Variables
|
|
118
|
-
|
|
119
|
-
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.
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("dateformat"),t=require("fs"),s=require("mkdirp"),a=require("path"),i=require("strip-ansi"),l=require("xmlbuilder");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),r=n(t),u=n(s),c=n(a),d=n(i),g=n(l);const h=e=>{const t=[],s=[],a=[];return e.forEach((e=>{const i=[],l=[],n=[];e.testResults.forEach((e=>{"pending"===e.status?i.push(e):"failed"===e.status?l.push(e):n.push(e)})),i.length>0&&t.push({...e,testResults:i}),l.length>0&&s.push({...e,testResults:l}),n.length>0&&a.push({...e,testResults:n})})),[].concat(t,s,a)},f=e=>(e&&e.sort(((e,t)=>t.perfStats.end-t.perfStats.start-(e.perfStats.end-e.perfStats.start))),e),p=e=>(e&&e.sort(((e,t)=>e.perfStats.end-e.perfStats.start-(t.perfStats.end-t.perfStats.start))),e),T=e=>{if(e){const t=e.sort(((e,t)=>E(e.testFilePath,t.testFilePath,!0)));return t.forEach((e=>{e.testResults.sort(((e,t)=>E(e.ancestorTitles.join(" "),t.ancestorTitles.join(" "),!0))),e.testResults.sort(((e,t)=>E(e.title,t.title,!0)))})),t}return e},m=e=>{if(e){const t=e.sort(((e,t)=>E(e.testFilePath,t.testFilePath)));return t.forEach((e=>{e.testResults.sort(((e,t)=>E(e.ancestorTitles.join(" "),t.ancestorTitles.join(" ")))),e.testResults.sort(((e,t)=>E(e.title,t.title)))})),t}return e},E=(e,t,s=!1)=>!s&&e<t||s&&e>t?-1:!s&&e>t||s&&e<t?1:0;class S{constructor(e){this.testData=e.testData,this.jestConfig=e.jestConfig,this.consoleLogList=e.consoleLogs,this.setupConfig(e.options)}async generate(){try{const e=await this.renderTestReport(),t=this.replaceRootDirInPath(this.jestConfig?this.jestConfig.rootDir:"",this.getConfigValue("outputPath"));await u.default(c.default.dirname(t));let s=!0;if(this.getConfigValue("append")){r.default.existsSync(t)&&(await this.appendToFile(t,e.content.toString()),s=!1)}return s&&r.default.writeFileSync(t,e.fullHtml.toString()),this.logMessage("success",`Report generated (${t})`),e.fullHtml}catch(e){this.logMessage("error",e)}}async renderTestReport(){const e=await this.renderTestReportContent();if(this.getConfigValue("boilerplate")){const t=this.replaceRootDirInPath(this.jestConfig?this.jestConfig.rootDir:"",this.getConfigValue("boilerplate")),s=r.default.readFileSync(t,"utf8");return{content:e.toString(),fullHtml:s.replace("{jesthtmlreporter-content}",e&&e.toString())}}const t=g.default.create({html:{}}),s=t.ele("head");s.ele("meta",{charset:"utf-8"}),s.ele("title",{},this.getConfigValue("pageTitle"));let a=c.default.join(__dirname,`../style/${this.getConfigValue("theme")}.css`);this.getConfigValue("styleOverridePath")&&(a=this.getConfigValue("styleOverridePath"));if(!this.getConfigValue("useCssFile")&&!this.getConfigValue("styleOverridePath")){const e=r.default.readFileSync(a,"utf8");s.raw(`<style type="text/css">${e}</style>`)}else s.ele("link",{rel:"stylesheet",type:"text/css",href:a});const i=t.ele("body");return e&&i.raw(e.toString()),this.getConfigValue("customScriptPath")&&i.raw(`<script src="${this.getConfigValue("customScriptPath")}"><\/script>`),{fullHtml:t.toString(),content:e.toString()}}renderTestSuiteHeader(e,t,s){const a=`collapsible-${s}`;e.ele("input",{id:a,type:"checkbox",class:"toggle",checked:this.getConfigValue("collapseSuitesByDefault")?null:"checked"});const i=e.ele("label",{for:a}).ele("div",{class:"suite-info"});i.ele("div",{class:"suite-path"},t.testFilePath);const l=(t.perfStats.end-t.perfStats.start)/1e3,n=["suite-time"];l>this.getConfigValue("executionTimeWarningThreshold")&&n.push("warn"),i.ele("div",{class:n.join(" ")},`${l}s`)}async renderTestReportContent(){try{if(!this.testData||0===Object.entries(this.testData).length)throw Error("No test data provided");const e=g.default.begin().element("div",{class:"jesthtml-content"}),t=e.ele("header");t.ele("h1",{id:"title"},this.getConfigValue("pageTitle"));const s=this.getConfigValue("logo");s&&t.ele("img",{id:"logo",src:s});const a=e.ele("div",{id:"metadata-container"});if(this.testData.startTime&&!isNaN(this.testData.startTime)){const e=new Date(this.testData.startTime);if(e){const t=o.default(e,this.getConfigValue("dateFormat"));a.ele("div",{id:"timestamp"},`Started: ${t}`)}}const i=a.ele("div",{id:"summary"}),l=i.ele("div",{id:"suite-summary"}),n=(e,t)=>[`summary-${e}`,t>0?"":" summary-empty"].join(" ");l.ele("div",{class:"summary-total"},`Suites (${this.testData.numTotalTestSuites})`),l.ele("div",{class:n("passed",this.testData.numPassedTestSuites)},`${this.testData.numPassedTestSuites} passed`),l.ele("div",{class:n("failed",this.testData.numFailedTestSuites)},`${this.testData.numFailedTestSuites} failed`),l.ele("div",{class:n("pending",this.testData.numPendingTestSuites)},`${this.testData.numPendingTestSuites} pending`),this.testData.snapshot&&this.testData.snapshot.unchecked>0&&this.getConfigValue("includeObsoleteSnapshots")&&l.ele("div",{class:"summary-obsolete-snapshots"},`${this.testData.snapshot.unchecked} obsolete snapshots`);const r=i.ele("div",{id:"test-summary"});r.ele("div",{class:"summary-total"},`Tests (${this.testData.numTotalTests})`),r.ele("div",{class:n("passed",this.testData.numPassedTests)},`${this.testData.numPassedTests} passed`),r.ele("div",{class:n("failed",this.testData.numFailedTests)},`${this.testData.numFailedTests} failed`),r.ele("div",{class:n("pending",this.testData.numPendingTests)},`${this.testData.numPendingTests} pending`);const u=((e,t)=>{switch(t&&t.toLowerCase()){case"status":return h(e);case"executiondesc":return f(e);case"executionasc":return p(e);case"titledesc":return T(e);case"titleasc":return m(e);default:return e}})(this.testData.testResults,this.getConfigValue("sort")),c=this.getConfigValue("statusIgnoreFilter");let d=[];return c&&(d=c.replace(/\s/g,"").toLowerCase().split(",")),u&&u.forEach(((t,s)=>{const a=e.ele("div",{id:`suite-${s+1}`,class:"suite-container"});this.renderTestSuiteHeader(a,t,s);const i=a.ele("div",{class:"suite-tests"});if(!t.testResults||t.testResults.length<=0){if(t.failureMessage&&this.getConfigValue("includeSuiteFailure")){i.ele("div",{class:"test-result failed"}).ele("div",{class:"failureMessages suiteFailure"}," ").ele("pre",{class:"failureMsg"},this.sanitizeOutput(t.failureMessage))}}else t.testResults.filter((e=>!d.includes(e.status))).forEach((async e=>{const t=i.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/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"},this.sanitizeOutput(e))}))}})),this.consoleLogList&&this.consoleLogList.length>0&&this.getConfigValue("includeConsoleLog")&&this.renderSuiteConsoleLogs(t,a),t.snapshot&&t.snapshot.unchecked>0&&this.getConfigValue("includeObsoleteSnapshots")&&this.renderSuiteObsoleteSnapshots(a,t)})),e}catch(e){this.logMessage("error",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"},this.sanitizeOutput(t.origin)),s.ele("pre",{class:"suite-consolelog-item-message"},this.sanitizeOutput(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"))}setupConfig(e){const{append:t,boilerplate:s,collapseSuitesByDefault:a,customScriptPath:i,dateFormat:l,executionTimeWarningThreshold:n,logo:o,includeConsoleLog:u,includeFailureMsg:d,includeStackTrace:g,includeSuiteFailure:h,includeObsoleteSnapshots:f,outputPath:p,pageTitle:T,theme:m,sort:E,statusIgnoreFilter:S,styleOverridePath:R,useCssFile:V}=e||{};this.config={append:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_APPEND",configValue:t},boilerplate:{defaultValue:null,environmentVariable:"JEST_HTML_REPORTER_BOILERPLATE",configValue:s},collapseSuitesByDefault:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_COLLAPSE_SUITES_BY_DEFAULT",configValue:a},customScriptPath:{defaultValue:null,environmentVariable:"JEST_HTML_REPORTER_CUSTOM_SCRIPT_PATH",configValue:i},dateFormat:{defaultValue:"yyyy-mm-dd HH:MM:ss",environmentVariable:"JEST_HTML_REPORTER_DATE_FORMAT",configValue:l},executionTimeWarningThreshold:{defaultValue:5,environmentVariable:"JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD",configValue:n},logo:{defaultValue:null,environmentVariable:"JEST_HTML_REPORTER_LOGO",configValue:o},includeFailureMsg:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_INCLUDE_FAILURE_MSG",configValue:d},includeStackTrace:{defaultValue:!0,environmentVariable:"JEST_HTML_REPORTER_INCLUDE_STACK_TRACE",configValue:g},includeSuiteFailure:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_INCLUDE_SUITE_FAILURE",configValue:h},includeObsoleteSnapshots:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_INCLUDE_OBSOLETE_SNAPSHOTS",configValue:f},includeConsoleLog:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_INCLUDE_CONSOLE_LOG",configValue:u},outputPath:{defaultValue:c.default.join(process.cwd(),"test-report.html"),environmentVariable:"JEST_HTML_REPORTER_OUTPUT_PATH",configValue:p},pageTitle:{defaultValue:"Test Report",environmentVariable:"JEST_HTML_REPORTER_PAGE_TITLE",configValue:T},theme:{defaultValue:"defaultTheme",environmentVariable:"JEST_HTML_REPORTER_THEME",configValue:m},sort:{defaultValue:null,environmentVariable:"JEST_HTML_REPORTER_SORT",configValue:E},statusIgnoreFilter:{defaultValue:null,environmentVariable:"JEST_HTML_REPORTER_STATUS_FILTER",configValue:S},styleOverridePath:{defaultValue:null,environmentVariable:"JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH",configValue:R},useCssFile:{defaultValue:!1,environmentVariable:"JEST_HTML_REPORTER_USE_CSS_FILE",configValue:V}};try{const e=r.default.readFileSync(c.default.join(process.cwd(),"jesthtmlreporter.config.json"),"utf8");if(e){const t=JSON.parse(e);for(const e of Object.keys(t))e in this.config&&(this.config[e].configValue=t[e]);return this.config}}catch(e){}try{const e=r.default.readFileSync(c.default.join(process.cwd(),"package.json"),"utf8");if(e){const t=JSON.parse(e)["jest-html-reporter"];for(const e of Object.keys(t))e in this.config&&(this.config[e].configValue=t[e]);return this.config}}catch(e){}}getConfigValue(e){const t=this.config[e];if(t)return process.env[t.environmentVariable]?process.env[t.environmentVariable]:t.configValue??t.defaultValue}async appendToFile(e,t){let s=t;const a=r.default.readFileSync(e,"utf8"),i=/<body>(.*?)<\/body>/gm.exec(t);if(i){const[e]=i;s=e}let l=a;const n=/<\/body>/gm.exec(a),o=n?n.index:0;return l=[a.slice(0,o),s,a.slice(o)].join(""),r.default.writeFileSync(e,l)}replaceRootDirInPath(e,t){return/^<rootDir>/.test(t)?c.default.resolve(e,c.default.normalize("./"+t.substring(9))):t}logMessage(e,t){const s={default:"[37m%s[0m",success:"[32m%s[0m",error:"[31m%s[0m"},a=s[e]?s[e]:s.default,i=`jest-html-reporter >> ${t}`;return void 0===process.env.JEST_WORKER_ID&&console.log(a,i),{logColor:a,logMsg:i}}sanitizeOutput(e){return d.default(e.replace(/(\x1b\[\d*m)/g,"").replace(/([^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFC\u{10000}-\u{10FFFF}])/gu,""))}}const R=e=>new S(e).generate();module.exports=function(e,t){const s=[];if(Object.prototype.hasOwnProperty.call(e,"testResults")){const s=e;return R({testData:s,options:t}),s}this.onTestResult=(e,t)=>{t.console&&s.push({filePath:t.testFilePath,logs:t.console})},this.onRunComplete=(a,i)=>R({testData:i,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"),a=require("strip-ansi");function o(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 o("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 a(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 p=(e,t)=>{const s={pending:[],failed:[],passed:[]},i=[];e.forEach((e=>{const t=[],n=[],a=[],o=[];e.testResults.forEach((e=>{"pending"===e.status?t.push(e):"failed"===e.status?n.push(e):"passed"===e.status?a.push(e):o.push(e)})),t.length>0&&s.pending.push({...e,testResults:t}),n.length>0&&s.failed.push({...e,testResults:n}),a.length>0&&s.passed.push({...e,testResults:a}),o.length>0&&i.push({...e,testResults:o})}));const n=[...t||[],...["pending","failed","passed"].filter((e=>!(t||[]).includes(e)))],a=Object.entries(s).sort((([e],[t])=>n.indexOf(e)-n.indexOf(t))).flatMap((([,e])=>e));return[...a,...i]},f=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={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 v(e){try{if(t.existsSync(e))return JSON.parse(t.readFileSync(e,"utf8"))}catch{return{}}return{}}const C={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};function F(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 D{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||{};return{...T,...F(n),...F(s),...F(e),...F(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 a=!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),a=n?n[1]:s,o=/<\/body>/i.exec(i),r=o?o.index:0,l=[i.slice(0,r),a,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()),a=!1)}return a&&t.writeFileSync(n,e.fullHtml.toString()),o("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:{}}),a=s.ele("head");a.ele("meta",{charset:"utf-8"}),a.ele("title",{},this.getConfigValue("pageTitle"));let o=i.join(__dirname,`../style/${this.getConfigValue("theme")}.css`);this.getConfigValue("styleOverridePath")&&(o=this.getConfigValue("styleOverridePath"));if(!this.getConfigValue("useCssFile")&&!this.getConfigValue("styleOverridePath")){const e=t.readFileSync(o,"utf8");a.raw(`<style type="text/css">${e}</style>`)}else a.ele("link",{rel:"stylesheet",type:"text/css",href:o});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 a=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"));a.ele("div",{id:"timestamp"},`Started: ${s}`)}}const o=a.ele("div",{id:"summary"}),r=o.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=o.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 p(e,t)}case"executiondesc":return f(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"});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"))}getConfigValue(e){return this.config[e]}}const b=e=>new D(e).generate();module.exports=function(e,t){const s=[];if(Object.prototype.hasOwnProperty.call(e,"testResults")){const s=e;return b({testData:s,options:t}),s}this.onTestResult=(e,t)=>{t.console&&s.push({filePath:t.testFilePath,logs:t.console})},this.onRunComplete=(i,n)=>b({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": "
|
|
3
|
+
"version": "4.0.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",
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
12
|
"tsc": "tsc",
|
|
13
|
-
"lint": "
|
|
13
|
+
"lint": "eslint src/",
|
|
14
14
|
"jest": "jest --no-cache --config=jest.config.json",
|
|
15
|
-
"test": "npm run lint && npm run
|
|
15
|
+
"test": "npm run lint && npm run jest",
|
|
16
|
+
"test:watch": "npm run jest -- --watch --no-coverage",
|
|
16
17
|
"bundle": "rollup -c",
|
|
17
18
|
"build": "npm run test && npm run bundle"
|
|
18
19
|
},
|
|
@@ -34,41 +35,43 @@
|
|
|
34
35
|
},
|
|
35
36
|
"homepage": "https://github.com/Hargne/jest-html-reporter#readme",
|
|
36
37
|
"engines": {
|
|
37
|
-
"node": ">=
|
|
38
|
+
"node": ">=14.0.0"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
|
-
"
|
|
41
|
+
"@jest/reporters": "^29.7.0",
|
|
42
|
+
"@jest/test-result": "^29.7.0",
|
|
43
|
+
"@jest/types": "^29.6.3",
|
|
41
44
|
"dateformat": "3.0.2",
|
|
45
|
+
"mkdirp": "^1.0.3",
|
|
42
46
|
"strip-ansi": "6.0.1",
|
|
43
|
-
"xmlbuilder": "15.0.0"
|
|
44
|
-
"@jest/test-result": "^29.0.2",
|
|
45
|
-
"@jest/types": "^29.0.2"
|
|
47
|
+
"xmlbuilder": "15.0.0"
|
|
46
48
|
},
|
|
47
49
|
"peerDependencies": {
|
|
48
50
|
"jest": "19.x - 29.x",
|
|
49
51
|
"typescript": "^3.7.x || ^4.3.x || ^5.x"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"@rollup/plugin-
|
|
57
|
-
"@rollup/plugin-
|
|
54
|
+
"@eslint/js": "^9.19.0",
|
|
55
|
+
"@jest/console": "^29.7.0",
|
|
56
|
+
"@rollup/plugin-commonjs": "^28.0.2",
|
|
57
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
58
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
59
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
58
60
|
"@types/dateformat": "^3.0.X",
|
|
59
|
-
"@types/jest": "^29.
|
|
61
|
+
"@types/jest": "^29.5.14",
|
|
60
62
|
"@types/mkdirp": "1.0.2",
|
|
61
|
-
"@types/node": "
|
|
63
|
+
"@types/node": "^22.13.0",
|
|
62
64
|
"@types/sinon": "9.0.11",
|
|
63
|
-
"
|
|
64
|
-
"jest": "^29.0
|
|
65
|
-
"
|
|
66
|
-
"rollup
|
|
65
|
+
"eslint": "^9.19.0",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
68
|
+
"rollup": "^4.34.1",
|
|
67
69
|
"sinon": "^9.0.1",
|
|
68
70
|
"ts-jest": "^29.0.0",
|
|
69
|
-
"
|
|
71
|
+
"tslib": "^2.8.1",
|
|
70
72
|
"tslint-config-prettier": "^1.18.0",
|
|
71
|
-
"typescript": "^
|
|
73
|
+
"typescript": "^5.7.3",
|
|
74
|
+
"typescript-eslint": "^8.22.0"
|
|
72
75
|
},
|
|
73
76
|
"browserslist": [
|
|
74
77
|
"since 2017-06"
|
package/style/defaultTheme.css
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--text-primary: #111;
|
|
3
|
+
--text-secondary: #4F4F4F;
|
|
4
|
+
--success: #006633;
|
|
5
|
+
--success-bright: #80FFBF;
|
|
6
|
+
--danger: #CC071E;
|
|
7
|
+
--danger-bright: #FBDFE0;
|
|
8
|
+
--warning: #995C00;
|
|
9
|
+
--warning-bright: #FFEEA8;
|
|
10
|
+
--panel: #eee;
|
|
11
|
+
--border: #949494;
|
|
12
|
+
--disabled: #6B6B6B;
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
html,
|
|
2
16
|
body {
|
|
3
17
|
font-family: Arial, Helvetica, sans-serif;
|
|
4
|
-
font-size:
|
|
18
|
+
font-size: 16px;
|
|
5
19
|
margin: 0;
|
|
6
20
|
padding: 0;
|
|
7
|
-
color:
|
|
21
|
+
color: var(--text-primary);
|
|
8
22
|
}
|
|
9
23
|
body {
|
|
10
24
|
padding: 2rem 1rem;
|
|
11
|
-
font-size: 0.85rem;
|
|
12
25
|
}
|
|
13
26
|
.jesthtml-content {
|
|
14
27
|
margin: 0 auto;
|
|
@@ -26,21 +39,21 @@ header {
|
|
|
26
39
|
height: 4rem;
|
|
27
40
|
}
|
|
28
41
|
#timestamp {
|
|
29
|
-
color:
|
|
42
|
+
color: var(--text-secondary);
|
|
30
43
|
margin-top: 0.5rem;
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
/** SUMMARY */
|
|
34
47
|
#summary {
|
|
35
|
-
color:
|
|
48
|
+
color: var(--text-primary);
|
|
36
49
|
margin: 2rem 0;
|
|
37
50
|
display: flex;
|
|
38
51
|
font-family: monospace;
|
|
39
52
|
font-size: 1rem;
|
|
40
53
|
}
|
|
41
54
|
#summary > div {
|
|
42
|
-
margin-right:
|
|
43
|
-
background:
|
|
55
|
+
margin-right: 0.5rem;
|
|
56
|
+
background: var(--panel);
|
|
44
57
|
padding: 1rem;
|
|
45
58
|
min-width: 15rem;
|
|
46
59
|
}
|
|
@@ -53,7 +66,7 @@ header {
|
|
|
53
66
|
}
|
|
54
67
|
#summary > div {
|
|
55
68
|
margin-right: 0;
|
|
56
|
-
margin-top:
|
|
69
|
+
margin-top: 1rem;
|
|
57
70
|
}
|
|
58
71
|
#summary > div:first-child {
|
|
59
72
|
margin-top: 0;
|
|
@@ -65,24 +78,28 @@ header {
|
|
|
65
78
|
margin-bottom: 0.5rem;
|
|
66
79
|
}
|
|
67
80
|
.summary-passed {
|
|
68
|
-
color:
|
|
69
|
-
border-left: 0.4rem solid
|
|
81
|
+
color: var(--success);
|
|
82
|
+
border-left: 0.4rem solid var(--success);
|
|
70
83
|
padding-left: 0.5rem;
|
|
84
|
+
margin-bottom: 0.15rem;
|
|
71
85
|
}
|
|
72
86
|
.summary-failed,
|
|
73
87
|
.summary-obsolete-snapshots {
|
|
74
|
-
color:
|
|
75
|
-
border-left: 0.4rem solid
|
|
88
|
+
color: var(--danger);
|
|
89
|
+
border-left: 0.4rem solid var(--danger);
|
|
76
90
|
padding-left: 0.5rem;
|
|
91
|
+
margin-bottom: 0.15rem;
|
|
77
92
|
}
|
|
78
93
|
.summary-pending {
|
|
79
|
-
color:
|
|
80
|
-
border-left: 0.4rem solid
|
|
94
|
+
color: var(--warning);
|
|
95
|
+
border-left: 0.4rem solid var(--warning);
|
|
81
96
|
padding-left: 0.5rem;
|
|
97
|
+
margin-bottom: 0.15rem;
|
|
82
98
|
}
|
|
83
99
|
.summary-empty {
|
|
84
|
-
color:
|
|
85
|
-
border-left: 0.4rem solid
|
|
100
|
+
color: var(--disabled);
|
|
101
|
+
border-left: 0.4rem solid var(--disabled);
|
|
102
|
+
margin-bottom: 0.15rem;
|
|
86
103
|
}
|
|
87
104
|
|
|
88
105
|
.test-result {
|
|
@@ -93,16 +110,16 @@ header {
|
|
|
93
110
|
border: 0;
|
|
94
111
|
}
|
|
95
112
|
.test-result.passed {
|
|
96
|
-
background-color:
|
|
97
|
-
color:
|
|
113
|
+
background-color: var(--success-bright);
|
|
114
|
+
color: var(--success);
|
|
98
115
|
}
|
|
99
116
|
.test-result.failed {
|
|
100
|
-
background-color:
|
|
101
|
-
color:
|
|
117
|
+
background-color: var(--danger-bright);
|
|
118
|
+
color: var(--danger);
|
|
102
119
|
}
|
|
103
120
|
.test-result.pending {
|
|
104
|
-
background-color:
|
|
105
|
-
color:
|
|
121
|
+
background-color: var(--warning-bright);
|
|
122
|
+
color: var(--warning);
|
|
106
123
|
}
|
|
107
124
|
|
|
108
125
|
.test-info {
|
|
@@ -127,13 +144,13 @@ header {
|
|
|
127
144
|
.test-duration {
|
|
128
145
|
width: 10%;
|
|
129
146
|
text-align: right;
|
|
130
|
-
font-size: 0.
|
|
147
|
+
font-size: 0.85rem;
|
|
131
148
|
}
|
|
132
149
|
|
|
133
150
|
.failureMessages {
|
|
134
151
|
padding: 0 1rem;
|
|
135
152
|
margin-top: 1rem;
|
|
136
|
-
border-top: 1px dashed
|
|
153
|
+
border-top: 1px dashed var(--danger);
|
|
137
154
|
}
|
|
138
155
|
.failureMessages.suiteFailure {
|
|
139
156
|
border-top: none;
|
|
@@ -147,33 +164,20 @@ header {
|
|
|
147
164
|
}
|
|
148
165
|
|
|
149
166
|
.suite-container {
|
|
150
|
-
margin-bottom:
|
|
151
|
-
}
|
|
152
|
-
.suite-container > input[type="checkbox"] {
|
|
153
|
-
position: absolute;
|
|
154
|
-
left: -100vw;
|
|
155
|
-
}
|
|
156
|
-
.suite-container label {
|
|
157
|
-
display: block;
|
|
158
|
-
}
|
|
159
|
-
.suite-container .suite-tests {
|
|
160
|
-
overflow-y: hidden;
|
|
161
|
-
height: 0;
|
|
162
|
-
}
|
|
163
|
-
.suite-container > input[type="checkbox"]:checked ~ .suite-tests {
|
|
164
|
-
height: auto;
|
|
165
|
-
overflow: visible;
|
|
167
|
+
margin-bottom: 1rem;
|
|
166
168
|
}
|
|
167
169
|
.suite-info {
|
|
168
170
|
padding: 1rem;
|
|
169
|
-
background-color:
|
|
170
|
-
color:
|
|
171
|
+
background-color: var(--panel);
|
|
172
|
+
color: var(--text-secondary);
|
|
173
|
+
border: 0.15rem solid;
|
|
174
|
+
border-color: var(--panel);
|
|
171
175
|
display: flex;
|
|
172
176
|
align-items: center;
|
|
173
177
|
margin-bottom: 0.25rem;
|
|
174
178
|
}
|
|
175
179
|
.suite-info:hover {
|
|
176
|
-
|
|
180
|
+
border-color: var(--border);
|
|
177
181
|
cursor: pointer;
|
|
178
182
|
}
|
|
179
183
|
.suite-info .suite-path {
|
|
@@ -183,29 +187,29 @@ header {
|
|
|
183
187
|
font-size: 1rem;
|
|
184
188
|
}
|
|
185
189
|
.suite-info .suite-time {
|
|
186
|
-
margin-left:
|
|
190
|
+
margin-left: 1rem;
|
|
187
191
|
padding: 0.2rem 0.3rem;
|
|
188
|
-
font-size: 0.
|
|
192
|
+
font-size: 0.85rem;
|
|
189
193
|
}
|
|
190
194
|
.suite-info .suite-time.warn {
|
|
191
|
-
background-color:
|
|
195
|
+
background-color: var(--danger);
|
|
192
196
|
color: #fff;
|
|
193
197
|
}
|
|
194
198
|
.suite-info:before {
|
|
195
199
|
content: "\2303";
|
|
196
200
|
display: inline-block;
|
|
197
|
-
margin-right:
|
|
198
|
-
transform: rotate(
|
|
201
|
+
margin-right: 1rem;
|
|
202
|
+
transform: rotate(180deg) translateY(0.15rem);
|
|
199
203
|
}
|
|
200
|
-
.suite-container
|
|
201
|
-
transform: rotate(
|
|
204
|
+
.suite-container[open] .suite-info:before {
|
|
205
|
+
transform: rotate(0deg) translateY(0.15rem);
|
|
202
206
|
}
|
|
203
207
|
|
|
204
208
|
/* CONSOLE LOGS */
|
|
205
209
|
.suite-consolelog {
|
|
206
210
|
margin-bottom: 0.25rem;
|
|
207
211
|
padding: 1rem;
|
|
208
|
-
background-color:
|
|
212
|
+
background-color: var(--panel);
|
|
209
213
|
}
|
|
210
214
|
.suite-consolelog-header {
|
|
211
215
|
font-weight: bold;
|
|
@@ -222,11 +226,11 @@ header {
|
|
|
222
226
|
word-wrap: break-word;
|
|
223
227
|
}
|
|
224
228
|
.suite-consolelog-item-origin {
|
|
225
|
-
color:
|
|
229
|
+
color: var(--text-secondary);
|
|
226
230
|
font-weight: bold;
|
|
227
231
|
}
|
|
228
232
|
.suite-consolelog-item-message {
|
|
229
|
-
color:
|
|
233
|
+
color: var(--text-primary);
|
|
230
234
|
font-size: 1rem;
|
|
231
235
|
padding: 0 0.5rem;
|
|
232
236
|
}
|
|
@@ -235,8 +239,8 @@ header {
|
|
|
235
239
|
.suite-obsolete-snapshots {
|
|
236
240
|
margin-bottom: 0.25rem;
|
|
237
241
|
padding: 1rem;
|
|
238
|
-
background-color:
|
|
239
|
-
color:
|
|
242
|
+
background-color: var(--danger-bright);
|
|
243
|
+
color: var(--danger);
|
|
240
244
|
}
|
|
241
245
|
.suite-obsolete-snapshots-header {
|
|
242
246
|
font-weight: bold;
|
|
@@ -253,7 +257,7 @@ header {
|
|
|
253
257
|
word-wrap: break-word;
|
|
254
258
|
}
|
|
255
259
|
.suite-obsolete-snapshots-item-message {
|
|
256
|
-
color:
|
|
260
|
+
color: var(--text-primary);
|
|
257
261
|
font-size: 1rem;
|
|
258
262
|
padding: 0 0.5rem;
|
|
259
263
|
}
|