monocart-reporter 1.6.33 → 1.6.35
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 +50 -53
- package/lib/cli.js +10 -3
- package/lib/generate-data.js +7 -4
- package/lib/plugins/audit/audit.js +3 -6
- package/lib/plugins/coverage/coverage-utils.js +33 -71
- package/lib/plugins/coverage/coverage.js +84 -61
- package/lib/plugins/coverage/istanbul/istanbul.js +25 -51
- package/lib/plugins/coverage/v8/dedupe.js +8 -17
- package/lib/plugins/coverage/v8/source-map.js +187 -21
- package/lib/plugins/coverage/v8/v8.js +132 -91
- package/lib/plugins/network/network.js +7 -7
- package/lib/runtime/monocart-common.js +1 -1
- package/lib/runtime/monocart-coverage.js +14 -11
- package/lib/runtime/monocart-network.js +1 -1
- package/lib/runtime/monocart-reporter.js +1 -1
- package/lib/runtime/monocart-v8.js +1 -1
- package/lib/utils/util.js +15 -0
- package/lib/visitor.js +17 -9
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -159,7 +159,11 @@ Separated metadata file (Already included in the above HTML and compressed, it c
|
|
|
159
159
|
## View Trace Online
|
|
160
160
|
> The [Trace Viewer](https://trace.playwright.dev/) requires that the trace file must be loaded over the http:// or https:// protocols without [CORS](https://developer.mozilla.org/en-US/docs/Glossary/CORS) issue, try following start a local web server:
|
|
161
161
|
```sh
|
|
162
|
+
# serve and open report
|
|
162
163
|
npx monocart show-report <your-outputFile-path>
|
|
164
|
+
|
|
165
|
+
# serve report
|
|
166
|
+
npx monocart serve-report <your-outputFile-path>
|
|
163
167
|
```
|
|
164
168
|
Or customize your own trace viewer url with option `traceViewerUrl` defaults to `https://trace.playwright.dev/?trace={traceUrl}`
|
|
165
169
|
|
|
@@ -627,6 +631,7 @@ Attach a code coverage report with API `attachCoverageReport(data, testInfo, opt
|
|
|
627
631
|
- Istanbul only:
|
|
628
632
|
- `watermarks` (Object) Istanbul watermarks, see [here](https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-lib-report)
|
|
629
633
|
- `lcov` (Boolean) Whether to create `lcov.info`
|
|
634
|
+
- `sourcePath` (Function) source path handler, return a new source path
|
|
630
635
|
- V8 only:
|
|
631
636
|
- `toIstanbul` (Boolean) Whether to convert to Istanbul report
|
|
632
637
|
- `watermarks` (Array) Defaults to `[50, 80]`
|
|
@@ -642,30 +647,27 @@ Attach a code coverage report with API `attachCoverageReport(data, testInfo, opt
|
|
|
642
647
|
```js
|
|
643
648
|
import { test, expect } from '@playwright/test';
|
|
644
649
|
import { attachCoverageReport } from 'monocart-reporter';
|
|
645
|
-
test.describe.configure({
|
|
646
|
-
mode: 'serial'
|
|
647
|
-
});
|
|
648
|
-
let page;
|
|
649
|
-
test.describe('take Istanbul coverage', () => {
|
|
650
|
-
test('first, open page', async ({ browser }) => {
|
|
651
|
-
page = await browser.newPage();
|
|
652
|
-
await page.goto(pageUrl);
|
|
653
|
-
});
|
|
654
650
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
651
|
+
test('Take Istanbul coverage report', async ({ page }) => {
|
|
652
|
+
|
|
653
|
+
await page.goto('http://localhost:8090/coverage/istanbul.html');
|
|
654
|
+
|
|
655
|
+
// delay for mock code execution
|
|
656
|
+
await new Promise((resolve) => {
|
|
657
|
+
setTimeout(resolve, 500);
|
|
659
658
|
});
|
|
660
659
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
660
|
+
// take Istanbul coverage
|
|
661
|
+
const coverageData = await page.evaluate(() => window.__coverage__);
|
|
662
|
+
await page.close();
|
|
663
|
+
expect(coverageData, 'expect found Istanbul data: __coverage__').toBeTruthy();
|
|
664
|
+
|
|
665
|
+
// coverage report
|
|
666
|
+
const report = await attachCoverageReport(coverageData, test.info(), {
|
|
667
|
+
lcov: true
|
|
668
668
|
});
|
|
669
|
+
console.log(report.summary);
|
|
670
|
+
|
|
669
671
|
});
|
|
670
672
|
```
|
|
671
673
|
|
|
@@ -675,43 +677,38 @@ test.describe('take Istanbul coverage', () => {
|
|
|
675
677
|
```js
|
|
676
678
|
import { test, expect } from '@playwright/test';
|
|
677
679
|
import { attachCoverageReport } from 'monocart-reporter';
|
|
678
|
-
test.describe.configure({
|
|
679
|
-
mode: 'serial'
|
|
680
|
-
});
|
|
681
|
-
let page;
|
|
682
|
-
test.describe('take V8 coverage', () => {
|
|
683
|
-
test('first, open page', async ({ browser }) => {
|
|
684
|
-
page = await browser.newPage();
|
|
685
|
-
await Promise.all([
|
|
686
|
-
page.coverage.startJSCoverage(),
|
|
687
|
-
page.coverage.startCSSCoverage()
|
|
688
|
-
]);
|
|
689
|
-
await page.goto(pageUrl);
|
|
690
|
-
});
|
|
691
680
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
681
|
+
test('Take V8 and Istanbul coverage report', async ({ page }) => {
|
|
682
|
+
|
|
683
|
+
await Promise.all([
|
|
684
|
+
page.coverage.startJSCoverage({
|
|
685
|
+
resetOnNavigation: false
|
|
686
|
+
}),
|
|
687
|
+
page.coverage.startCSSCoverage({
|
|
688
|
+
resetOnNavigation: false
|
|
689
|
+
})
|
|
690
|
+
]);
|
|
691
|
+
|
|
692
|
+
await page.goto('http://localhost:8090/coverage/v8.html');
|
|
693
|
+
|
|
694
|
+
// delay for mock code execution
|
|
695
|
+
await new Promise((resolve) => {
|
|
696
|
+
setTimeout(resolve, 500);
|
|
696
697
|
});
|
|
697
698
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
// }
|
|
709
|
-
// });
|
|
710
|
-
expect(coverageList.length).toBeGreaterThan(0);
|
|
711
|
-
// coverage report
|
|
712
|
-
const report = await attachCoverageReport(coverageList, test.info());
|
|
713
|
-
console.log(report.summary);
|
|
699
|
+
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
700
|
+
page.coverage.stopJSCoverage(),
|
|
701
|
+
page.coverage.stopCSSCoverage()
|
|
702
|
+
]);
|
|
703
|
+
await page.close();
|
|
704
|
+
|
|
705
|
+
const coverageList = [... jsCoverage, ... cssCoverage];
|
|
706
|
+
|
|
707
|
+
const v8 = await attachCoverageReport(coverageList, test.info(), {
|
|
708
|
+
excludeDistFile: false
|
|
714
709
|
});
|
|
710
|
+
console.log(v8.summary);
|
|
711
|
+
|
|
715
712
|
});
|
|
716
713
|
```
|
|
717
714
|
|
package/lib/cli.js
CHANGED
|
@@ -35,7 +35,7 @@ const openUrl = async (p) => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
const
|
|
38
|
+
const serveReport = async (list, openReport) => {
|
|
39
39
|
if (!list.length) {
|
|
40
40
|
list.push(defaultOptions.outputFile);
|
|
41
41
|
}
|
|
@@ -83,7 +83,9 @@ const showReport = async (list) => {
|
|
|
83
83
|
|
|
84
84
|
server.listen(port, function() {
|
|
85
85
|
EC.logCyan(`${new Date().toLocaleString()} server listening on ${url}`);
|
|
86
|
-
|
|
86
|
+
if (openReport) {
|
|
87
|
+
openUrl(url);
|
|
88
|
+
}
|
|
87
89
|
});
|
|
88
90
|
|
|
89
91
|
};
|
|
@@ -93,7 +95,12 @@ const start = function() {
|
|
|
93
95
|
const command = args.shift();
|
|
94
96
|
// console.log(command, args);
|
|
95
97
|
if (command === 'show-report') {
|
|
96
|
-
|
|
98
|
+
serveReport(args, true);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (command === 'serve-report') {
|
|
103
|
+
serveReport(args, false);
|
|
97
104
|
}
|
|
98
105
|
};
|
|
99
106
|
|
package/lib/generate-data.js
CHANGED
|
@@ -4,8 +4,9 @@ const Util = require('./utils/util.js');
|
|
|
4
4
|
const { getTickInfo } = require('./utils/system.js');
|
|
5
5
|
const Visitor = require('./visitor.js');
|
|
6
6
|
const { calculateSummary } = require('./common.js');
|
|
7
|
-
const {
|
|
8
|
-
const {
|
|
7
|
+
const { generateGlobalCoverageReport } = require('./plugins/coverage/coverage.js');
|
|
8
|
+
const { generateGlobalNetworkReport } = require('./plugins/network/network.js');
|
|
9
|
+
const version = require('../package.json').version;
|
|
9
10
|
|
|
10
11
|
const getReportName = (options, config, metadata) => {
|
|
11
12
|
const reportName = options.name || config.name || metadata.name;
|
|
@@ -20,11 +21,11 @@ const artifactsHandler = async (visitor, options) => {
|
|
|
20
21
|
// global artifacts
|
|
21
22
|
const { coverage, network } = visitor.artifactDataMap;
|
|
22
23
|
if (coverage) {
|
|
23
|
-
const report = await
|
|
24
|
+
const report = await generateGlobalCoverageReport(coverage, options);
|
|
24
25
|
artifacts.push(report);
|
|
25
26
|
}
|
|
26
27
|
if (network) {
|
|
27
|
-
const report = await
|
|
28
|
+
const report = await generateGlobalNetworkReport(coverage, options);
|
|
28
29
|
artifacts.push(report);
|
|
29
30
|
}
|
|
30
31
|
return artifacts;
|
|
@@ -92,6 +93,8 @@ const generateData = async (results) => {
|
|
|
92
93
|
system.configFile = Util.relativePath(config.configFile);
|
|
93
94
|
// playwright version
|
|
94
95
|
system.playwright = config.version;
|
|
96
|
+
// monocart version
|
|
97
|
+
system.monocart = version;
|
|
95
98
|
|
|
96
99
|
// test root dir
|
|
97
100
|
system.testDir = Util.relativePath(config.rootDir);
|
|
@@ -70,13 +70,10 @@ const attachAuditReport = async (runnerResult, testInfo, options = {}) => {
|
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
const title = options.title || `Lighthouse Report - ${testInfo.title}`;
|
|
74
|
-
|
|
75
73
|
options = {
|
|
76
|
-
title
|
|
74
|
+
title: `Lighthouse Report - ${testInfo.title}`,
|
|
77
75
|
outputDir: Util.resolveOutputDir(testInfo),
|
|
78
|
-
outputName: `audit-${Util.
|
|
79
|
-
|
|
76
|
+
outputName: `audit-${Util.resolveTestIdWithRetry(testInfo)}`,
|
|
80
77
|
... options
|
|
81
78
|
};
|
|
82
79
|
|
|
@@ -90,7 +87,7 @@ const attachAuditReport = async (runnerResult, testInfo, options = {}) => {
|
|
|
90
87
|
|
|
91
88
|
// `.lhr` is the Lighthouse Result as a JS object
|
|
92
89
|
const report = {
|
|
93
|
-
title,
|
|
90
|
+
title: options.title,
|
|
94
91
|
... getSummaryReport(runnerResult.lhr)
|
|
95
92
|
};
|
|
96
93
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
const Util = require('../../utils/util.js');
|
|
2
|
-
const Concurrency = require('../../platform/concurrency.js');
|
|
3
|
-
const { convertSourceMap, axios } = require('../../runtime/monocart-coverage.js');
|
|
4
2
|
|
|
5
3
|
const sortRanges = (ranges) => {
|
|
6
4
|
ranges.sort((a, b) => {
|
|
@@ -67,6 +65,8 @@ const getSourcePath = (url, index = '', type = '') => {
|
|
|
67
65
|
return filterPath(relPath);
|
|
68
66
|
};
|
|
69
67
|
|
|
68
|
+
// ========================================================================================================
|
|
69
|
+
|
|
70
70
|
const mergeSourceRoot = (sourceRoot, sourceName) => {
|
|
71
71
|
if (sourceName.startsWith(sourceRoot)) {
|
|
72
72
|
return sourceName;
|
|
@@ -74,89 +74,51 @@ const mergeSourceRoot = (sourceRoot, sourceName) => {
|
|
|
74
74
|
return sourceRoot + sourceName;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
const initSourceMapRootAndUrl = (sourceMap, fileUrls, fileSources) => {
|
|
78
|
+
// reset sourceRoot
|
|
79
|
+
const sourceRoot = sourceMap.sourceRoot || '';
|
|
80
|
+
sourceMap.sourceRoot = '';
|
|
81
|
+
|
|
82
|
+
sourceMap.sources = sourceMap.sources.map((sourceName, i) => {
|
|
83
|
+
const sourceUrl = mergeSourceRoot(sourceRoot, sourceName);
|
|
84
|
+
const sourcePath = getSourcePath(sourceUrl, i + 1);
|
|
85
|
+
fileUrls[sourcePath] = sourceUrl;
|
|
86
|
+
fileSources[sourcePath] = sourceMap.sourcesContent[i];
|
|
87
|
+
return sourcePath;
|
|
88
88
|
});
|
|
89
|
-
return [err, res];
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const getSourceMapUrl = (content, url) => {
|
|
93
89
|
|
|
94
|
-
|
|
95
|
-
if (!m) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
90
|
+
};
|
|
98
91
|
|
|
99
|
-
|
|
100
|
-
const r = convertSourceMap.mapFileCommentRegex.exec(comment);
|
|
101
|
-
// for some odd reason //# .. captures in 1 and /* .. */ in 2
|
|
102
|
-
const filename = r[1] || r[2];
|
|
92
|
+
// ================================================================================================
|
|
103
93
|
|
|
104
|
-
|
|
94
|
+
const convertFunctionsToRanges = (functions) => {
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
} catch (e) {
|
|
109
|
-
// console.log(e)
|
|
110
|
-
}
|
|
111
|
-
if (mapUrl) {
|
|
112
|
-
return mapUrl.toString();
|
|
96
|
+
if (!Util.isList(functions)) {
|
|
97
|
+
return [];
|
|
113
98
|
}
|
|
114
|
-
};
|
|
115
99
|
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
100
|
+
const ranges = [];
|
|
101
|
+
for (const fun of functions) {
|
|
102
|
+
if (fun.ranges) {
|
|
103
|
+
for (const range of fun.ranges) {
|
|
104
|
+
// rename startOffset/endOffset to start/end, keep count
|
|
105
|
+
ranges.push({
|
|
106
|
+
start: range.startOffset,
|
|
107
|
+
end: range.endOffset,
|
|
108
|
+
count: range.count
|
|
109
|
+
});
|
|
110
|
+
}
|
|
121
111
|
}
|
|
122
|
-
return data;
|
|
123
112
|
}
|
|
124
|
-
};
|
|
125
113
|
|
|
126
|
-
|
|
127
|
-
const concurrency = new Concurrency();
|
|
128
|
-
for (const item of v8list) {
|
|
129
|
-
// useless for css
|
|
130
|
-
if (item.type === 'css') {
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
114
|
+
sortRanges(ranges);
|
|
133
115
|
|
|
134
|
-
|
|
135
|
-
const converter = convertSourceMap.fromSource(source);
|
|
136
|
-
if (converter) {
|
|
137
|
-
item.sourceMap = resolveSourceMap(converter.sourcemap);
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
const sourceMapUrl = getSourceMapUrl(source, item.url);
|
|
141
|
-
if (sourceMapUrl) {
|
|
142
|
-
item.sourceMapUrl = sourceMapUrl;
|
|
143
|
-
concurrency.addItem(item);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
await concurrency.start(async (item) => {
|
|
147
|
-
const [err, res] = await request({
|
|
148
|
-
url: item.sourceMapUrl
|
|
149
|
-
});
|
|
150
|
-
if (!err && res) {
|
|
151
|
-
item.sourceMap = resolveSourceMap(res.data);
|
|
152
|
-
}
|
|
153
|
-
});
|
|
116
|
+
return ranges;
|
|
154
117
|
};
|
|
155
118
|
|
|
156
|
-
|
|
157
119
|
module.exports = {
|
|
158
120
|
sortRanges,
|
|
159
121
|
getSourcePath,
|
|
160
|
-
|
|
161
|
-
|
|
122
|
+
initSourceMapRootAndUrl,
|
|
123
|
+
convertFunctionsToRanges
|
|
162
124
|
};
|
|
@@ -3,13 +3,9 @@ const path = require('path');
|
|
|
3
3
|
const EC = require('eight-colors');
|
|
4
4
|
|
|
5
5
|
const Util = require('../../utils/util.js');
|
|
6
|
-
|
|
7
|
-
const {
|
|
8
|
-
convertV8ToIstanbul, mergeIstanbulList, saveIstanbulReport
|
|
9
|
-
} = require('./istanbul/istanbul.js');
|
|
10
|
-
|
|
6
|
+
const { convertV8ToIstanbul, saveIstanbulReport } = require('./istanbul/istanbul.js');
|
|
11
7
|
const {
|
|
12
|
-
|
|
8
|
+
initV8ListAndSourcemap, unpackV8List, mergeV8Coverage, saveV8Report
|
|
13
9
|
} = require('./v8/v8.js');
|
|
14
10
|
|
|
15
11
|
// ========================================================================================================
|
|
@@ -48,6 +44,9 @@ const defaultIstanbulOptions = {
|
|
|
48
44
|
unpackSourceMap: true,
|
|
49
45
|
sourceFilter: null,
|
|
50
46
|
|
|
47
|
+
// source path handler
|
|
48
|
+
sourcePath: null,
|
|
49
|
+
|
|
51
50
|
// (usually not used) source finder for Istanbul HTML report
|
|
52
51
|
sourceFinder: null,
|
|
53
52
|
|
|
@@ -101,6 +100,10 @@ const generateV8Coverage = async (v8list, testInfo, options) => {
|
|
|
101
100
|
... options
|
|
102
101
|
};
|
|
103
102
|
|
|
103
|
+
// init v8list and unpack sourcemap
|
|
104
|
+
const inlineSourceMap = true;
|
|
105
|
+
v8list = await initV8ListAndSourcemap(v8list, options, inlineSourceMap);
|
|
106
|
+
|
|
104
107
|
// ================================================================
|
|
105
108
|
|
|
106
109
|
if (options.toIstanbul) {
|
|
@@ -120,7 +123,8 @@ const generateV8Coverage = async (v8list, testInfo, options) => {
|
|
|
120
123
|
|
|
121
124
|
// ================================================================
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
// functions to ranges, and unpack source maps
|
|
127
|
+
await unpackV8List(v8list, options);
|
|
124
128
|
|
|
125
129
|
const report = await saveV8Report(v8list, options);
|
|
126
130
|
|
|
@@ -136,21 +140,26 @@ const attachCoverageReport = (coverageInput, testInfo, options = {}) => {
|
|
|
136
140
|
return;
|
|
137
141
|
}
|
|
138
142
|
|
|
139
|
-
const title = options.title || `Coverage Report - ${testInfo.title}`;
|
|
140
|
-
|
|
141
143
|
options = {
|
|
142
|
-
title
|
|
144
|
+
// default title
|
|
145
|
+
title: `Coverage Report - ${testInfo.title}`,
|
|
143
146
|
outputDir: Util.resolveOutputDir(testInfo),
|
|
144
|
-
outputName: `coverage-${Util.
|
|
147
|
+
outputName: `coverage-${Util.resolveTestIdWithRetry(testInfo)}`,
|
|
145
148
|
... options
|
|
146
149
|
};
|
|
147
150
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
151
|
+
// support multiple calls
|
|
152
|
+
let htmlDir = path.resolve(options.outputDir, options.outputName);
|
|
153
|
+
let i = 1;
|
|
154
|
+
while (fs.existsSync(htmlDir)) {
|
|
155
|
+
const outputName = `${options.outputName}-${i}`;
|
|
156
|
+
htmlDir = path.resolve(options.outputDir, outputName);
|
|
157
|
+
i += 1;
|
|
153
158
|
}
|
|
159
|
+
|
|
160
|
+
fs.mkdirSync(htmlDir, {
|
|
161
|
+
recursive: true
|
|
162
|
+
});
|
|
154
163
|
options.htmlDir = htmlDir;
|
|
155
164
|
|
|
156
165
|
if (Array.isArray(coverageInput)) {
|
|
@@ -162,26 +171,11 @@ const attachCoverageReport = (coverageInput, testInfo, options = {}) => {
|
|
|
162
171
|
|
|
163
172
|
// ========================================================================================================
|
|
164
173
|
|
|
165
|
-
const generateArtifactData = (v8list, options) => {
|
|
166
|
-
options = {
|
|
167
|
-
... defaultV8Options,
|
|
168
|
-
... options
|
|
169
|
-
};
|
|
170
|
-
if (options.toIstanbul) {
|
|
171
|
-
options = {
|
|
172
|
-
... defaultIstanbulOptions,
|
|
173
|
-
... options
|
|
174
|
-
};
|
|
175
|
-
return convertV8ToIstanbul(v8list, options);
|
|
176
|
-
}
|
|
177
|
-
return initV8List(v8list, options);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
174
|
// add coverage report to global, v8list only
|
|
181
|
-
const addCoverageReport = async (
|
|
175
|
+
const addCoverageReport = async (v8list, testInfo) => {
|
|
182
176
|
|
|
183
|
-
if (!
|
|
184
|
-
EC.logRed(
|
|
177
|
+
if (!Util.isList(v8list)) {
|
|
178
|
+
EC.logRed(`[MCR] invalid v8 list for test: ${testInfo.title}`);
|
|
185
179
|
return;
|
|
186
180
|
}
|
|
187
181
|
|
|
@@ -193,25 +187,33 @@ const addCoverageReport = async (coverageInput, testInfo) => {
|
|
|
193
187
|
const outputDir = path.dirname(outputFile);
|
|
194
188
|
|
|
195
189
|
const options = {
|
|
190
|
+
... defaultV8Options,
|
|
196
191
|
// use reporter dir as output dir, NOT test output dir
|
|
197
192
|
outputDir,
|
|
198
193
|
outputName: 'coverage',
|
|
199
194
|
... coverageOptions
|
|
200
195
|
};
|
|
201
196
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const
|
|
197
|
+
const reportDir = path.resolve(options.outputDir, options.outputName);
|
|
198
|
+
|
|
199
|
+
// artifactsDir for temp artifact files
|
|
200
|
+
const artifactsDir = path.resolve(reportDir, '.artifacts');
|
|
201
|
+
options.artifactsDir = artifactsDir;
|
|
206
202
|
|
|
207
|
-
const
|
|
203
|
+
const filename = `coverage-${Util.resolveTestIdWithRetry(testInfo)}.json`;
|
|
204
|
+
const jsonPath = path.resolve(artifactsDir, filename);
|
|
208
205
|
|
|
209
|
-
//
|
|
206
|
+
// init v8list and unpack sourcemap
|
|
207
|
+
const inlineSourceMap = false;
|
|
208
|
+
v8list = await initV8ListAndSourcemap(v8list, options, inlineSourceMap);
|
|
209
|
+
|
|
210
|
+
// console.log('addCoverageReport', coverageInput.map((it) => it.url));
|
|
210
211
|
|
|
211
212
|
const report = {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
data
|
|
213
|
+
// title for debug
|
|
214
|
+
title: testInfo.title,
|
|
215
|
+
// merge with data
|
|
216
|
+
data: v8list
|
|
215
217
|
};
|
|
216
218
|
|
|
217
219
|
const artifactContent = JSON.stringify({
|
|
@@ -233,34 +235,43 @@ const addCoverageReport = async (coverageInput, testInfo) => {
|
|
|
233
235
|
|
|
234
236
|
// ========================================================================================================
|
|
235
237
|
|
|
236
|
-
const
|
|
238
|
+
const getGlobalCoverageData = async (dataList, options) => {
|
|
237
239
|
|
|
238
240
|
options = {
|
|
239
241
|
... defaultV8Options,
|
|
240
242
|
... options
|
|
241
243
|
};
|
|
242
244
|
|
|
245
|
+
// merge v8list first
|
|
246
|
+
const v8list = await mergeV8Coverage(dataList, options);
|
|
247
|
+
// console.log('after merge', v8list.map((it) => it.url));
|
|
248
|
+
|
|
243
249
|
if (options.toIstanbul) {
|
|
250
|
+
|
|
244
251
|
options = {
|
|
245
252
|
... defaultIstanbulOptions,
|
|
246
253
|
... options
|
|
247
254
|
};
|
|
248
|
-
|
|
249
|
-
const { coverageData, fileSources } =
|
|
250
|
-
|
|
255
|
+
|
|
256
|
+
const { coverageData, fileSources } = await convertV8ToIstanbul(v8list, options);
|
|
257
|
+
|
|
258
|
+
const report = await saveIstanbulReport(coverageData, fileSources, options);
|
|
259
|
+
|
|
260
|
+
// console.log(report);
|
|
261
|
+
|
|
262
|
+
return report;
|
|
251
263
|
}
|
|
252
264
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return saveV8Report(v8list, options);
|
|
265
|
+
// functions to ranges, and unpack source maps
|
|
266
|
+
await unpackV8List(v8list, options);
|
|
267
|
+
|
|
268
|
+
const report = await saveV8Report(v8list, options);
|
|
269
|
+
|
|
270
|
+
return report;
|
|
260
271
|
};
|
|
261
272
|
|
|
262
273
|
// global coverage report, run different process with addCoverageReport
|
|
263
|
-
const
|
|
274
|
+
const generateGlobalCoverageReport = async (dataList, reporterOptions) => {
|
|
264
275
|
|
|
265
276
|
// reporter outputFile
|
|
266
277
|
const outputFile = await Util.resolveOutputFile(reporterOptions.outputFile);
|
|
@@ -274,15 +285,27 @@ const generateCoverageReport = async (dataList, reporterOptions) => {
|
|
|
274
285
|
... coverageOptions
|
|
275
286
|
};
|
|
276
287
|
|
|
277
|
-
const
|
|
278
|
-
if (!fs.existsSync(
|
|
279
|
-
fs.mkdirSync(
|
|
288
|
+
const reportDir = path.resolve(options.outputDir, options.outputName);
|
|
289
|
+
if (!fs.existsSync(reportDir)) {
|
|
290
|
+
fs.mkdirSync(reportDir, {
|
|
280
291
|
recursive: true
|
|
281
292
|
});
|
|
282
293
|
}
|
|
283
|
-
options.htmlDir =
|
|
294
|
+
options.htmlDir = reportDir;
|
|
295
|
+
|
|
296
|
+
// artifactsDir for temp artifact files
|
|
297
|
+
const artifactsDir = path.resolve(reportDir, '.artifacts');
|
|
298
|
+
options.artifactsDir = artifactsDir;
|
|
284
299
|
|
|
285
|
-
const report = await
|
|
300
|
+
const report = await getGlobalCoverageData(dataList, options);
|
|
301
|
+
// console.log(report);
|
|
302
|
+
|
|
303
|
+
// =============================================================
|
|
304
|
+
// remove artifacts dir after report generated
|
|
305
|
+
if (!options.debug) {
|
|
306
|
+
Util.rmSync(artifactsDir);
|
|
307
|
+
}
|
|
308
|
+
// =============================================================
|
|
286
309
|
|
|
287
310
|
return {
|
|
288
311
|
global: true,
|
|
@@ -295,6 +318,6 @@ const generateCoverageReport = async (dataList, reporterOptions) => {
|
|
|
295
318
|
|
|
296
319
|
module.exports = {
|
|
297
320
|
addCoverageReport,
|
|
298
|
-
|
|
321
|
+
generateGlobalCoverageReport,
|
|
299
322
|
attachCoverageReport
|
|
300
323
|
};
|