monocart-reporter 2.9.4 → 2.9.6
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 +5 -1
- package/lib/cli.js +16 -3
- package/lib/generate-report.js +60 -13
- package/lib/index.d.ts +6 -1
- package/lib/merge-data.js +15 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1066,7 +1066,11 @@ npx monocart merge <glob-patterns>
|
|
|
1066
1066
|
npx monocart merge path-to/shard*/index.json -o merged-reports/index.html
|
|
1067
1067
|
|
|
1068
1068
|
# -c --config
|
|
1069
|
-
npx monocart merge path-to/shard*/
|
|
1069
|
+
npx monocart merge path-to/shard*/my-report.zip -c mr.config.js
|
|
1070
|
+
|
|
1071
|
+
# NOTE: The asterisk(*) is a special character which is interpreted by some operating systems
|
|
1072
|
+
# For example: Mac and Linux, please put it in quotes, but NOT for Windows
|
|
1073
|
+
npx monocart merge 'path-to/shard*/*.zip'
|
|
1070
1074
|
```
|
|
1071
1075
|
The default config files (In order of priority)
|
|
1072
1076
|
- mr.config.js
|
package/lib/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
@@ -272,6 +272,12 @@ const resolveConfigOptions = async (configPath) => {
|
|
|
272
272
|
return configOptions;
|
|
273
273
|
};
|
|
274
274
|
|
|
275
|
+
const exit = (code) => {
|
|
276
|
+
if (code) {
|
|
277
|
+
process.exit(code);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
275
281
|
const mergeReports = async (str, cliOptions) => {
|
|
276
282
|
|
|
277
283
|
await initNodeOptions(cliOptions);
|
|
@@ -285,6 +291,7 @@ const mergeReports = async (str, cliOptions) => {
|
|
|
285
291
|
} else {
|
|
286
292
|
if (customConfig) {
|
|
287
293
|
Util.logError(`ERROR: not found config file: ${customConfig}`);
|
|
294
|
+
exit(1);
|
|
288
295
|
return;
|
|
289
296
|
}
|
|
290
297
|
}
|
|
@@ -297,15 +304,21 @@ const mergeReports = async (str, cliOptions) => {
|
|
|
297
304
|
|
|
298
305
|
Util.initLoggingLevel(options.logging);
|
|
299
306
|
|
|
307
|
+
Util.logInfo(`glob patterns: ${EC.cyan(str)}`);
|
|
308
|
+
|
|
300
309
|
const files = await glob(str);
|
|
301
310
|
if (!Util.isList(files)) {
|
|
302
311
|
Util.logError(`ERROR: no files found with glob: ${str}`);
|
|
312
|
+
exit(1);
|
|
303
313
|
return;
|
|
304
314
|
}
|
|
305
|
-
// console.log(files, options);
|
|
306
315
|
|
|
307
|
-
|
|
316
|
+
Util.logInfo(`glob files: ${files.join(', ')}`);
|
|
308
317
|
|
|
318
|
+
const reportData = await merge(files, options);
|
|
319
|
+
if (!reportData) {
|
|
320
|
+
exit(1);
|
|
321
|
+
}
|
|
309
322
|
};
|
|
310
323
|
|
|
311
324
|
program
|
package/lib/generate-report.js
CHANGED
|
@@ -18,34 +18,80 @@ const generateJson = (outputDir, filename, reportData, options) => {
|
|
|
18
18
|
reportData.jsonPath = Util.relativePath(jsonPath);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const initZipOptions = (outputDir, filename, zipOptions) => {
|
|
22
|
+
let clean = false;
|
|
23
|
+
let outputFile;
|
|
24
|
+
if (typeof zipOptions === 'string') {
|
|
25
|
+
outputFile = zipOptions;
|
|
26
|
+
} else if (typeof zipOptions === 'object') {
|
|
27
|
+
if (zipOptions.outputFile) {
|
|
28
|
+
outputFile = zipOptions.outputFile;
|
|
29
|
+
}
|
|
30
|
+
if (zipOptions.clean) {
|
|
31
|
+
clean = true;
|
|
32
|
+
}
|
|
25
33
|
}
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!zipPath.endsWith('.zip')) {
|
|
31
|
-
zipPath += '.zip';
|
|
35
|
+
if (outputFile) {
|
|
36
|
+
if (!outputFile.endsWith('.zip')) {
|
|
37
|
+
outputFile += '.zip';
|
|
32
38
|
}
|
|
33
|
-
const zipDir = path.dirname(
|
|
39
|
+
const zipDir = path.dirname(outputFile);
|
|
34
40
|
if (!fs.existsSync(zipDir)) {
|
|
35
41
|
fs.mkdirSync(zipDir, {
|
|
36
42
|
recursive: true
|
|
37
43
|
});
|
|
38
44
|
}
|
|
45
|
+
|
|
46
|
+
} else {
|
|
47
|
+
outputFile = path.resolve(outputDir, `${filename}.zip`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
outputFile,
|
|
53
|
+
clean
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const generateZip = (outputDir, filename, reportData, options) => {
|
|
58
|
+
|
|
59
|
+
const zipOptions = options.zip;
|
|
60
|
+
if (!zipOptions) {
|
|
61
|
+
return;
|
|
39
62
|
}
|
|
40
63
|
|
|
64
|
+
const { outputFile, clean } = initZipOptions(outputDir, filename, zipOptions);
|
|
65
|
+
|
|
41
66
|
const reportFiles = [];
|
|
42
67
|
return new Promise((resolve) => {
|
|
43
68
|
const zipFile = new ZipFile();
|
|
44
|
-
zipFile.outputStream.pipe(fs.createWriteStream(
|
|
69
|
+
zipFile.outputStream.pipe(fs.createWriteStream(outputFile)).on('close', function() {
|
|
45
70
|
|
|
46
|
-
// remove files after zip
|
|
47
71
|
reportData.reportFiles = reportFiles;
|
|
48
|
-
|
|
72
|
+
|
|
73
|
+
// whether to clean the files after zipped
|
|
74
|
+
if (clean) {
|
|
75
|
+
// console.log('clean', reportFiles);
|
|
76
|
+
const dirSet = new Set();
|
|
77
|
+
reportFiles.forEach((f) => {
|
|
78
|
+
const fp = path.resolve(outputDir, f);
|
|
79
|
+
dirSet.add(path.dirname(fp));
|
|
80
|
+
Util.rmSync(fp);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// clean empty dirs
|
|
84
|
+
const dirList = Array.from(dirSet).reverse();
|
|
85
|
+
dirList.forEach((dir) => {
|
|
86
|
+
const files = fs.readdirSync(dir);
|
|
87
|
+
if (files.length === 0) {
|
|
88
|
+
Util.rmSync(dir);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
reportData.zipPath = Util.relativePath(outputFile);
|
|
49
95
|
|
|
50
96
|
resolve();
|
|
51
97
|
});
|
|
@@ -308,6 +354,7 @@ const generateReport = async (reportData, options, rawData) => {
|
|
|
308
354
|
|
|
309
355
|
Util.logInfo(`view report: ${EC.cyan(`npx monocart show-report ${htmlPath}`)}`);
|
|
310
356
|
|
|
357
|
+
return reportData;
|
|
311
358
|
};
|
|
312
359
|
|
|
313
360
|
module.exports = generateReport;
|
package/lib/index.d.ts
CHANGED
|
@@ -61,7 +61,12 @@ export type MonocartReporterOptions = {
|
|
|
61
61
|
* {boolean} using default path
|
|
62
62
|
* {string} zip file path
|
|
63
63
|
*/
|
|
64
|
-
zip?: boolean | string
|
|
64
|
+
zip?: boolean | string | {
|
|
65
|
+
/** the zip file path */
|
|
66
|
+
outputFile?: string;
|
|
67
|
+
/** whether to clean the files after zipped */
|
|
68
|
+
clean?: boolean;
|
|
69
|
+
};
|
|
65
70
|
|
|
66
71
|
/**
|
|
67
72
|
* whether to copy attachments to the reporter output dir, defaults to true
|
package/lib/merge-data.js
CHANGED
|
@@ -36,20 +36,30 @@ const unzipDataFile = async (item, num, options) => {
|
|
|
36
36
|
// Do not forget to close the file once you're done
|
|
37
37
|
await zip.close();
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
const filename = path.basename(item, '.zip');
|
|
40
40
|
let jsonPath = path.resolve(unzipDir, `${filename}.json`);
|
|
41
41
|
if (fs.existsSync(jsonPath)) {
|
|
42
42
|
return jsonPath;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
// filename for both html and json
|
|
46
|
+
const htmlMap = {};
|
|
47
|
+
const jsonMap = {};
|
|
45
48
|
Util.forEachFile(unzipDir, (name, dir) => {
|
|
46
49
|
if (name.endsWith('.html')) {
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
htmlMap[path.basename(name, '.html')] = true;
|
|
51
|
+
} else if (name.endsWith('.json')) {
|
|
52
|
+
jsonMap[path.basename(name, '.json')] = true;
|
|
49
53
|
}
|
|
50
54
|
}, true);
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
const keys = Object.keys(htmlMap);
|
|
57
|
+
for (const fn of keys) {
|
|
58
|
+
if (jsonMap[fn]) {
|
|
59
|
+
jsonPath = path.resolve(unzipDir, `${fn}.json`);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
53
63
|
|
|
54
64
|
return jsonPath;
|
|
55
65
|
};
|
|
@@ -74,7 +84,7 @@ const getReportData = async (item, num, options) => {
|
|
|
74
84
|
// for finding attachments
|
|
75
85
|
const jsonDir = Util.relativePath(path.dirname(item));
|
|
76
86
|
|
|
77
|
-
Util.logInfo(`report data loaded: ${item}`);
|
|
87
|
+
Util.logInfo(`report data loaded: ${Util.relativePath(item)}`);
|
|
78
88
|
return {
|
|
79
89
|
jsonDir,
|
|
80
90
|
data
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monocart-reporter",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.6",
|
|
4
4
|
"description": "A playwright test reporter. Shows suites/cases/steps with tree style, markdown annotations, custom columns/formatters/data collection visitors, console logs, style tags, send email.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@babel/code-frame": "^7.25.7",
|
|
56
|
-
"@playwright/test": "^1.
|
|
56
|
+
"@playwright/test": "^1.48.0",
|
|
57
57
|
"ansi-to-html": "^0.7.2",
|
|
58
58
|
"async-tick": "^1.0.0",
|
|
59
59
|
"autolinker": "^4.0.0",
|