monocart-reporter 1.6.27 → 1.6.29
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 +15 -50
- package/lib/generate-data.js +3 -3
- package/lib/generate-report.js +30 -22
- package/lib/index.js +4 -0
- package/lib/plugins/audit/audit.js +7 -1
- package/lib/plugins/coverage/coverage-utils.js +8 -0
- package/lib/plugins/coverage/coverage.js +15 -5
- package/lib/plugins/coverage/istanbul/istanbul.js +18 -3
- package/lib/plugins/coverage/v8/position-mapping.js +0 -4
- package/lib/plugins/coverage/v8/source-map.js +64 -122
- package/lib/plugins/coverage/v8/v8.js +1 -0
- package/lib/plugins/network/network.js +3 -1
- package/lib/runtime/monocart-coverage.js +11 -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/runtime/monocart-vendor.js +40 -40
- package/lib/utils/system.js +3 -1
- package/lib/visitor.js +16 -8
- package/package.json +9 -31
package/README.md
CHANGED
|
@@ -493,6 +493,7 @@ module.exports = {
|
|
|
493
493
|
]
|
|
494
494
|
};
|
|
495
495
|
```
|
|
496
|
+
see example [remove-secrets](https://github.com/cenfun/monocart-reporter-test/tree/main/tests/remove-secrets)
|
|
496
497
|
|
|
497
498
|
## Style Tags
|
|
498
499
|
* Add tag to test/describe title ( starts with `@` )
|
|
@@ -742,13 +743,14 @@ const report = await attachCoverageReport(coverageList, test.info(), {
|
|
|
742
743
|
| Input data format | Istanbul (Object) | V8 (Array) | V8 (Array) |
|
|
743
744
|
| Options | `watermarks: {}` | `watermarks: [50, 80]` | `toIstanbul: true, watermarks: {}` |
|
|
744
745
|
| Output report | [Istanbul HTML report](https://cenfun.github.io/monocart-reporter/coverage-4ffdff9b89e7b58476cf/index.html) | [V8 HTML report](https://cenfun.github.io/monocart-reporter/coverage-f8ad4b6741d60f9e7b81/index.html) | [Istanbul HTML report](https://cenfun.github.io/monocart-reporter/coverage-391e7054ca1e6d944895/index.html) |
|
|
745
|
-
| Indicators | Covered Lines, Branches, Statements and Functions, Execution Counts | Covered Bytes, Execution Counts | Covered Lines, Branches, Statements and Functions, Execution Counts |
|
|
746
|
+
| Indicators | Covered Lines, Branches, Statements and Functions, Execution Counts | Covered Bytes, Lines (after formatted) Execution Counts | Covered Lines, Branches, Statements and Functions, Execution Counts |
|
|
747
|
+
| Source code without [instrumentation](https://github.com/istanbuljs/babel-plugin-istanbul) | ❌ | ✅ | ✅ |
|
|
746
748
|
| CSS coverage | ❌ | ✅ | ❌ |
|
|
747
749
|
| Minified code | N/A | ✅ | ❌ |
|
|
748
750
|
| Code formatting | N/A | ✅ | ❌ |
|
|
749
751
|
|
|
750
752
|
### Global Coverage Report
|
|
751
|
-
|
|
753
|
+
The global coverage report will not be attached to any test case, but will merge all coverages into one global report after all the tests are finished. The API is `addCoverageReport(v8list, testInfo)`, currently supported `V8` only. Here is an example for Playwright Component Testing [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue).
|
|
752
754
|
```js
|
|
753
755
|
// playwright.config.js
|
|
754
756
|
module.exports = {
|
|
@@ -906,91 +908,54 @@ module.exports = {
|
|
|
906
908
|
// async hook after report data generated
|
|
907
909
|
onEnd: async (reportData, capability) => {
|
|
908
910
|
// console.log(reportData.summary);
|
|
909
|
-
|
|
910
|
-
// send email
|
|
911
|
-
// const sendEmail = require('./common/send-email.js');
|
|
912
|
-
// await sendEmail(reportData, capability);
|
|
913
|
-
|
|
914
|
-
// testrail integration
|
|
915
|
-
// const testrail = require('./common/testrail.js');
|
|
916
|
-
// await testrail(reportData, capability);
|
|
917
|
-
|
|
918
|
-
// jira + zephyr scale integration
|
|
919
|
-
// const zephyrScale = require('./common/zephyr-scale.js');
|
|
920
|
-
// await zephyrScale(reportData, capability);
|
|
921
|
-
|
|
922
|
-
// jira + xray integration
|
|
923
|
-
// const xray = require('./common/xray.js');
|
|
924
|
-
// await xray(reportData, capability);
|
|
925
|
-
|
|
926
|
-
// slack integration with webhook
|
|
927
|
-
// const slackWebhook = require('./common/slack-webhook.js');
|
|
928
|
-
// await slackWebhook(reportData, capability);
|
|
929
|
-
|
|
930
|
-
// slack integration with web api
|
|
931
|
-
// const slackWebApi = require('./common/slack-web-api.js');
|
|
932
|
-
// await slackWebApi(reportData, capability);
|
|
933
|
-
|
|
934
|
-
// discord integration with webhook
|
|
935
|
-
// const discordWebhook = require('./common/discord-webhook.js');
|
|
936
|
-
// await discordWebhook(reportData, capability);
|
|
937
|
-
|
|
938
|
-
// teams integration with webhook
|
|
939
|
-
// const teamsWebhook = require('./common/teams-webhook.js');
|
|
940
|
-
// await teamsWebhook(reportData, capability);
|
|
941
|
-
|
|
942
|
-
// html to pdf
|
|
943
|
-
// const toPdf = require('./common/to-pdf.js');
|
|
944
|
-
// await toPdf(reportData, capability);
|
|
945
911
|
}
|
|
946
912
|
}]
|
|
947
913
|
]
|
|
948
914
|
};
|
|
949
915
|
```
|
|
950
916
|
## Send Email
|
|
951
|
-
Simply send email with [nodemailer](https://nodemailer.com), check example: [send-email
|
|
917
|
+
Simply send email with [nodemailer](https://nodemailer.com), check example: [send-email](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/send-email)
|
|
952
918
|
|
|
953
919
|

|
|
954
920
|
|
|
955
921
|
|
|
956
922
|
## Testrail Integration
|
|
957
|
-
Send results to your Testrail
|
|
923
|
+
Send test results to your Testrail, check example: [testrail](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/testrail)
|
|
958
924
|
|
|
959
925
|

|
|
960
926
|
|
|
961
927
|
## Jira + Zephyr Scale Integration
|
|
962
|
-
Create test cycle and executions with [zephyr-scale-api](https://support.smartbear.com/zephyr-scale-cloud/api-docs/), check example: [zephyr-scale
|
|
928
|
+
Create test cycle and executions with [zephyr-scale-api](https://support.smartbear.com/zephyr-scale-cloud/api-docs/), check example: [zephyr-scale](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/zephyr-scale)
|
|
963
929
|
|
|
964
930
|

|
|
965
931
|
|
|
966
932
|
## Jira + Xray Integration
|
|
967
|
-
check example: [xray.js](/tests/common/xray.js)
|
|
968
933
|
- Import test execution results with [Xray REST API](https://docs.getxray.app/display/XRAYCLOUD/REST+API)
|
|
969
934
|
- Update Jira issue status with [Jira Transition API](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-transitions-post)
|
|
935
|
+
check example: [xray](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/xray)
|
|
970
936
|
|
|
971
937
|

|
|
972
938
|
|
|
973
|
-
|
|
974
939
|
## Slack Integration
|
|
975
|
-
1. Simply send message with [@slack/webhook](https://github.com/slackapi/node-slack-sdk), example: [slack-webhook
|
|
976
|
-
2. Recommended: Post chat message and upload image with [@slack/web-api](https://github.com/slackapi/node-slack-sdk), example: [slack-web-api
|
|
940
|
+
1. Simply send message with [@slack/webhook](https://github.com/slackapi/node-slack-sdk), example: [slack-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/slack-webhook)
|
|
941
|
+
2. Recommended: Post chat message and upload image with [@slack/web-api](https://github.com/slackapi/node-slack-sdk), example: [slack-web-api](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/slack-web-api)
|
|
977
942
|
|
|
978
943
|

|
|
979
944
|
|
|
980
945
|
## Discord Integration
|
|
981
|
-
Using [Discord webhooks](https://discord.com/developers/docs/resources/webhook) to post messages to channels. example: [discord-webhook
|
|
946
|
+
Using [Discord webhooks](https://discord.com/developers/docs/resources/webhook) to post messages to channels. example: [discord-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/discord-webhook)
|
|
982
947
|
|
|
983
948
|

|
|
984
949
|
|
|
985
950
|
## Teams Integration
|
|
986
|
-
Please create an [Incoming Webhooks](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook) for the channel first. example: [teams-webhook
|
|
951
|
+
Please create an [Incoming Webhooks](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook) for the channel first. example: [teams-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/teams-webhook)
|
|
987
952
|
|
|
988
953
|

|
|
989
954
|
|
|
990
955
|
## Dingtalk/Weixin/Feishu Integration
|
|
991
|
-
- [dingtalk-webhook
|
|
992
|
-
- [weixin-webhook
|
|
993
|
-
- [feishu-webhook
|
|
956
|
+
- [dingtalk-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/dingtalk-webhook)
|
|
957
|
+
- [weixin-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/weixin-webhook)
|
|
958
|
+
- [feishu-webhook](https://github.com/cenfun/monocart-reporter-test/tree/main/integrations/feishu-webhook)
|
|
994
959
|
|
|
995
960
|
## Dependencies
|
|
996
961
|
- UI Framework [Vue 3](https://github.com/vuejs/core)
|
package/lib/generate-data.js
CHANGED
|
@@ -16,9 +16,9 @@ const getReportName = (options, config, metadata) => {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const artifactsHandler = async (visitor, options) => {
|
|
19
|
-
const artifacts = [];
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const artifacts = [].concat(visitor.artifacts);
|
|
20
|
+
// global artifacts
|
|
21
|
+
const { coverage, network } = visitor.artifactDataMap;
|
|
22
22
|
if (coverage) {
|
|
23
23
|
const report = await generateCoverageReport(coverage, options);
|
|
24
24
|
artifacts.push(report);
|
package/lib/generate-report.js
CHANGED
|
@@ -55,22 +55,26 @@ const showTestResults = (reportData) => {
|
|
|
55
55
|
|
|
56
56
|
const summary = reportData.summary;
|
|
57
57
|
|
|
58
|
-
const colorHandler = (item,
|
|
59
|
-
if (item.id === 'failed') {
|
|
60
|
-
if (item.value > 0) {
|
|
61
|
-
v = EC.red(v);
|
|
62
|
-
}
|
|
58
|
+
const colorHandler = (item, row) => {
|
|
63
59
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
60
|
+
if (['failed', 'errors'].includes(item.id) && item.value > 0) {
|
|
61
|
+
row.name = EC.red(row.name);
|
|
62
|
+
row.value = EC.red(row.value);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (['flaky', 'retries'].includes(item.id) && item.value > 0) {
|
|
67
|
+
row.name = EC.yellow(row.name);
|
|
68
|
+
row.value = EC.yellow(row.value);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (item.id === 'passed') {
|
|
69
73
|
if (summary.failed.value === 0 && summary.passed.value > 0) {
|
|
70
|
-
|
|
74
|
+
row.name = EC.green(row.name);
|
|
75
|
+
row.value = EC.green(row.value);
|
|
71
76
|
}
|
|
72
77
|
}
|
|
73
|
-
return v;
|
|
74
78
|
};
|
|
75
79
|
|
|
76
80
|
let rows = [];
|
|
@@ -82,9 +86,12 @@ const showTestResults = (reportData) => {
|
|
|
82
86
|
if (caseTypes.includes(item.id) || suiteSubs.includes(item.id)) {
|
|
83
87
|
return;
|
|
84
88
|
}
|
|
85
|
-
|
|
89
|
+
|
|
90
|
+
const row = {
|
|
86
91
|
... item
|
|
87
|
-
}
|
|
92
|
+
};
|
|
93
|
+
colorHandler(item, row);
|
|
94
|
+
rows.push(row);
|
|
88
95
|
});
|
|
89
96
|
|
|
90
97
|
const tests = rows.find((it) => it.id === 'tests');
|
|
@@ -94,10 +101,12 @@ const showTestResults = (reportData) => {
|
|
|
94
101
|
};
|
|
95
102
|
const value = `${item.value}`.padEnd(`${tests.value}`.length, ' ');
|
|
96
103
|
const percent = `(${item.percent})`;
|
|
97
|
-
|
|
98
|
-
name:
|
|
99
|
-
value:
|
|
104
|
+
const row = {
|
|
105
|
+
name: item.name,
|
|
106
|
+
value: `${value} ${percent}`
|
|
100
107
|
};
|
|
108
|
+
colorHandler(item, row);
|
|
109
|
+
return row;
|
|
101
110
|
});
|
|
102
111
|
|
|
103
112
|
const suites = rows.find((it) => it.id === 'suites');
|
|
@@ -143,11 +152,10 @@ const generateReport = async (reportData, options) => {
|
|
|
143
152
|
|
|
144
153
|
if (artifacts) {
|
|
145
154
|
artifacts.forEach((report) => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// convert
|
|
149
|
-
report.
|
|
150
|
-
|
|
155
|
+
const g = report.global ? `${EC.magenta('(global)')}` : '';
|
|
156
|
+
console.log(`[MCR] ${report.name}: ${EC.cyan(report.path)} ${report.title} ${g}`);
|
|
157
|
+
// convert path to relative reporter
|
|
158
|
+
report.path = Util.relativePath(report.path, outputDir);
|
|
151
159
|
});
|
|
152
160
|
}
|
|
153
161
|
|
package/lib/index.js
CHANGED
|
@@ -70,7 +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
|
+
|
|
73
75
|
options = {
|
|
76
|
+
title,
|
|
74
77
|
outputDir: Util.resolveOutputDir(testInfo),
|
|
75
78
|
outputName: `audit-${Util.shortTestId(testInfo.testId)}`,
|
|
76
79
|
|
|
@@ -86,7 +89,10 @@ const attachAuditReport = async (runnerResult, testInfo, options = {}) => {
|
|
|
86
89
|
options.htmlDir = htmlDir;
|
|
87
90
|
|
|
88
91
|
// `.lhr` is the Lighthouse Result as a JS object
|
|
89
|
-
const report =
|
|
92
|
+
const report = {
|
|
93
|
+
title,
|
|
94
|
+
... getSummaryReport(runnerResult.lhr)
|
|
95
|
+
};
|
|
90
96
|
|
|
91
97
|
const htmlPath = path.resolve(htmlDir, 'index.html');
|
|
92
98
|
// `.report` is the HTML report as a string
|
|
@@ -67,6 +67,13 @@ const getSourcePath = (url, index = '', type = '') => {
|
|
|
67
67
|
return filterPath(relPath);
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
const mergeSourceRoot = (sourceRoot, sourceName) => {
|
|
71
|
+
if (sourceName.startsWith(sourceRoot)) {
|
|
72
|
+
return sourceName;
|
|
73
|
+
}
|
|
74
|
+
return sourceRoot + sourceName;
|
|
75
|
+
};
|
|
76
|
+
|
|
70
77
|
// ================================================================================================
|
|
71
78
|
|
|
72
79
|
const request = async (options) => {
|
|
@@ -150,5 +157,6 @@ const collectSourceMaps = async (v8list) => {
|
|
|
150
157
|
module.exports = {
|
|
151
158
|
sortRanges,
|
|
152
159
|
getSourcePath,
|
|
160
|
+
mergeSourceRoot,
|
|
153
161
|
collectSourceMaps
|
|
154
162
|
};
|
|
@@ -15,6 +15,10 @@ const {
|
|
|
15
15
|
// ========================================================================================================
|
|
16
16
|
|
|
17
17
|
const defaultV8Options = {
|
|
18
|
+
|
|
19
|
+
// Defaults to test title
|
|
20
|
+
// title: '',
|
|
21
|
+
|
|
18
22
|
// (Boolean) Whether to convert to Istanbul report
|
|
19
23
|
toIstanbul: false,
|
|
20
24
|
|
|
@@ -36,6 +40,9 @@ const defaultV8Options = {
|
|
|
36
40
|
|
|
37
41
|
const defaultIstanbulOptions = {
|
|
38
42
|
|
|
43
|
+
// Defaults to test title
|
|
44
|
+
// title: '',
|
|
45
|
+
|
|
39
46
|
// when toIstanbul = true
|
|
40
47
|
entryFilter: null,
|
|
41
48
|
unpackSourceMap: true,
|
|
@@ -129,8 +136,10 @@ const attachCoverageReport = (coverageInput, testInfo, options = {}) => {
|
|
|
129
136
|
return;
|
|
130
137
|
}
|
|
131
138
|
|
|
139
|
+
const title = options.title || `Coverage Report - ${testInfo.title}`;
|
|
140
|
+
|
|
132
141
|
options = {
|
|
133
|
-
title
|
|
142
|
+
title,
|
|
134
143
|
outputDir: Util.resolveOutputDir(testInfo),
|
|
135
144
|
outputName: `coverage-${Util.shortTestId(testInfo.testId)}`,
|
|
136
145
|
... options
|
|
@@ -276,10 +285,11 @@ const generateCoverageReport = async (dataList, reporterOptions) => {
|
|
|
276
285
|
const report = await generateGlobalCoverageReport(dataList, options);
|
|
277
286
|
|
|
278
287
|
return {
|
|
279
|
-
|
|
280
|
-
name: '
|
|
281
|
-
|
|
282
|
-
summary: report.summary
|
|
288
|
+
global: true,
|
|
289
|
+
name: 'coverage',
|
|
290
|
+
path: report.htmlPath,
|
|
291
|
+
summary: report.summary,
|
|
292
|
+
title: options.title
|
|
283
293
|
};
|
|
284
294
|
};
|
|
285
295
|
|
|
@@ -4,6 +4,7 @@ const EC = require('eight-colors');
|
|
|
4
4
|
|
|
5
5
|
const istanbulReports = require('istanbul-reports');
|
|
6
6
|
|
|
7
|
+
const Util = require('../../../utils/util.js');
|
|
7
8
|
const IstanbulSummary = require('./istanbul-summary.js');
|
|
8
9
|
|
|
9
10
|
const {
|
|
@@ -17,7 +18,9 @@ const {
|
|
|
17
18
|
// const istanbulLibCoverage = require('istanbul-lib-coverage');
|
|
18
19
|
// const istanbulLibReport = require('istanbul-lib-report');
|
|
19
20
|
|
|
20
|
-
const {
|
|
21
|
+
const {
|
|
22
|
+
getSourcePath, mergeSourceRoot, collectSourceMaps
|
|
23
|
+
} = require('../coverage-utils.js');
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
const saveIstanbulReport = (coverageData, fileSources, options) => {
|
|
@@ -74,6 +77,8 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
|
|
|
74
77
|
const htmlReport = istanbulReports.create('html', {});
|
|
75
78
|
htmlReport.execute(context);
|
|
76
79
|
|
|
80
|
+
const htmlPath = Util.relativePath(path.resolve(options.htmlDir, 'index.html'));
|
|
81
|
+
|
|
77
82
|
if (options.lcov) {
|
|
78
83
|
const lcovReport = istanbulReports.create('lcovonly', {});
|
|
79
84
|
lcovReport.execute(context);
|
|
@@ -82,7 +87,12 @@ const saveIstanbulReport = (coverageData, fileSources, options) => {
|
|
|
82
87
|
// add watermarks and color
|
|
83
88
|
const coverageReport = new IstanbulSummary();
|
|
84
89
|
coverageReport.execute(context);
|
|
85
|
-
const report =
|
|
90
|
+
const report = {
|
|
91
|
+
title: options.title,
|
|
92
|
+
htmlPath,
|
|
93
|
+
watermarks: contextOptions.watermarks,
|
|
94
|
+
... coverageReport.getReport()
|
|
95
|
+
};
|
|
86
96
|
|
|
87
97
|
return report;
|
|
88
98
|
};
|
|
@@ -141,9 +151,14 @@ const getConversionSources = (item, fileSources) => {
|
|
|
141
151
|
// 'webpack://monocart-v8/external umd "monocart-code-viewer"'
|
|
142
152
|
// format the url to sourcePath
|
|
143
153
|
|
|
154
|
+
// reset sourceRoot
|
|
155
|
+
const sourceRoot = sourceMap.sourceRoot || '';
|
|
156
|
+
sourceMap.sourceRoot = '';
|
|
157
|
+
|
|
144
158
|
// resolve source path and add to file sources cache for html report sourceFinder
|
|
145
159
|
sourceMap.sources = sourceMap.sources.map((sourceName, i) => {
|
|
146
|
-
const
|
|
160
|
+
const sourceUrl = mergeSourceRoot(sourceRoot, sourceName);
|
|
161
|
+
const newSourceName = getSourcePath(sourceUrl, i + 1);
|
|
147
162
|
fileSources[newSourceName] = sourceMap.sourcesContent[i];
|
|
148
163
|
return newSourceName;
|
|
149
164
|
});
|
|
@@ -29,10 +29,6 @@ class PositionMapping {
|
|
|
29
29
|
this.sourceName = sourceName;
|
|
30
30
|
this.lines = this.getLines(source);
|
|
31
31
|
this.ranges = [];
|
|
32
|
-
this.range = {
|
|
33
|
-
start: 0,
|
|
34
|
-
end: 0
|
|
35
|
-
};
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
// =============================================================================
|