jest-html-reporter 2.8.1 → 2.8.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/dist/htmlreporter.js +373 -0
- package/dist/htmlreporter.js.map +1 -0
- package/dist/index.js +602 -0
- package/dist/index.js.map +1 -0
- package/dist/main.js +1 -11
- package/dist/main.min.js +1 -1
- package/dist/sortingMethods.js +57 -0
- package/dist/sortingMethods.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const dateformat_1 = __importDefault(require("dateformat"));
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const mkdirp_1 = __importDefault(require("mkdirp"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const strip_ansi_1 = __importDefault(require("strip-ansi"));
|
|
11
|
+
const xmlbuilder_1 = __importDefault(require("xmlbuilder"));
|
|
12
|
+
const sortingMethods_1 = require("./sortingMethods");
|
|
13
|
+
class HTMLReporter {
|
|
14
|
+
constructor(testData, options) {
|
|
15
|
+
this.testData = testData;
|
|
16
|
+
this.setupConfig(options);
|
|
17
|
+
}
|
|
18
|
+
async generate() {
|
|
19
|
+
const report = await this.renderTestReport();
|
|
20
|
+
const outputPath = this.getConfigValue("outputPath");
|
|
21
|
+
await mkdirp_1.default(path_1.default.dirname(outputPath));
|
|
22
|
+
await fs_1.default.writeFile(outputPath, report, writeFileError => {
|
|
23
|
+
if (writeFileError) {
|
|
24
|
+
throw new Error(`Something went wrong when creating the file: ${writeFileError}`);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
this.logMessage("success", `Report generated (${outputPath})`);
|
|
28
|
+
}
|
|
29
|
+
async renderTestReport() {
|
|
30
|
+
try {
|
|
31
|
+
// Generate the content of the test report
|
|
32
|
+
const reportBody = await this.renderTestReportBody();
|
|
33
|
+
// --
|
|
34
|
+
// Boilerplate Option
|
|
35
|
+
if (!!this.getConfigValue("boilerplate")) {
|
|
36
|
+
const boilerplateContent = await this.getFileContent(this.getConfigValue("boilerplate"));
|
|
37
|
+
return boilerplateContent.replace("{jesthtmlreporter-content}", reportBody.toString());
|
|
38
|
+
}
|
|
39
|
+
// --
|
|
40
|
+
// Create HTML and apply reporter content
|
|
41
|
+
const HTMLBase = {
|
|
42
|
+
html: {
|
|
43
|
+
head: {
|
|
44
|
+
meta: { "@charset": "utf-8" },
|
|
45
|
+
title: { "#text": this.getConfigValue("pageTitle") },
|
|
46
|
+
style: undefined,
|
|
47
|
+
link: undefined
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
// Default to the currently set theme
|
|
52
|
+
let stylesheetFilePath = path_1.default.join(__dirname, `../style/${this.getConfigValue("theme")}.css`);
|
|
53
|
+
// Overriding stylesheet
|
|
54
|
+
if (this.getConfigValue("styleOverridePath")) {
|
|
55
|
+
stylesheetFilePath = this.getConfigValue("styleOverridePath");
|
|
56
|
+
}
|
|
57
|
+
// Decide whether to inline the CSS or not
|
|
58
|
+
const inlineCSS = !this.getConfigValue("useCssFile") &&
|
|
59
|
+
!!!this.getConfigValue("styleOverridePath");
|
|
60
|
+
if (inlineCSS) {
|
|
61
|
+
const stylesheetContent = await fs_1.default.readFileSync(stylesheetFilePath, "utf8");
|
|
62
|
+
HTMLBase.html.head.style = {
|
|
63
|
+
"@type": "text/css",
|
|
64
|
+
"#text": stylesheetContent
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
HTMLBase.html.head.link = {
|
|
69
|
+
"@rel": "stylesheet",
|
|
70
|
+
"@type": "text/css",
|
|
71
|
+
"@href": stylesheetFilePath
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const report = xmlbuilder_1.default.create(HTMLBase);
|
|
75
|
+
report.ele("body").raw(reportBody.toString());
|
|
76
|
+
return report;
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
this.logMessage("error", e);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async renderTestReportBody() {
|
|
84
|
+
try {
|
|
85
|
+
if (!this.testData) {
|
|
86
|
+
throw Error("No test data provided");
|
|
87
|
+
}
|
|
88
|
+
// HTML Body
|
|
89
|
+
const reportBody = xmlbuilder_1.default.begin().element("div", {
|
|
90
|
+
id: "jesthtml-content"
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* Page Header
|
|
94
|
+
*/
|
|
95
|
+
const header = reportBody.ele("header");
|
|
96
|
+
// Page Title
|
|
97
|
+
header.ele("h1", { id: "title" }, this.getConfigValue("pageTitle"));
|
|
98
|
+
// Logo
|
|
99
|
+
const logo = this.getConfigValue("logo");
|
|
100
|
+
if (logo) {
|
|
101
|
+
header.ele("img", { id: "logo", src: logo });
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Meta-Data
|
|
105
|
+
*/
|
|
106
|
+
const metaDataContainer = reportBody.ele("div", {
|
|
107
|
+
id: "metadata-container"
|
|
108
|
+
});
|
|
109
|
+
// Timestamp
|
|
110
|
+
const timestamp = new Date(this.testData.startTime);
|
|
111
|
+
metaDataContainer.ele("div", { id: "timestamp" }, `Start: ${dateformat_1.default(timestamp.toDateString(), this.getConfigValue("dateFormat"))}`);
|
|
112
|
+
// Test Summary
|
|
113
|
+
metaDataContainer.ele("div", { id: "summary" }, `${this.testData.numTotalTests} tests -- ${this.testData.numPassedTests} passed / ${this.testData.numFailedTests} failed / ${this.testData.numPendingTests} pending`);
|
|
114
|
+
/**
|
|
115
|
+
* Apply any given sorting method to the test results
|
|
116
|
+
*/
|
|
117
|
+
const sortedTestResults = sortingMethods_1.sortTestResults(this.testData.testResults, this.getConfigValue("sort"));
|
|
118
|
+
/**
|
|
119
|
+
* Setup ignored test result statuses
|
|
120
|
+
*/
|
|
121
|
+
const statusIgnoreFilter = this.getConfigValue("statusIgnoreFilter");
|
|
122
|
+
let ignoredStatuses = [];
|
|
123
|
+
if (statusIgnoreFilter) {
|
|
124
|
+
ignoredStatuses = statusIgnoreFilter
|
|
125
|
+
.replace(/\s/g, "")
|
|
126
|
+
.toLowerCase()
|
|
127
|
+
.split(",");
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Test Suites
|
|
131
|
+
*/
|
|
132
|
+
sortedTestResults.map(suite => {
|
|
133
|
+
// Filter out the test results with statuses that equals the statusIgnoreFilter
|
|
134
|
+
for (const [i, result] of suite.testResults.entries()) {
|
|
135
|
+
if (ignoredStatuses.includes(result.status)) {
|
|
136
|
+
suite.testResults.splice(i, 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Ignore this suite if there are no results
|
|
140
|
+
if (!suite.testResults || suite.testResults.length <= 0) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Suite Information
|
|
144
|
+
const suiteInfo = reportBody.ele("div", { class: "suite-info" });
|
|
145
|
+
// Suite Path
|
|
146
|
+
suiteInfo.ele("div", { class: "suite-path" }, suite.testFilePath);
|
|
147
|
+
// Suite execution time
|
|
148
|
+
const executionTime = (suite.perfStats.end - suite.perfStats.start) / 1000;
|
|
149
|
+
suiteInfo.ele("div", { class: `suite-time${executionTime > 5 ? " warn" : ""}` }, `${executionTime}s`);
|
|
150
|
+
// Suite Test Table
|
|
151
|
+
const suiteTable = reportBody.ele("table", {
|
|
152
|
+
class: "suite-table",
|
|
153
|
+
cellspacing: "0",
|
|
154
|
+
cellpadding: "0"
|
|
155
|
+
});
|
|
156
|
+
// Test Results
|
|
157
|
+
suite.testResults.forEach(test => {
|
|
158
|
+
const testTr = suiteTable.ele("tr", { class: test.status });
|
|
159
|
+
// Suite Name(s)
|
|
160
|
+
testTr.ele("td", { class: "suite" }, test.ancestorTitles.join(" > "));
|
|
161
|
+
// Test name
|
|
162
|
+
const testTitleTd = testTr.ele("td", { class: "test" }, test.title);
|
|
163
|
+
// Test Failure Messages
|
|
164
|
+
if (test.failureMessages &&
|
|
165
|
+
this.getConfigValue("includeFailureMsg")) {
|
|
166
|
+
const failureMsgDiv = testTitleTd.ele("div", {
|
|
167
|
+
class: "failureMessages"
|
|
168
|
+
});
|
|
169
|
+
test.failureMessages.forEach(failureMsg => {
|
|
170
|
+
failureMsgDiv.ele("pre", { class: "failureMsg" }, strip_ansi_1.default(failureMsg));
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Append data to <tr>
|
|
174
|
+
testTr.ele("td", { class: "result" }, test.status === "passed"
|
|
175
|
+
? `${test.status} in ${test.duration / 1000}s`
|
|
176
|
+
: test.status);
|
|
177
|
+
});
|
|
178
|
+
// All console.logs caught during the test run
|
|
179
|
+
if (this.consoleLogList &&
|
|
180
|
+
this.consoleLogList.length > 0 &&
|
|
181
|
+
this.getConfigValue("includeConsoleLog")) {
|
|
182
|
+
// Filter out the logs for this test file path
|
|
183
|
+
const filteredConsoleLogs = this.consoleLogList.find(logs => logs.filePath === suite.testFilePath);
|
|
184
|
+
if (filteredConsoleLogs && filteredConsoleLogs.logs.length > 0) {
|
|
185
|
+
// Console Log Container
|
|
186
|
+
const consoleLogContainer = reportBody.ele("div", {
|
|
187
|
+
class: "suite-consolelog"
|
|
188
|
+
});
|
|
189
|
+
// Console Log Header
|
|
190
|
+
consoleLogContainer.ele("div", { class: "suite-consolelog-header" }, "Console Log");
|
|
191
|
+
// Apply the logs to the body
|
|
192
|
+
filteredConsoleLogs.logs.forEach(log => {
|
|
193
|
+
const logElement = consoleLogContainer.ele("div", {
|
|
194
|
+
class: "suite-consolelog-item"
|
|
195
|
+
});
|
|
196
|
+
logElement.ele("pre", { class: "suite-consolelog-item-origin" }, strip_ansi_1.default(log.origin));
|
|
197
|
+
logElement.ele("pre", { class: "suite-consolelog-item-message" }, strip_ansi_1.default(log.message));
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
return reportBody;
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
this.logMessage("error", e);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Fetch and setup configuration
|
|
210
|
+
*/
|
|
211
|
+
setupConfig(options) {
|
|
212
|
+
this.config = {
|
|
213
|
+
append: {
|
|
214
|
+
defaultValue: false,
|
|
215
|
+
environmentVariable: "JEST_HTML_REPORTER_APPEND",
|
|
216
|
+
configValue: options.append
|
|
217
|
+
},
|
|
218
|
+
boilerplate: {
|
|
219
|
+
defaultValue: null,
|
|
220
|
+
environmentVariable: "JEST_HTML_REPORTER_BOILERPLATE",
|
|
221
|
+
configValue: options.boilerplate
|
|
222
|
+
},
|
|
223
|
+
customScriptPath: {
|
|
224
|
+
defaultValue: null,
|
|
225
|
+
environmentVariable: "JEST_HTML_REPORTER_CUSTOM_SCRIPT_PATH",
|
|
226
|
+
configValue: options.customScriptPath
|
|
227
|
+
},
|
|
228
|
+
dateFormat: {
|
|
229
|
+
defaultValue: "yyyy-mm-dd HH:MM:ss",
|
|
230
|
+
environmentVariable: "JEST_HTML_REPORTER_DATE_FORMAT",
|
|
231
|
+
configValue: options.dateFormat
|
|
232
|
+
},
|
|
233
|
+
executionTimeWarningThreshold: {
|
|
234
|
+
defaultValue: 5,
|
|
235
|
+
environmentVariable: "JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD",
|
|
236
|
+
configValue: options.executionTimeWarningThreshold
|
|
237
|
+
},
|
|
238
|
+
logo: {
|
|
239
|
+
defaultValue: null,
|
|
240
|
+
environmentVariable: "JEST_HTML_REPORTER_LOGO",
|
|
241
|
+
configValue: options.logo
|
|
242
|
+
},
|
|
243
|
+
includeFailureMsg: {
|
|
244
|
+
defaultValue: false,
|
|
245
|
+
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_FAILURE_MSG",
|
|
246
|
+
configValue: options.includeFailureMsg
|
|
247
|
+
},
|
|
248
|
+
includeConsoleLog: {
|
|
249
|
+
defaultValue: false,
|
|
250
|
+
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_CONSOLE_LOG",
|
|
251
|
+
configValue: options.includeConsoleLog
|
|
252
|
+
},
|
|
253
|
+
outputPath: {
|
|
254
|
+
defaultValue: path_1.default.join(process.cwd(), "test-report.html"),
|
|
255
|
+
environmentVariable: "JEST_HTML_REPORTER_OUTPUT_PATH",
|
|
256
|
+
configValue: options.outputPath
|
|
257
|
+
},
|
|
258
|
+
pageTitle: {
|
|
259
|
+
defaultValue: "Test Report",
|
|
260
|
+
environmentVariable: "JEST_HTML_REPORTER_PAGE_TITLE",
|
|
261
|
+
configValue: options.pageTitle
|
|
262
|
+
},
|
|
263
|
+
theme: {
|
|
264
|
+
defaultValue: "defaultTheme",
|
|
265
|
+
environmentVariable: "JEST_HTML_REPORTER_THEME",
|
|
266
|
+
configValue: options.theme
|
|
267
|
+
},
|
|
268
|
+
sort: {
|
|
269
|
+
defaultValue: null,
|
|
270
|
+
environmentVariable: "JEST_HTML_REPORTER_SORT",
|
|
271
|
+
configValue: options.sort
|
|
272
|
+
},
|
|
273
|
+
statusIgnoreFilter: {
|
|
274
|
+
defaultValue: null,
|
|
275
|
+
environmentVariable: "JEST_HTML_REPORTER_STATUS_FILTER",
|
|
276
|
+
configValue: options.statusIgnoreFilter
|
|
277
|
+
},
|
|
278
|
+
styleOverridePath: {
|
|
279
|
+
defaultValue: null,
|
|
280
|
+
environmentVariable: "JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH",
|
|
281
|
+
configValue: options.styleOverridePath
|
|
282
|
+
},
|
|
283
|
+
useCssFile: {
|
|
284
|
+
defaultValue: false,
|
|
285
|
+
environmentVariable: "JEST_HTML_REPORTER_USE_CSS_FILE",
|
|
286
|
+
configValue: options.useCssFile
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
// Attempt to collect and assign config settings from jesthtmlreporter.config.json
|
|
290
|
+
try {
|
|
291
|
+
const jesthtmlreporterconfig = fs_1.default.readFileSync(path_1.default.join(process.cwd(), "jesthtmlreporter.config.json"), "utf8");
|
|
292
|
+
if (jesthtmlreporterconfig) {
|
|
293
|
+
const parsedConfig = JSON.parse(jesthtmlreporterconfig);
|
|
294
|
+
for (const key of Object.keys(parsedConfig)) {
|
|
295
|
+
if (this.config[key]) {
|
|
296
|
+
this.config[key].configValue =
|
|
297
|
+
parsedConfig[key];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch (e) {
|
|
304
|
+
/** do nothing */
|
|
305
|
+
}
|
|
306
|
+
// If above method did not work we attempt to check package.json
|
|
307
|
+
try {
|
|
308
|
+
const packageJson = fs_1.default.readFileSync(path_1.default.join(process.cwd(), "package.json"), "utf8");
|
|
309
|
+
if (packageJson) {
|
|
310
|
+
const parsedConfig = JSON.parse(packageJson)["jest-html-reporter"];
|
|
311
|
+
for (const key of Object.keys(parsedConfig)) {
|
|
312
|
+
if (this.config[key]) {
|
|
313
|
+
this.config[key].configValue =
|
|
314
|
+
parsedConfig[key];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
/** do nothing */
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Returns the configurated value from the config in the following priority order:
|
|
325
|
+
* Environment Variable > JSON configured value > Default value
|
|
326
|
+
* @param key
|
|
327
|
+
*/
|
|
328
|
+
getConfigValue(key) {
|
|
329
|
+
const option = this.config[key];
|
|
330
|
+
if (!option) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (process.env[option.environmentVariable]) {
|
|
334
|
+
return process.env[option.environmentVariable];
|
|
335
|
+
}
|
|
336
|
+
return option.configValue || option.defaultValue;
|
|
337
|
+
}
|
|
338
|
+
async getFileContent(filePath) {
|
|
339
|
+
try {
|
|
340
|
+
fs_1.default.readFile(filePath, "utf8", (err, content) => {
|
|
341
|
+
if (err) {
|
|
342
|
+
throw Error(`Could not locate file: '${filePath}': ${err}`);
|
|
343
|
+
}
|
|
344
|
+
return content;
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
catch (e) {
|
|
348
|
+
this.logMessage("error", e);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Method for logging to the terminal
|
|
354
|
+
* @param type
|
|
355
|
+
* @param message
|
|
356
|
+
* @param ignoreConsole
|
|
357
|
+
*/
|
|
358
|
+
logMessage(type = "default", message, ignoreConsole) {
|
|
359
|
+
const logTypes = {
|
|
360
|
+
default: "\x1b[37m%s\x1b[0m",
|
|
361
|
+
success: "\x1b[32m%s\x1b[0m",
|
|
362
|
+
error: "\x1b[31m%s\x1b[0m"
|
|
363
|
+
};
|
|
364
|
+
const logColor = !logTypes[type] ? logTypes.default : logTypes[type];
|
|
365
|
+
const logMsg = `jest-html-reporter >> ${message}`;
|
|
366
|
+
if (!ignoreConsole) {
|
|
367
|
+
console.log(logColor, logMsg);
|
|
368
|
+
}
|
|
369
|
+
return { logColor, logMsg }; // Return for testing purposes
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
exports.default = HTMLReporter;
|
|
373
|
+
//# sourceMappingURL=htmlreporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"htmlreporter.js","sourceRoot":"","sources":["../src/htmlreporter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
4
|
+
|
|
5
|
+
var dateformat = _interopDefault(require('dateformat'));
|
|
6
|
+
var fs = _interopDefault(require('fs'));
|
|
7
|
+
var mkdirp = _interopDefault(require('mkdirp'));
|
|
8
|
+
var path = _interopDefault(require('path'));
|
|
9
|
+
var stripAnsi = _interopDefault(require('strip-ansi'));
|
|
10
|
+
var xmlbuilder = _interopDefault(require('xmlbuilder'));
|
|
11
|
+
|
|
12
|
+
var sorting = ((testResults, sortType) => {
|
|
13
|
+
const sortTypeLowercase = sortType && sortType.toLowerCase();
|
|
14
|
+
|
|
15
|
+
switch (sortTypeLowercase) {
|
|
16
|
+
case "status":
|
|
17
|
+
return sortByStatus(testResults);
|
|
18
|
+
|
|
19
|
+
case "executiondesc":
|
|
20
|
+
return sortByExecutionDesc(testResults);
|
|
21
|
+
|
|
22
|
+
case "executionasc":
|
|
23
|
+
return sortByExecutionAsc(testResults);
|
|
24
|
+
|
|
25
|
+
case "titledesc":
|
|
26
|
+
return sortByTitleDesc(testResults);
|
|
27
|
+
|
|
28
|
+
case "titleasc":
|
|
29
|
+
return sortByTitleAsc(testResults);
|
|
30
|
+
|
|
31
|
+
default:
|
|
32
|
+
return testResults;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Splits test suites apart based on individual test status and sorts by that status:
|
|
37
|
+
* 1. Pending
|
|
38
|
+
* 2. Failed
|
|
39
|
+
* 3. Passed
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
const sortByStatus = testResults => {
|
|
43
|
+
const pendingSuites = [];
|
|
44
|
+
const failingSuites = [];
|
|
45
|
+
const passingSuites = [];
|
|
46
|
+
testResults.forEach(result => {
|
|
47
|
+
const pending = [];
|
|
48
|
+
const failed = [];
|
|
49
|
+
const passed = [];
|
|
50
|
+
result.testResults.forEach(x => {
|
|
51
|
+
if (x.status === "pending") {
|
|
52
|
+
pending.push(x);
|
|
53
|
+
} else if (x.status === "failed") {
|
|
54
|
+
failed.push(x);
|
|
55
|
+
} else {
|
|
56
|
+
passed.push(x);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (pending.length > 0) {
|
|
61
|
+
pendingSuites.push({ ...result,
|
|
62
|
+
testResults: pending
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (failed.length > 0) {
|
|
67
|
+
failingSuites.push({ ...result,
|
|
68
|
+
testResults: failed
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (passed.length > 0) {
|
|
73
|
+
passingSuites.push({ ...result,
|
|
74
|
+
testResults: passed
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return [].concat(pendingSuites, failingSuites, passingSuites);
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Sorts by Execution Time | Descending
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
const sortByExecutionDesc = testResults => {
|
|
86
|
+
if (testResults) {
|
|
87
|
+
testResults.sort((a, b) => b.perfStats.end - b.perfStats.start - (a.perfStats.end - a.perfStats.start));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return testResults;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Sorts by Execution Time | Ascending
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
const sortByExecutionAsc = testResults => {
|
|
98
|
+
if (testResults) {
|
|
99
|
+
testResults.sort((a, b) => a.perfStats.end - a.perfStats.start - (b.perfStats.end - b.perfStats.start));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return testResults;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Sorts by Suite filename and Test name | Descending
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
const sortByTitleDesc = testResults => {
|
|
110
|
+
if (testResults) {
|
|
111
|
+
// Sort Suites
|
|
112
|
+
const sorted = testResults.sort((a, b) => sortAlphabetically(a.testFilePath, b.testFilePath, true)); // Sort Suite testResults
|
|
113
|
+
|
|
114
|
+
sorted.forEach(suite => {
|
|
115
|
+
suite.testResults.sort((a, b) => sortAlphabetically(a.ancestorTitles.join(" "), b.ancestorTitles.join(" "), true));
|
|
116
|
+
});
|
|
117
|
+
return sorted;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return testResults;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Sorts by Suite filename and Test name | Ascending
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
const sortByTitleAsc = testResults => {
|
|
128
|
+
if (testResults) {
|
|
129
|
+
// Sort Suites
|
|
130
|
+
const sorted = testResults.sort((a, b) => sortAlphabetically(a.testFilePath, b.testFilePath)); // Sort Suite testResults
|
|
131
|
+
|
|
132
|
+
sorted.forEach(suite => {
|
|
133
|
+
suite.testResults.sort((a, b) => sortAlphabetically(a.ancestorTitles.join(" "), b.ancestorTitles.join(" ")));
|
|
134
|
+
});
|
|
135
|
+
return sorted;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return testResults;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Helper sorting method
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
const sortAlphabetically = (a, b, reversed = false) => {
|
|
146
|
+
if (!reversed && a < b || reversed && a > b) {
|
|
147
|
+
return -1;
|
|
148
|
+
} else if (!reversed && a > b || reversed && a < b) {
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return 0;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
class HTMLReporter {
|
|
156
|
+
constructor(testData, options, consoleLogs) {
|
|
157
|
+
this.testData = testData;
|
|
158
|
+
this.consoleLogList = consoleLogs;
|
|
159
|
+
this.setupConfig(options);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async generate() {
|
|
163
|
+
try {
|
|
164
|
+
const report = await this.renderTestReport();
|
|
165
|
+
const outputPath = this.getConfigValue("outputPath");
|
|
166
|
+
await mkdirp(path.dirname(outputPath));
|
|
167
|
+
|
|
168
|
+
if (this.getConfigValue("append")) {
|
|
169
|
+
await fs.appendFileSync(outputPath, report);
|
|
170
|
+
} else {
|
|
171
|
+
await fs.writeFileSync(outputPath, report);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
this.logMessage("success", `Report generated (${outputPath})`);
|
|
175
|
+
return report;
|
|
176
|
+
} catch (e) {
|
|
177
|
+
this.logMessage("error", e);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async renderTestReport() {
|
|
182
|
+
// Generate the content of the test report
|
|
183
|
+
const reportBody = await this.renderTestReportBody(); // --
|
|
184
|
+
// Boilerplate Option
|
|
185
|
+
|
|
186
|
+
if (!!this.getConfigValue("boilerplate")) {
|
|
187
|
+
const boilerplateContent = await fs.readFileSync(this.getConfigValue("boilerplate"), "utf8");
|
|
188
|
+
return boilerplateContent.replace("{jesthtmlreporter-content}", reportBody.toString());
|
|
189
|
+
} // --
|
|
190
|
+
// Create HTML and apply reporter content
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
const HTMLBase = {
|
|
194
|
+
html: {
|
|
195
|
+
head: {
|
|
196
|
+
meta: {
|
|
197
|
+
"@charset": "utf-8"
|
|
198
|
+
},
|
|
199
|
+
title: {
|
|
200
|
+
"#text": this.getConfigValue("pageTitle")
|
|
201
|
+
},
|
|
202
|
+
style: undefined,
|
|
203
|
+
link: undefined
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}; // Default to the currently set theme
|
|
207
|
+
|
|
208
|
+
let stylesheetFilePath = path.join(__dirname, `../style/${this.getConfigValue("theme")}.css`); // Overriding stylesheet
|
|
209
|
+
|
|
210
|
+
if (this.getConfigValue("styleOverridePath")) {
|
|
211
|
+
stylesheetFilePath = this.getConfigValue("styleOverridePath");
|
|
212
|
+
} // Decide whether to inline the CSS or not
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
const inlineCSS = !this.getConfigValue("useCssFile") && !!!this.getConfigValue("styleOverridePath");
|
|
216
|
+
|
|
217
|
+
if (inlineCSS) {
|
|
218
|
+
const stylesheetContent = await fs.readFileSync(stylesheetFilePath, "utf8");
|
|
219
|
+
HTMLBase.html.head.style = {
|
|
220
|
+
"@type": "text/css",
|
|
221
|
+
"#text": stylesheetContent
|
|
222
|
+
};
|
|
223
|
+
} else {
|
|
224
|
+
HTMLBase.html.head.link = {
|
|
225
|
+
"@rel": "stylesheet",
|
|
226
|
+
"@type": "text/css",
|
|
227
|
+
"@href": stylesheetFilePath
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const report = xmlbuilder.create(HTMLBase);
|
|
232
|
+
report.ele("body").raw(reportBody.toString());
|
|
233
|
+
return report;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async renderTestReportBody() {
|
|
237
|
+
try {
|
|
238
|
+
if (!this.testData || Object.entries(this.testData).length === 0) {
|
|
239
|
+
throw Error("No test data provided");
|
|
240
|
+
} // HTML Body
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
const reportBody = xmlbuilder.begin().element("div", {
|
|
244
|
+
id: "jesthtml-content"
|
|
245
|
+
});
|
|
246
|
+
/**
|
|
247
|
+
* Page Header
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
const header = reportBody.ele("header"); // Page Title
|
|
251
|
+
|
|
252
|
+
header.ele("h1", {
|
|
253
|
+
id: "title"
|
|
254
|
+
}, this.getConfigValue("pageTitle")); // Logo
|
|
255
|
+
|
|
256
|
+
const logo = this.getConfigValue("logo");
|
|
257
|
+
|
|
258
|
+
if (logo) {
|
|
259
|
+
header.ele("img", {
|
|
260
|
+
id: "logo",
|
|
261
|
+
src: logo
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Meta-Data
|
|
266
|
+
*/
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
const metaDataContainer = reportBody.ele("div", {
|
|
270
|
+
id: "metadata-container"
|
|
271
|
+
}); // Timestamp
|
|
272
|
+
|
|
273
|
+
const timestamp = new Date(this.testData.startTime);
|
|
274
|
+
metaDataContainer.ele("div", {
|
|
275
|
+
id: "timestamp"
|
|
276
|
+
}, `Start: ${dateformat(timestamp.toDateString(), this.getConfigValue("dateFormat"))}`); // Test Summary
|
|
277
|
+
|
|
278
|
+
metaDataContainer.ele("div", {
|
|
279
|
+
id: "summary"
|
|
280
|
+
}, `${this.testData.numTotalTests} tests -- ${this.testData.numPassedTests} passed / ${this.testData.numFailedTests} failed / ${this.testData.numPendingTests} pending`);
|
|
281
|
+
/**
|
|
282
|
+
* Apply any given sorting method to the test results
|
|
283
|
+
*/
|
|
284
|
+
|
|
285
|
+
const sortedTestResults = sorting(this.testData.testResults, this.getConfigValue("sort"));
|
|
286
|
+
/**
|
|
287
|
+
* Setup ignored test result statuses
|
|
288
|
+
*/
|
|
289
|
+
|
|
290
|
+
const statusIgnoreFilter = this.getConfigValue("statusIgnoreFilter");
|
|
291
|
+
let ignoredStatuses = [];
|
|
292
|
+
|
|
293
|
+
if (statusIgnoreFilter) {
|
|
294
|
+
ignoredStatuses = statusIgnoreFilter.replace(/\s/g, "").toLowerCase().split(",");
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Test Suites
|
|
298
|
+
*/
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
sortedTestResults.map(suite => {
|
|
302
|
+
// Ignore this suite if there are no results
|
|
303
|
+
if (!suite.testResults || suite.testResults.length <= 0) {
|
|
304
|
+
return;
|
|
305
|
+
} // Suite Information
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
const suiteInfo = reportBody.ele("div", {
|
|
309
|
+
class: "suite-info"
|
|
310
|
+
}); // Suite Path
|
|
311
|
+
|
|
312
|
+
suiteInfo.ele("div", {
|
|
313
|
+
class: "suite-path"
|
|
314
|
+
}, suite.testFilePath); // Suite execution time
|
|
315
|
+
|
|
316
|
+
const executionTime = (suite.perfStats.end - suite.perfStats.start) / 1000;
|
|
317
|
+
suiteInfo.ele("div", {
|
|
318
|
+
class: `suite-time${executionTime > 5 ? " warn" : ""}`
|
|
319
|
+
}, `${executionTime}s`); // Suite Test Table
|
|
320
|
+
|
|
321
|
+
const suiteTable = reportBody.ele("table", {
|
|
322
|
+
class: "suite-table",
|
|
323
|
+
cellspacing: "0",
|
|
324
|
+
cellpadding: "0"
|
|
325
|
+
}); // Test Results
|
|
326
|
+
|
|
327
|
+
suite.testResults // Filter out the test results with statuses that equals the statusIgnoreFilter
|
|
328
|
+
.filter(s => !ignoredStatuses.includes(s.status)).forEach(test => {
|
|
329
|
+
const testTr = suiteTable.ele("tr", {
|
|
330
|
+
class: test.status
|
|
331
|
+
}); // Suite Name(s)
|
|
332
|
+
|
|
333
|
+
testTr.ele("td", {
|
|
334
|
+
class: "suite"
|
|
335
|
+
}, test.ancestorTitles.join(" > ")); // Test name
|
|
336
|
+
|
|
337
|
+
const testTitleTd = testTr.ele("td", {
|
|
338
|
+
class: "test"
|
|
339
|
+
}, test.title); // Test Failure Messages
|
|
340
|
+
|
|
341
|
+
if (test.failureMessages && this.getConfigValue("includeFailureMsg")) {
|
|
342
|
+
const failureMsgDiv = testTitleTd.ele("div", {
|
|
343
|
+
class: "failureMessages"
|
|
344
|
+
});
|
|
345
|
+
test.failureMessages.forEach(failureMsg => {
|
|
346
|
+
failureMsgDiv.ele("pre", {
|
|
347
|
+
class: "failureMsg"
|
|
348
|
+
}, stripAnsi(failureMsg));
|
|
349
|
+
});
|
|
350
|
+
} // Append data to <tr>
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
testTr.ele("td", {
|
|
354
|
+
class: "result"
|
|
355
|
+
}, test.status === "passed" ? `${test.status} in ${test.duration / 1000}s` : test.status);
|
|
356
|
+
}); // All console.logs caught during the test run
|
|
357
|
+
|
|
358
|
+
if (this.consoleLogList && this.consoleLogList.length > 0 && this.getConfigValue("includeConsoleLog")) {
|
|
359
|
+
// Filter out the logs for this test file path
|
|
360
|
+
const filteredConsoleLogs = this.consoleLogList.find(logs => logs.filePath === suite.testFilePath);
|
|
361
|
+
|
|
362
|
+
if (filteredConsoleLogs && filteredConsoleLogs.logs.length > 0) {
|
|
363
|
+
// Console Log Container
|
|
364
|
+
const consoleLogContainer = reportBody.ele("div", {
|
|
365
|
+
class: "suite-consolelog"
|
|
366
|
+
}); // Console Log Header
|
|
367
|
+
|
|
368
|
+
consoleLogContainer.ele("div", {
|
|
369
|
+
class: "suite-consolelog-header"
|
|
370
|
+
}, "Console Log"); // Apply the logs to the body
|
|
371
|
+
|
|
372
|
+
filteredConsoleLogs.logs.forEach(log => {
|
|
373
|
+
const logElement = consoleLogContainer.ele("div", {
|
|
374
|
+
class: "suite-consolelog-item"
|
|
375
|
+
});
|
|
376
|
+
logElement.ele("pre", {
|
|
377
|
+
class: "suite-consolelog-item-origin"
|
|
378
|
+
}, stripAnsi(log.origin));
|
|
379
|
+
logElement.ele("pre", {
|
|
380
|
+
class: "suite-consolelog-item-message"
|
|
381
|
+
}, stripAnsi(log.message));
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
return reportBody;
|
|
387
|
+
} catch (e) {
|
|
388
|
+
this.logMessage("error", e);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Fetch and setup configuration
|
|
393
|
+
*/
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
setupConfig(options) {
|
|
397
|
+
this.config = {
|
|
398
|
+
append: {
|
|
399
|
+
defaultValue: false,
|
|
400
|
+
environmentVariable: "JEST_HTML_REPORTER_APPEND",
|
|
401
|
+
configValue: options.append
|
|
402
|
+
},
|
|
403
|
+
boilerplate: {
|
|
404
|
+
defaultValue: null,
|
|
405
|
+
environmentVariable: "JEST_HTML_REPORTER_BOILERPLATE",
|
|
406
|
+
configValue: options.boilerplate
|
|
407
|
+
},
|
|
408
|
+
customScriptPath: {
|
|
409
|
+
defaultValue: null,
|
|
410
|
+
environmentVariable: "JEST_HTML_REPORTER_CUSTOM_SCRIPT_PATH",
|
|
411
|
+
configValue: options.customScriptPath
|
|
412
|
+
},
|
|
413
|
+
dateFormat: {
|
|
414
|
+
defaultValue: "yyyy-mm-dd HH:MM:ss",
|
|
415
|
+
environmentVariable: "JEST_HTML_REPORTER_DATE_FORMAT",
|
|
416
|
+
configValue: options.dateFormat
|
|
417
|
+
},
|
|
418
|
+
executionTimeWarningThreshold: {
|
|
419
|
+
defaultValue: 5,
|
|
420
|
+
environmentVariable: "JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD",
|
|
421
|
+
configValue: options.executionTimeWarningThreshold
|
|
422
|
+
},
|
|
423
|
+
logo: {
|
|
424
|
+
defaultValue: null,
|
|
425
|
+
environmentVariable: "JEST_HTML_REPORTER_LOGO",
|
|
426
|
+
configValue: options.logo
|
|
427
|
+
},
|
|
428
|
+
includeFailureMsg: {
|
|
429
|
+
defaultValue: false,
|
|
430
|
+
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_FAILURE_MSG",
|
|
431
|
+
configValue: options.includeFailureMsg
|
|
432
|
+
},
|
|
433
|
+
includeConsoleLog: {
|
|
434
|
+
defaultValue: false,
|
|
435
|
+
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_CONSOLE_LOG",
|
|
436
|
+
configValue: options.includeConsoleLog
|
|
437
|
+
},
|
|
438
|
+
outputPath: {
|
|
439
|
+
defaultValue: path.join(process.cwd(), "test-report.html"),
|
|
440
|
+
environmentVariable: "JEST_HTML_REPORTER_OUTPUT_PATH",
|
|
441
|
+
configValue: options.outputPath
|
|
442
|
+
},
|
|
443
|
+
pageTitle: {
|
|
444
|
+
defaultValue: "Test Report",
|
|
445
|
+
environmentVariable: "JEST_HTML_REPORTER_PAGE_TITLE",
|
|
446
|
+
configValue: options.pageTitle
|
|
447
|
+
},
|
|
448
|
+
theme: {
|
|
449
|
+
defaultValue: "defaultTheme",
|
|
450
|
+
environmentVariable: "JEST_HTML_REPORTER_THEME",
|
|
451
|
+
configValue: options.theme
|
|
452
|
+
},
|
|
453
|
+
sort: {
|
|
454
|
+
defaultValue: null,
|
|
455
|
+
environmentVariable: "JEST_HTML_REPORTER_SORT",
|
|
456
|
+
configValue: options.sort
|
|
457
|
+
},
|
|
458
|
+
statusIgnoreFilter: {
|
|
459
|
+
defaultValue: null,
|
|
460
|
+
environmentVariable: "JEST_HTML_REPORTER_STATUS_FILTER",
|
|
461
|
+
configValue: options.statusIgnoreFilter
|
|
462
|
+
},
|
|
463
|
+
styleOverridePath: {
|
|
464
|
+
defaultValue: null,
|
|
465
|
+
environmentVariable: "JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH",
|
|
466
|
+
configValue: options.styleOverridePath
|
|
467
|
+
},
|
|
468
|
+
useCssFile: {
|
|
469
|
+
defaultValue: false,
|
|
470
|
+
environmentVariable: "JEST_HTML_REPORTER_USE_CSS_FILE",
|
|
471
|
+
configValue: options.useCssFile
|
|
472
|
+
}
|
|
473
|
+
}; // Attempt to collect and assign config settings from jesthtmlreporter.config.json
|
|
474
|
+
|
|
475
|
+
try {
|
|
476
|
+
const jesthtmlreporterconfig = fs.readFileSync(path.join(process.cwd(), "jesthtmlreporter.config.json"), "utf8");
|
|
477
|
+
|
|
478
|
+
if (jesthtmlreporterconfig) {
|
|
479
|
+
const parsedConfig = JSON.parse(jesthtmlreporterconfig);
|
|
480
|
+
|
|
481
|
+
for (const key of Object.keys(parsedConfig)) {
|
|
482
|
+
if (this.config[key]) {
|
|
483
|
+
this.config[key].configValue = parsedConfig[key];
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
} catch (e) {}
|
|
490
|
+
/** do nothing */
|
|
491
|
+
// If above method did not work we attempt to check package.json
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
try {
|
|
495
|
+
const packageJson = fs.readFileSync(path.join(process.cwd(), "package.json"), "utf8");
|
|
496
|
+
|
|
497
|
+
if (packageJson) {
|
|
498
|
+
const parsedConfig = JSON.parse(packageJson)["jest-html-reporter"];
|
|
499
|
+
|
|
500
|
+
for (const key of Object.keys(parsedConfig)) {
|
|
501
|
+
if (this.config[key]) {
|
|
502
|
+
this.config[key].configValue = parsedConfig[key];
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
} catch (e) {
|
|
507
|
+
/** do nothing */
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Returns the configurated value from the config in the following priority order:
|
|
512
|
+
* Environment Variable > JSON configured value > Default value
|
|
513
|
+
* @param key
|
|
514
|
+
*/
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
getConfigValue(key) {
|
|
518
|
+
const option = this.config[key];
|
|
519
|
+
|
|
520
|
+
if (!option) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (process.env[option.environmentVariable]) {
|
|
525
|
+
return process.env[option.environmentVariable];
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return option.configValue || option.defaultValue;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Method for logging to the terminal
|
|
532
|
+
* @param type
|
|
533
|
+
* @param message
|
|
534
|
+
* @param ignoreConsole
|
|
535
|
+
*/
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
logMessage(type = "default", message, ignoreConsole) {
|
|
539
|
+
const logTypes = {
|
|
540
|
+
default: "\x1b[37m%s\x1b[0m",
|
|
541
|
+
success: "\x1b[32m%s\x1b[0m",
|
|
542
|
+
error: "\x1b[31m%s\x1b[0m"
|
|
543
|
+
};
|
|
544
|
+
const logColor = !logTypes[type] ? logTypes.default : logTypes[type];
|
|
545
|
+
const logMsg = `jest-html-reporter >> ${message}`;
|
|
546
|
+
|
|
547
|
+
if (!ignoreConsole) {
|
|
548
|
+
console.log(logColor, logMsg);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return {
|
|
552
|
+
logColor,
|
|
553
|
+
logMsg
|
|
554
|
+
}; // Return for testing purposes
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function JestHtmlReporter(globalConfig, options) {
|
|
560
|
+
const consoleLogs = [];
|
|
561
|
+
/**
|
|
562
|
+
* If the first parameter has a property named 'testResults',
|
|
563
|
+
* the script is being run as a 'testResultsProcessor'.
|
|
564
|
+
* We then need to return the test results as they were received from Jest
|
|
565
|
+
* https://facebook.github.io/jest/docs/en/configuration.html#testresultsprocessor-string
|
|
566
|
+
*/
|
|
567
|
+
|
|
568
|
+
if (Object.prototype.hasOwnProperty.call(globalConfig, "testResults")) {
|
|
569
|
+
// @ts-ignore
|
|
570
|
+
setupAndRun(globalConfig.testResults, options); // Return the results as required by Jest
|
|
571
|
+
|
|
572
|
+
return globalConfig;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* The default behaviour - run as Custom Reporter, in parallel with Jest.
|
|
576
|
+
* https://facebook.github.io/jest/docs/en/configuration.html#reporters-array-modulename-modulename-options
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
this.onTestResult = (data, result) => {
|
|
581
|
+
// Catch console logs per test
|
|
582
|
+
if (result.console) {
|
|
583
|
+
consoleLogs.push({
|
|
584
|
+
filePath: result.testFilePath,
|
|
585
|
+
logs: result.console
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
this.onRunComplete = (contexts, testResult) => setupAndRun(testResult, options, consoleLogs);
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Setup Jest HTML Reporter and generate a report with the given data
|
|
594
|
+
*/
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
const setupAndRun = (testResults, options, logs) => {
|
|
598
|
+
const reporter = new HTMLReporter(testResults, options, logs);
|
|
599
|
+
return reporter.generate();
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
module.exports = JestHtmlReporter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAGA,kEAA0C;AAG1C,SAAS,gBAAgB,CACvB,YAAiC,EACjC,OAA8B;IAE9B,oDAAoD;IACpD,MAAM,WAAW,GAA+B,EAAE,CAAC;IAEnD;;;;;OAKG;IACH,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE;QACrE,kBAAkB;QAClB,MAAM,QAAQ,GAAG,IAAI,sBAAY;QAC/B,aAAa;QACb,YAAY,CAAC,WAAW,EACxB,OAAmC,CACpC,CAAC;QACF,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACpB,yCAAyC;QACzC,OAAO,YAAY,CAAC;KACrB;IAED;;;;OAIG;IACH,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC;IAC/B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;IAE3B,IAAI,CAAC,YAAY,GAAG,CAAC,IAAS,EAAE,MAAkB,EAAE,EAAE;QACpD,8BAA8B;QAC9B,IAAI,MAAM,CAAC,OAAO,EAAE;YAClB,WAAW,CAAC,IAAI,CAAC;gBACf,QAAQ,EAAE,MAAM,CAAC,YAAY;gBAC7B,IAAI,EAAE,MAAM,CAAC,OAAO;aACrB,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,IAAI,CAAC,aAAa,GAAG,CAAC,QAAa,EAAE,UAA4B,EAAE,EAAE;QACnE,MAAM,QAAQ,GAAG,IAAI,sBAAY,CAC/B,UAAU,EACV,OAAmC,CACpC,CAAC;QACF,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACpB,2CAA2C;IAC7C,CAAC,CAAC;AACJ,CAAC;AAED,kBAAe,gBAAgB,CAAC"}
|
package/dist/main.js
CHANGED
|
@@ -531,18 +531,8 @@ class ReportGenerator {
|
|
|
531
531
|
const consoleLogContainer = reportBody.ele('div', { class: 'suite-consolelog' });
|
|
532
532
|
// Console Log Header
|
|
533
533
|
consoleLogContainer.ele('div', { class: 'suite-consolelog-header' }, 'Console Log');
|
|
534
|
-
// Sort the order by the path
|
|
535
|
-
const sortedConsoleLogs = filteredConsoleLogs.logs.sort((a, b) => {
|
|
536
|
-
if (a.origin < b.origin) {
|
|
537
|
-
return -1;
|
|
538
|
-
}
|
|
539
|
-
if (a.origin > b.origin) {
|
|
540
|
-
return 1;
|
|
541
|
-
}
|
|
542
|
-
return 0;
|
|
543
|
-
});
|
|
544
534
|
// Apply the logs to the body
|
|
545
|
-
|
|
535
|
+
filteredConsoleLogs.logs.forEach((log) => {
|
|
546
536
|
const logElement = consoleLogContainer.ele('div', { class: 'suite-consolelog-item' });
|
|
547
537
|
logElement.ele('pre', { class: 'suite-consolelog-item-origin' }, stripAnsi(log.origin));
|
|
548
538
|
logElement.ele('pre', { class: 'suite-consolelog-item-message' }, stripAnsi(log.message));
|
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 o={default:"[37m%s[0m",success:"[32m%s[0m",error:"[31m%s[0m"},n=o[e]?o[e]:o.default,i=`jest-html-reporter >> ${t}`;return s||console.log(n,i),{logColor:n,logMsg:i}},writeFile:({filePath:e,content:t})=>new Promise((s,o)=>{mkdirp(path.dirname(e),n=>n?o(new Error(`Something went wrong when creating the folder: ${n}`)):fs.writeFile(e,t,t=>t?o(new Error(`Something went wrong when creating the file: ${t}`)):s(e)))}),appendFile:({filePath:e,content:t})=>new Promise((s,o)=>{mkdirp(path.dirname(e),n=>n?o(new Error(`Something went wrong when creating the folder: ${n}`)):fs.readFile(e,"utf8",(n,i)=>{let r=t;if(!n){const n=/<body>(.*?)<\/body>/gm.exec(t);if(n){const[e]=n;r=e}if(i){let t=i;const n=/<\/body>/gm.exec(i),l=n?n.index:0;return t=[i.slice(0,l),r,i.slice(l)].join(""),fs.writeFile(e,t,t=>t?o(new Error(`Something went wrong when creating the file: ${t}`)):s(e))}}return fs.appendFile(e,r,t=>t?o(new Error(`Something went wrong when appending the file: ${t}`)):s(e))}))}),getFileContent:({filePath:e})=>new Promise((t,s)=>{fs.readFile(e,"utf8",(o,n)=>o?s(new Error(`Could not locate file: '${e}': ${o}`)):t(n))}),createHtmlBase:({pageTitle:e,stylesheet:t,stylesheetPath:s})=>{const o={html:{head:{meta:{"@charset":"utf-8"},title:{"#text":e}}}};return s?o.html.head.link={"@rel":"stylesheet","@type":"text/css","@href":s}:o.html.head.style={"@type":"text/css","#text":t},xmlbuilder.create(o)},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.appendFile,utils_4=utils.getFileContent,utils_5=utils.createHtmlBase,utils_6=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 n=[],i=[],r=[];e.testResults.forEach(e=>{"pending"===e.status?n.push(e):"failed"===e.status?i.push(e):r.push(e)}),n.length&&t.push(Object.assign({},e,{testResults:n})),i.length&&s.push(Object.assign({},e,{testResults:i})),r.length&&o.push(Object.assign({},e,{testResults:r}))}),[].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,this.consoleLogs=null}generate({data:e,ignoreConsole:t}){const s=this.config.getOutputFilepath(),o=this.config.shouldUseCssFile(),n=this.config.shouldGetStylesheetContent(),i=this.config.getAppend();let r=null,l=null;return o&&(r=this.config.getStylesheetFilepath()),(l=n?()=>this.getStylesheetContent():()=>Promise.resolve())().then(t=>this.renderHtmlReport({data:e,stylesheet:t,stylesheetPath:r})).then(e=>i?utils.appendFile({filePath:s,content: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}))}integrateContentIntoBoilerplate({content:e}){const t=this.config.getBoilerplatePath();return new Promise((s,o)=>utils.getFileContent({filePath:t}).then(t=>s(t.replace("{jesthtmlreporter-content}",e))).catch(e=>o(e)))}getStylesheetContent(){const e=this.config.getStylesheetFilepath();return utils.getFileContent({filePath:e})}renderHtmlReport({data:e,stylesheet:t,stylesheetPath:s}){return new Promise((o,n)=>{if(!e)return n(new Error("Test data missing or malformed"));const i=this.config.getPageTitle(),r=this.getReportBody({data:e,pageTitle:i});if(this.config.getBoilerplatePath())return this.integrateContentIntoBoilerplate({content:r}).then(e=>o(e));const l=utils.createHtmlBase({pageTitle:i,stylesheet:t,stylesheetPath:s}),a=l.ele("body");a.raw(r);const c=this.config.getCustomScriptFilepath();return c&&a.raw(`<script src="${c}"><\/script>`),o(l)})}getReportBody({data:e,pageTitle:t}){const s=xmlbuilder.begin().element("div",{id:"jesthtml-content"}),o=s.ele("header");o.ele("h1",{id:"title"},t);const n=this.config.getLogo();n&&o.ele("img",{id:"logo",src:n});const i=s.ele("div",{id:"metadata-container"}),r=new Date(e.startTime);i.ele("div",{id:"timestamp"},`Start: ${dateformat(r,this.config.getDateFormat())}`),i.ele("div",{id:"summary"},`${e.numTotalTests} tests -- ${e.numPassedTests} passed / ${e.numFailedTests} failed / ${e.numPendingTests} pending`);const l=sorting.sortSuiteResults({testData:e.testResults,sortMethod:this.config.getSort()}),a=this.config.getStatusIgnoreFilter();let c=[];return a&&(c=a.replace(/\s/g,"").toLowerCase().split(",")),l.forEach(e=>{for(let t=e.testResults.length-1;t>=0;t-=1)c.includes(e.testResults[t].status)&&e.testResults.splice(t,1);if(!e.testResults||e.testResults.length<=0)return;const t=s.ele("div",{class:"suite-info"});t.ele("div",{class:"suite-path"},e.testFilePath);const o=(e.perfStats.end-e.perfStats.start)/1e3;t.ele("div",{class:`suite-time${o>5?" warn":""}`},`${o}s`);const n=s.ele("table",{class:"suite-table",cellspacing:"0",cellpadding:"0"});if(e.testResults.forEach(e=>{const t=n.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)}),this.consoleLogs&&this.consoleLogs.length>0&&this.config.shouldIncludeConsoleLog()){const t=this.consoleLogs.find(t=>t.testFilePath===e.testFilePath);if(t&&t.logs.length>0){const e=s.ele("div",{class:"suite-consolelog"});e.ele("div",{class:"suite-consolelog-header"},"Console Log"),t.logs.sort((e,t)=>e.origin<t.origin?-1:e.origin>t.origin?1:0).forEach(t=>{const s=e.ele("div",{class:"suite-consolelog-item"});s.ele("pre",{class:"suite-consolelog-item-origin"},stripAnsi(t.origin)),s.ele("pre",{class:"suite-consolelog-item-message"},stripAnsi(t.message))})}}}),s}}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",n=()=>Boolean(process.env.JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH)||Boolean(t.styleOverridePath),i=()=>process.env.JEST_HTML_REPORTER_USE_CSS_FILE||t.useCssFile||!1;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:()=>{return(process.env.JEST_HTML_REPORTER_OUTPUT_PATH||t.outputPath||path.join(process.cwd(),"test-report.html")).replace(/<rootdir>/gi,".")},getStylesheetFilepath:()=>process.env.JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH||t.styleOverridePath||path.join(__dirname,`../style/${o()}.css`),getHasStyleOverridePath:n,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,shouldUseCssFile:i,shouldGetStylesheetContent:()=>!(n()&&i()),getExecutionTimeWarningThreshold:()=>process.env.JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD||t.executionTimeWarningThreshold||5,getBoilerplatePath:()=>process.env.JEST_HTML_REPORTER_BOILERPLATE||t.boilerplate||null,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",getStatusIgnoreFilter:()=>process.env.JEST_HTML_REPORTER_STATUS_FILTER||t.statusIgnoreFilter||null,getAppend:()=>process.env.JEST_HTML_REPORTER_APPEND||t.append||!1}}),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.getHasStyleOverridePath,config_8=config_1.getCustomScriptFilepath,config_9=config_1.getPageTitle,config_10=config_1.getLogo,config_11=config_1.shouldIncludeFailureMessages,config_12=config_1.shouldIncludeConsoleLog,config_13=config_1.shouldUseCssFile,config_14=config_1.shouldGetStylesheetContent,config_15=config_1.getExecutionTimeWarningThreshold,config_16=config_1.getBoilerplatePath,config_17=config_1.getTheme,config_18=config_1.getDateFormat,config_19=config_1.getSort,config_20=config_1.getStatusIgnoreFilter,config_21=config_1.getAppend;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.consoleLogs=[],this.onTestResult=((e,t)=>{t.console&&this.consoleLogs.push({testFilePath:t.testFilePath,logs:t.console})}),this.onRunComplete=((e,t)=>(config_1.setConfigData(this.jestOptions),s.config=config_1,s.consoleLogs=this.consoleLogs,s.generate({data:t})))}var src=JestHtmlReporter;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:"[37m%s[0m",success:"[32m%s[0m",error:"[31m%s[0m"},n=o[e]?o[e]:o.default,i=`jest-html-reporter >> ${t}`;return s||console.log(n,i),{logColor:n,logMsg:i}},writeFile:({filePath:e,content:t})=>new Promise((s,o)=>{mkdirp(path.dirname(e),n=>n?o(new Error(`Something went wrong when creating the folder: ${n}`)):fs.writeFile(e,t,t=>t?o(new Error(`Something went wrong when creating the file: ${t}`)):s(e)))}),appendFile:({filePath:e,content:t})=>new Promise((s,o)=>{mkdirp(path.dirname(e),n=>n?o(new Error(`Something went wrong when creating the folder: ${n}`)):fs.readFile(e,"utf8",(n,i)=>{let r=t;if(!n){const n=/<body>(.*?)<\/body>/gm.exec(t);if(n){const[e]=n;r=e}if(i){let t=i;const n=/<\/body>/gm.exec(i),l=n?n.index:0;return t=[i.slice(0,l),r,i.slice(l)].join(""),fs.writeFile(e,t,t=>t?o(new Error(`Something went wrong when creating the file: ${t}`)):s(e))}}return fs.appendFile(e,r,t=>t?o(new Error(`Something went wrong when appending the file: ${t}`)):s(e))}))}),getFileContent:({filePath:e})=>new Promise((t,s)=>{fs.readFile(e,"utf8",(o,n)=>o?s(new Error(`Could not locate file: '${e}': ${o}`)):t(n))}),createHtmlBase:({pageTitle:e,stylesheet:t,stylesheetPath:s})=>{const o={html:{head:{meta:{"@charset":"utf-8"},title:{"#text":e}}}};return s?o.html.head.link={"@rel":"stylesheet","@type":"text/css","@href":s}:o.html.head.style={"@type":"text/css","#text":t},xmlbuilder.create(o)},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.appendFile,utils_4=utils.getFileContent,utils_5=utils.createHtmlBase,utils_6=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 n=[],i=[],r=[];e.testResults.forEach(e=>{"pending"===e.status?n.push(e):"failed"===e.status?i.push(e):r.push(e)}),n.length&&t.push(Object.assign({},e,{testResults:n})),i.length&&s.push(Object.assign({},e,{testResults:i})),r.length&&o.push(Object.assign({},e,{testResults:r}))}),[].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,this.consoleLogs=null}generate({data:e,ignoreConsole:t}){const s=this.config.getOutputFilepath(),o=this.config.shouldUseCssFile(),n=this.config.shouldGetStylesheetContent(),i=this.config.getAppend();let r=null,l=null;return o&&(r=this.config.getStylesheetFilepath()),(l=n?()=>this.getStylesheetContent():()=>Promise.resolve())().then(t=>this.renderHtmlReport({data:e,stylesheet:t,stylesheetPath:r})).then(e=>i?utils.appendFile({filePath:s,content: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}))}integrateContentIntoBoilerplate({content:e}){const t=this.config.getBoilerplatePath();return new Promise((s,o)=>utils.getFileContent({filePath:t}).then(t=>s(t.replace("{jesthtmlreporter-content}",e))).catch(e=>o(e)))}getStylesheetContent(){const e=this.config.getStylesheetFilepath();return utils.getFileContent({filePath:e})}renderHtmlReport({data:e,stylesheet:t,stylesheetPath:s}){return new Promise((o,n)=>{if(!e)return n(new Error("Test data missing or malformed"));const i=this.config.getPageTitle(),r=this.getReportBody({data:e,pageTitle:i});if(this.config.getBoilerplatePath())return this.integrateContentIntoBoilerplate({content:r}).then(e=>o(e));const l=utils.createHtmlBase({pageTitle:i,stylesheet:t,stylesheetPath:s}),a=l.ele("body");a.raw(r);const c=this.config.getCustomScriptFilepath();return c&&a.raw(`<script src="${c}"><\/script>`),o(l)})}getReportBody({data:e,pageTitle:t}){const s=xmlbuilder.begin().element("div",{id:"jesthtml-content"}),o=s.ele("header");o.ele("h1",{id:"title"},t);const n=this.config.getLogo();n&&o.ele("img",{id:"logo",src:n});const i=s.ele("div",{id:"metadata-container"}),r=new Date(e.startTime);i.ele("div",{id:"timestamp"},`Start: ${dateformat(r,this.config.getDateFormat())}`),i.ele("div",{id:"summary"},`${e.numTotalTests} tests -- ${e.numPassedTests} passed / ${e.numFailedTests} failed / ${e.numPendingTests} pending`);const l=sorting.sortSuiteResults({testData:e.testResults,sortMethod:this.config.getSort()}),a=this.config.getStatusIgnoreFilter();let c=[];return a&&(c=a.replace(/\s/g,"").toLowerCase().split(",")),l.forEach(e=>{for(let t=e.testResults.length-1;t>=0;t-=1)c.includes(e.testResults[t].status)&&e.testResults.splice(t,1);if(!e.testResults||e.testResults.length<=0)return;const t=s.ele("div",{class:"suite-info"});t.ele("div",{class:"suite-path"},e.testFilePath);const o=(e.perfStats.end-e.perfStats.start)/1e3;t.ele("div",{class:`suite-time${o>5?" warn":""}`},`${o}s`);const n=s.ele("table",{class:"suite-table",cellspacing:"0",cellpadding:"0"});if(e.testResults.forEach(e=>{const t=n.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)}),this.consoleLogs&&this.consoleLogs.length>0&&this.config.shouldIncludeConsoleLog()){const t=this.consoleLogs.find(t=>t.testFilePath===e.testFilePath);if(t&&t.logs.length>0){const e=s.ele("div",{class:"suite-consolelog"});e.ele("div",{class:"suite-consolelog-header"},"Console Log"),t.logs.forEach(t=>{const s=e.ele("div",{class:"suite-consolelog-item"});s.ele("pre",{class:"suite-consolelog-item-origin"},stripAnsi(t.origin)),s.ele("pre",{class:"suite-consolelog-item-message"},stripAnsi(t.message))})}}}),s}}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",n=()=>Boolean(process.env.JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH)||Boolean(t.styleOverridePath),i=()=>process.env.JEST_HTML_REPORTER_USE_CSS_FILE||t.useCssFile||!1;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:()=>{return(process.env.JEST_HTML_REPORTER_OUTPUT_PATH||t.outputPath||path.join(process.cwd(),"test-report.html")).replace(/<rootdir>/gi,".")},getStylesheetFilepath:()=>process.env.JEST_HTML_REPORTER_STYLE_OVERRIDE_PATH||t.styleOverridePath||path.join(__dirname,`../style/${o()}.css`),getHasStyleOverridePath:n,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,shouldUseCssFile:i,shouldGetStylesheetContent:()=>!(n()&&i()),getExecutionTimeWarningThreshold:()=>process.env.JEST_HTML_REPORTER_EXECUTION_TIME_WARNING_THRESHOLD||t.executionTimeWarningThreshold||5,getBoilerplatePath:()=>process.env.JEST_HTML_REPORTER_BOILERPLATE||t.boilerplate||null,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",getStatusIgnoreFilter:()=>process.env.JEST_HTML_REPORTER_STATUS_FILTER||t.statusIgnoreFilter||null,getAppend:()=>process.env.JEST_HTML_REPORTER_APPEND||t.append||!1}}),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.getHasStyleOverridePath,config_8=config_1.getCustomScriptFilepath,config_9=config_1.getPageTitle,config_10=config_1.getLogo,config_11=config_1.shouldIncludeFailureMessages,config_12=config_1.shouldIncludeConsoleLog,config_13=config_1.shouldUseCssFile,config_14=config_1.shouldGetStylesheetContent,config_15=config_1.getExecutionTimeWarningThreshold,config_16=config_1.getBoilerplatePath,config_17=config_1.getTheme,config_18=config_1.getDateFormat,config_19=config_1.getSort,config_20=config_1.getStatusIgnoreFilter,config_21=config_1.getAppend;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.consoleLogs=[],this.onTestResult=((e,t)=>{t.console&&this.consoleLogs.push({testFilePath:t.testFilePath,logs:t.console})}),this.onRunComplete=((e,t)=>(config_1.setConfigData(this.jestOptions),s.config=config_1,s.consoleLogs=this.consoleLogs,s.generate({data:t})))}var src=JestHtmlReporter;module.exports=src;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sortTestResults = (testResults, sortType) => {
|
|
4
|
+
switch (sortType) {
|
|
5
|
+
case "status":
|
|
6
|
+
return sortTestResultsByStatus(testResults);
|
|
7
|
+
default:
|
|
8
|
+
return testResults;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Splits test suites apart based on individual test status and sorts by that status:
|
|
13
|
+
* 1. Pending
|
|
14
|
+
* 2. Failed
|
|
15
|
+
* 3. Passed
|
|
16
|
+
*/
|
|
17
|
+
const sortTestResultsByStatus = (testResults) => {
|
|
18
|
+
const pendingSuites = [];
|
|
19
|
+
const failingSuites = [];
|
|
20
|
+
const passingSuites = [];
|
|
21
|
+
testResults.forEach(result => {
|
|
22
|
+
const pending = [];
|
|
23
|
+
const failed = [];
|
|
24
|
+
const passed = [];
|
|
25
|
+
result.testResults.forEach(x => {
|
|
26
|
+
if (x.status === "pending") {
|
|
27
|
+
pending.push(x);
|
|
28
|
+
}
|
|
29
|
+
else if (x.status === "failed") {
|
|
30
|
+
failed.push(x);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
passed.push(x);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (pending.length) {
|
|
37
|
+
pendingSuites.push({
|
|
38
|
+
...result,
|
|
39
|
+
testResults: pending
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (failed.length) {
|
|
43
|
+
failingSuites.push({
|
|
44
|
+
...result,
|
|
45
|
+
testResults: failed
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (passed.length) {
|
|
49
|
+
pendingSuites.push({
|
|
50
|
+
...result,
|
|
51
|
+
testResults: failed
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return [].concat(pendingSuites, failingSuites, passingSuites);
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=sortingMethods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sortingMethods.js","sourceRoot":"","sources":["../src/sortingMethods.ts"],"names":[],"mappings":";;AAGa,QAAA,eAAe,GAAG,CAC7B,WAA4C,EAC5C,QAAkC,EACD,EAAE;IACnC,QAAQ,QAAQ,EAAE;QAChB,KAAK,QAAQ;YACX,OAAO,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAC9C;YACE,OAAO,WAAW,CAAC;KACtB;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,uBAAuB,GAAG,CAC9B,WAA4C,EAC5C,EAAE;IACF,MAAM,aAAa,GAAoC,EAAE,CAAC;IAC1D,MAAM,aAAa,GAAoC,EAAE,CAAC;IAC1D,MAAM,aAAa,GAAoC,EAAE,CAAC;IAE1D,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QAC3B,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,MAAM,MAAM,GAAsB,EAAE,CAAC;QAErC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAC7B,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE;gBAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;iBAAM,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE;gBAChC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAChB;iBAAM;gBACL,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aAChB;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,aAAa,CAAC,IAAI,CAAC;gBACjB,GAAG,MAAM;gBACT,WAAW,EAAE,OAAO;aACrB,CAAC,CAAC;SACJ;QACD,IAAI,MAAM,CAAC,MAAM,EAAE;YACjB,aAAa,CAAC,IAAI,CAAC;gBACjB,GAAG,MAAM;gBACT,WAAW,EAAE,MAAM;aACpB,CAAC,CAAC;SACJ;QACD,IAAI,MAAM,CAAC,MAAM,EAAE;YACjB,aAAa,CAAC,IAAI,CAAC;gBACjB,GAAG,MAAM;gBACT,WAAW,EAAE,MAAM;aACpB,CAAC,CAAC;SACJ;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;AAChE,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jest-html-reporter",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.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",
|
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
"xmlbuilder": "13.0.2"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"jest": "19.x -
|
|
47
|
+
"jest": "19.x - 25.x"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"eslint": "^4.19.1",
|
|
51
51
|
"eslint-config-airbnb-base": "^12.1.0",
|
|
52
|
-
"eslint-plugin-import": "^2.
|
|
52
|
+
"eslint-plugin-import": "^2.20.1",
|
|
53
53
|
"istanbul-api": "1.2.2",
|
|
54
54
|
"istanbul-reports": "1.1.4",
|
|
55
|
-
"jest": "^
|
|
55
|
+
"jest": "^25.1.0",
|
|
56
56
|
"rollup": "^0.55.5",
|
|
57
57
|
"rollup-plugin-commonjs": "^8.4.1",
|
|
58
58
|
"rollup-plugin-node-resolve": "^3.4.0",
|