monocart-reporter 2.9.3 → 2.9.5
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 +4 -3
- package/lib/generate-report.js +55 -34
- package/lib/index.d.ts +6 -1
- package/lib/merge-data.js +25 -1
- package/lib/utils/util.js +44 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1060,13 +1060,14 @@ see example [merge.js](https://github.com/cenfun/monocart-reporter-examples/blob
|
|
|
1060
1060
|
|
|
1061
1061
|
### Using `merge` CLI
|
|
1062
1062
|
```sh
|
|
1063
|
-
|
|
1063
|
+
# NOTE: The asterisk(*) is a special character which is interpreted by some operating systems (Mac and Linux), please put it in quotes
|
|
1064
|
+
npx monocart merge '<glob-patterns>'
|
|
1064
1065
|
|
|
1065
1066
|
# -o --outputFile
|
|
1066
|
-
npx monocart merge path-to/shard*/index.json -o merged-reports/index.html
|
|
1067
|
+
npx monocart merge 'path-to/shard*/index.json' -o merged-reports/index.html
|
|
1067
1068
|
|
|
1068
1069
|
# -c --config
|
|
1069
|
-
npx monocart merge path-to/shard*/
|
|
1070
|
+
npx monocart merge 'path-to/shard*/my-report.zip' -c mr.config.js
|
|
1070
1071
|
```
|
|
1071
1072
|
The default config files (In order of priority)
|
|
1072
1073
|
- mr.config.js
|
package/lib/generate-report.js
CHANGED
|
@@ -18,64 +18,85 @@ const generateJson = (outputDir, filename, reportData, options) => {
|
|
|
18
18
|
reportData.jsonPath = Util.relativePath(jsonPath);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
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
|
+
}
|
|
24
33
|
}
|
|
25
|
-
const dirs = [];
|
|
26
|
-
fs.readdirSync(dir, {
|
|
27
|
-
withFileTypes: true
|
|
28
|
-
}).forEach((it) => {
|
|
29
34
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
if (outputFile) {
|
|
36
|
+
if (!outputFile.endsWith('.zip')) {
|
|
37
|
+
outputFile += '.zip';
|
|
33
38
|
}
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
39
|
+
const zipDir = path.dirname(outputFile);
|
|
40
|
+
if (!fs.existsSync(zipDir)) {
|
|
41
|
+
fs.mkdirSync(zipDir, {
|
|
42
|
+
recursive: true
|
|
43
|
+
});
|
|
37
44
|
}
|
|
38
|
-
});
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
} else {
|
|
47
|
+
outputFile = path.resolve(outputDir, `${filename}.zip`);
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
outputFile,
|
|
53
|
+
clean
|
|
54
|
+
};
|
|
44
55
|
};
|
|
45
56
|
|
|
46
57
|
const generateZip = (outputDir, filename, reportData, options) => {
|
|
47
58
|
|
|
48
|
-
|
|
59
|
+
const zipOptions = options.zip;
|
|
60
|
+
if (!zipOptions) {
|
|
49
61
|
return;
|
|
50
62
|
}
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
if (typeof options.zip === 'string') {
|
|
54
|
-
zipPath = options.zip;
|
|
55
|
-
if (!zipPath.endsWith('.zip')) {
|
|
56
|
-
zipPath += '.zip';
|
|
57
|
-
}
|
|
58
|
-
const zipDir = path.dirname(zipPath);
|
|
59
|
-
if (!fs.existsSync(zipDir)) {
|
|
60
|
-
fs.mkdirSync(zipDir, {
|
|
61
|
-
recursive: true
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
64
|
+
const { outputFile, clean } = initZipOptions(outputDir, filename, zipOptions);
|
|
65
65
|
|
|
66
66
|
const reportFiles = [];
|
|
67
67
|
return new Promise((resolve) => {
|
|
68
68
|
const zipFile = new ZipFile();
|
|
69
|
-
zipFile.outputStream.pipe(fs.createWriteStream(
|
|
69
|
+
zipFile.outputStream.pipe(fs.createWriteStream(outputFile)).on('close', function() {
|
|
70
70
|
|
|
71
|
-
// remove files after zip
|
|
72
71
|
reportData.reportFiles = reportFiles;
|
|
73
|
-
|
|
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);
|
|
74
95
|
|
|
75
96
|
resolve();
|
|
76
97
|
});
|
|
77
98
|
|
|
78
|
-
forEachFile(outputDir, (name, dir) => {
|
|
99
|
+
Util.forEachFile(outputDir, (name, dir) => {
|
|
79
100
|
const absPath = path.resolve(dir, name);
|
|
80
101
|
const relPath = Util.relativePath(absPath, outputDir);
|
|
81
102
|
reportFiles.push(relPath);
|
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
|
@@ -37,7 +37,31 @@ const unzipDataFile = async (item, num, options) => {
|
|
|
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
|
+
if (fs.existsSync(jsonPath)) {
|
|
42
|
+
return jsonPath;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// filename for both html and json
|
|
46
|
+
const htmlMap = {};
|
|
47
|
+
const jsonMap = {};
|
|
48
|
+
Util.forEachFile(unzipDir, (name, dir) => {
|
|
49
|
+
if (name.endsWith('.html')) {
|
|
50
|
+
htmlMap[path.basename(name, '.html')] = true;
|
|
51
|
+
} else if (name.endsWith('.json')) {
|
|
52
|
+
jsonMap[path.basename(name, '.json')] = true;
|
|
53
|
+
}
|
|
54
|
+
}, true);
|
|
55
|
+
|
|
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
|
+
}
|
|
63
|
+
|
|
64
|
+
return jsonPath;
|
|
41
65
|
};
|
|
42
66
|
|
|
43
67
|
const getReportData = async (item, num, options) => {
|
package/lib/utils/util.js
CHANGED
|
@@ -277,6 +277,50 @@ const Util = {
|
|
|
277
277
|
}
|
|
278
278
|
},
|
|
279
279
|
|
|
280
|
+
// eslint-disable-next-line complexity
|
|
281
|
+
forEachFile: (dir, callback, shallow) => {
|
|
282
|
+
if (!fs.existsSync(dir)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const isBreak = (res) => {
|
|
287
|
+
return res === 'break' || res === false;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const dirs = [];
|
|
291
|
+
const list = fs.readdirSync(dir, {
|
|
292
|
+
withFileTypes: true
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
for (const item of list) {
|
|
296
|
+
|
|
297
|
+
if (item.isFile()) {
|
|
298
|
+
const res = callback(item.name, dir);
|
|
299
|
+
if (isBreak(res)) {
|
|
300
|
+
return res;
|
|
301
|
+
}
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (item.isDirectory()) {
|
|
306
|
+
dirs.push(path.resolve(dir, item.name));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (shallow) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
for (const subDir of dirs) {
|
|
316
|
+
const res = Util.forEachFile(subDir, callback, shallow);
|
|
317
|
+
if (isBreak(res)) {
|
|
318
|
+
return res;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
},
|
|
323
|
+
|
|
280
324
|
getTemplate: function(templatePath) {
|
|
281
325
|
if (!Util.templateCache) {
|
|
282
326
|
Util.templateCache = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monocart-reporter",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.5",
|
|
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",
|