monocart-reporter 2.1.1 → 2.2.1
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 +171 -239
- package/lib/default/options.js +4 -1
- package/lib/generate-report.js +2 -2
- package/lib/index.d.ts +5 -5
- package/lib/packages/monocart-common.js +1 -1
- package/lib/packages/monocart-network.js +1 -1
- package/lib/packages/monocart-reporter-app.js +1 -0
- package/lib/packages/monocart-vendor.js +12 -19
- package/lib/platform/share.js +0 -1
- package/lib/plugins/comments.js +33 -34
- package/lib/visitor.js +6 -7
- package/package.json +7 -6
- package/lib/packages/monocart-reporter.js +0 -1
- package/lib/utils/parse-source.js +0 -19
package/README.md
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/monocart-reporter)
|
|
4
4
|
[](https://www.npmjs.com/package/monocart-reporter)
|
|
5
5
|

|
|
6
|
+

|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
* A [Playwright](https://github.com/microsoft/playwright) Test [Reporter](https://playwright.dev/docs/test-reporters) (Node.js)
|
|
8
10
|
- Shows Test Report in A `Tree Grid`
|
|
@@ -15,29 +17,25 @@
|
|
|
15
17
|
* [Install](#install)
|
|
16
18
|
* [Playwright Config](#playwright-config)
|
|
17
19
|
* [Examples](#examples)
|
|
18
|
-
* [Output](#output)
|
|
20
|
+
* [Output](#output)
|
|
19
21
|
* [Reporter Options](#reporter-options)
|
|
20
22
|
* [View Trace Online](#view-trace-online)
|
|
21
23
|
* [Custom Fields Report](#custom-fields-report)
|
|
22
|
-
* [Custom Columns](#custom-columns)
|
|
24
|
+
* [Custom Columns](#custom-columns)
|
|
23
25
|
- [Column Formatter](#column-formatter)
|
|
24
26
|
- [Searchable Fields](#searchable-fields)
|
|
25
|
-
* [Custom
|
|
27
|
+
* [Custom Fields in Comments](#custom-fields-in-comments)
|
|
28
|
+
* [Custom Data Visitor](#custom-data-visitor)
|
|
26
29
|
- [Collect Data from the Title](#collect-data-from-the-title)
|
|
27
30
|
- [Collect Data from the Annotations](#collect-data-from-the-annotations)
|
|
28
|
-
- [Collect Data from the Comments](#collect-data-from-the-comments) (Recommended)
|
|
29
31
|
- [Remove Secrets and Sensitive Data](#remove-secrets-and-sensitive-data)
|
|
30
32
|
* [Style Tags](#style-tags)
|
|
31
33
|
* [Metadata](#metadata)
|
|
32
34
|
* [Trend Chart](#trend-chart)
|
|
33
35
|
* [Attach Lighthouse Audit Report](#attach-lighthouse-audit-report)
|
|
34
36
|
* [Code Coverage Report](#code-coverage-report)
|
|
35
|
-
- [Coverage Options](#coverage-options)
|
|
36
|
-
- [Istanbul](#istanbul)
|
|
37
|
-
- [V8](#v8)
|
|
38
|
-
- [V8 to Istanbul](#v8-to-istanbul)
|
|
39
|
-
- [Istanbul vs V8](#istanbul-vs-v8)
|
|
40
37
|
- [Global Coverage Report](#global-coverage-report)
|
|
38
|
+
- [Coverage Options](#coverage-options)
|
|
41
39
|
- [Coverage Examples](#coverage-examples)
|
|
42
40
|
* [Attach Network Report](#attach-network-report)
|
|
43
41
|
* [Global State Management](#global-state-management)
|
|
@@ -63,8 +61,6 @@
|
|
|
63
61
|
|
|
64
62
|

|
|
65
63
|
|
|
66
|
-
[More Test Reports](https://github.com/cenfun/monocart-reporter-test)
|
|
67
|
-
|
|
68
64
|
## Install
|
|
69
65
|
```sh
|
|
70
66
|
npm i -D monocart-reporter
|
|
@@ -88,7 +84,8 @@ Playwright Docs [https://playwright.dev/docs/test-reporters](https://playwright.
|
|
|
88
84
|
|
|
89
85
|
## Examples
|
|
90
86
|
- [tests](/tests/)
|
|
91
|
-
- [
|
|
87
|
+
- More Examples [monocart-reporter-examples](https://github.com/cenfun/monocart-reporter-examples)
|
|
88
|
+
|
|
92
89
|
## Output
|
|
93
90
|
- path-to/your-filename.html
|
|
94
91
|
Single HTML file (data compressed), easy to transfer/deploy or open directly anywhere
|
|
@@ -162,7 +159,10 @@ Separated metadata file (Already included in the above HTML and compressed, it c
|
|
|
162
159
|
|
|
163
160
|
// rows data handler (suite, case and step)
|
|
164
161
|
visitor: null,
|
|
165
|
-
// visitor: (data, metadata
|
|
162
|
+
// visitor: (data, metadata) => {},
|
|
163
|
+
|
|
164
|
+
// enable/disable custom fields in comments. Defaults to true.
|
|
165
|
+
customFieldsInComments: true,
|
|
166
166
|
|
|
167
167
|
// onEnd hook
|
|
168
168
|
onEnd: null
|
|
@@ -183,8 +183,8 @@ Or customize your own trace viewer url with option `traceViewerUrl` defaults to
|
|
|
183
183
|
|
|
184
184
|
## Custom Fields Report
|
|
185
185
|
You can add custom fields to the report. for example: Owner, JIRA Key etc.
|
|
186
|
-
- First, you need to add [
|
|
187
|
-
- Then, collect data for these fields with [custom
|
|
186
|
+
- First, you need to add [Custom Columns](#custom-columns) for the fields.
|
|
187
|
+
- Then, collect data for these fields with [Custom Fields in Comments](#custom-fields-in-comments) or [Custom Data Visitor](#custom-data-visitor)
|
|
188
188
|
|
|
189
189
|
### Custom Columns
|
|
190
190
|
The report will be displayed in a `Tree Grid`. The `columns` function is used to customize the grid columns. The column properties following:
|
|
@@ -297,11 +297,97 @@ module.exports = {
|
|
|
297
297
|
};
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
+
### Custom Fields in Comments
|
|
301
|
+
> The code comments are good enough to provide extra information without breaking existing code, and no dependencies, clean, easy to read, etc.
|
|
302
|
+
- First, enable option `customFieldsInComments` to `true`
|
|
303
|
+
```js
|
|
304
|
+
// playwright.config.js
|
|
305
|
+
module.exports = {
|
|
306
|
+
reporter: [
|
|
307
|
+
['monocart-reporter', {
|
|
308
|
+
// enable/disable custom fields in comments. Defaults to true.
|
|
309
|
+
customFieldsInComments: true
|
|
310
|
+
}]
|
|
311
|
+
]
|
|
312
|
+
};
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
- Then, add comments for the tests
|
|
316
|
+
> Note: Each comment item must start with `@` which is similar to [JSDoc](https://jsdoc.app/).
|
|
317
|
+
|
|
318
|
+
For example, adding `owner` and `jira` to the cases, steps, and suites. or updating the value if the field exists like `title`
|
|
319
|
+
```js
|
|
320
|
+
/**
|
|
321
|
+
* for file (comment file in the first line)
|
|
322
|
+
* @owner FO
|
|
323
|
+
*/
|
|
324
|
+
const { test, expect } = require('@playwright/test');
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* for case
|
|
328
|
+
* @owner Kevin
|
|
329
|
+
* @jira MCR-16888
|
|
330
|
+
*/
|
|
331
|
+
test('case title', () => {
|
|
332
|
+
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* @description multiple lines text description
|
|
337
|
+
multiple lines text description
|
|
338
|
+
multiple lines text description
|
|
339
|
+
* @jira MCR-16888
|
|
340
|
+
*/
|
|
341
|
+
test('case description', () => {
|
|
342
|
+
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* for describe suite
|
|
347
|
+
* @owner Mark
|
|
348
|
+
* @jira MCR-16900
|
|
349
|
+
*/
|
|
350
|
+
test.describe('suite title', () => {
|
|
351
|
+
|
|
352
|
+
test('case title', ({ browserName }, testInfo) => {
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* rewrite assert step title "expect.toBe" to
|
|
356
|
+
* @title my custom assert step title
|
|
357
|
+
* @annotations important
|
|
358
|
+
*/
|
|
359
|
+
expect(testInfo).toBe(test.info());
|
|
360
|
+
|
|
361
|
+
// @owner Steve
|
|
362
|
+
await test.step('step title', () => {
|
|
363
|
+
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* rewrite "beforeAll hook" title to
|
|
372
|
+
* @title do something before all
|
|
373
|
+
*/
|
|
374
|
+
test.beforeAll(() => {
|
|
375
|
+
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* rewrite "beforeEach hook" title to
|
|
380
|
+
* @title do something before each
|
|
381
|
+
*/
|
|
382
|
+
test.beforeEach(() => {
|
|
383
|
+
|
|
384
|
+
});
|
|
385
|
+
```
|
|
386
|
+
|
|
300
387
|
### Custom Data Visitor
|
|
301
388
|
The `visitor` function will be executed for each row item (suite, case and step). Arguments:
|
|
302
389
|
- `data` data item (suite/case/step) for reporter, you can rewrite some of its properties or add more
|
|
303
390
|
- `metadata` original data object from Playwright test, could be one of [Suite](https://playwright.dev/docs/api/class-suite), [TestCase](https://playwright.dev/docs/api/class-testcase) or [TestStep](https://playwright.dev/docs/api/class-teststep)
|
|
304
|
-
- `collect` see [collect data from the comments](#collect-data-from-the-comments)
|
|
305
391
|
|
|
306
392
|
#### Collect Data from the Title
|
|
307
393
|
For example, we want to parse out the jira key from the title:
|
|
@@ -318,7 +404,7 @@ module.exports = {
|
|
|
318
404
|
['monocart-reporter', {
|
|
319
405
|
name: "My Test Report",
|
|
320
406
|
outputFile: './test-results/report.html',
|
|
321
|
-
visitor: (data, metadata
|
|
407
|
+
visitor: (data, metadata) => {
|
|
322
408
|
// [MCR-123] collect data from the title
|
|
323
409
|
const matchResult = metadata.title.match(/\[(.+)\]/);
|
|
324
410
|
if (matchResult && matchResult[1]) {
|
|
@@ -329,7 +415,7 @@ module.exports = {
|
|
|
329
415
|
]
|
|
330
416
|
};
|
|
331
417
|
```
|
|
332
|
-
multiple matches example: [collect-data](https://github.com/cenfun/monocart-reporter-
|
|
418
|
+
multiple matches example: [collect-data](https://github.com/cenfun/monocart-reporter-examples/tree/main/tests/collect-data)
|
|
333
419
|
|
|
334
420
|
#### Collect Data from the Annotations
|
|
335
421
|
It should be easier than getting from title. see [custom annotations](https://playwright.dev/docs/test-annotations#custom-annotations) via `test.info().annotations`
|
|
@@ -348,7 +434,7 @@ module.exports = {
|
|
|
348
434
|
['monocart-reporter', {
|
|
349
435
|
name: "My Test Report",
|
|
350
436
|
outputFile: './test-results/report.html',
|
|
351
|
-
visitor: (data, metadata
|
|
437
|
+
visitor: (data, metadata) => {
|
|
352
438
|
// collect data from the annotations
|
|
353
439
|
if (metadata.annotations) {
|
|
354
440
|
const jiraItem = metadata.annotations.find((item) => item.type === 'jira');
|
|
@@ -362,119 +448,6 @@ module.exports = {
|
|
|
362
448
|
};
|
|
363
449
|
```
|
|
364
450
|
|
|
365
|
-
#### Collect Data from the Comments
|
|
366
|
-
> The code comments are good enough to provide extra information without breaking existing code, and no dependencies, clean, easy to read, etc.
|
|
367
|
-
- First, add the collection of comments in the visitor.
|
|
368
|
-
> Note: If there are any parsing error messages in red lines, try other parser options like `sourceType: 'module'` or `plugins: ['typescript']` according to your situation.
|
|
369
|
-
```js
|
|
370
|
-
// playwright.config.js
|
|
371
|
-
module.exports = {
|
|
372
|
-
reporter: [
|
|
373
|
-
['monocart-reporter', {
|
|
374
|
-
name: "My Test Report",
|
|
375
|
-
outputFile: './test-results/report.html',
|
|
376
|
-
// additional custom visitor for columns
|
|
377
|
-
visitor: (data, metadata, collect) => {
|
|
378
|
-
|
|
379
|
-
// auto collect data from the comments
|
|
380
|
-
const parserOptions = {
|
|
381
|
-
// Indicate the mode the code should be parsed in.
|
|
382
|
-
// Can be one of "script", "module", or "unambiguous". Defaults to "script".
|
|
383
|
-
// sourceType: 'module',
|
|
384
|
-
|
|
385
|
-
// enable typescript syntax.
|
|
386
|
-
// plugins: ['typescript']
|
|
387
|
-
|
|
388
|
-
// more https://babeljs.io/docs/babel-parser
|
|
389
|
-
};
|
|
390
|
-
const comments = collect.comments(parserOptions);
|
|
391
|
-
if (comments) {
|
|
392
|
-
// Append all collected comments data to report data
|
|
393
|
-
Object.assign(data, comments);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
}]
|
|
398
|
-
]
|
|
399
|
-
};
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
- Then, add comments to your tests
|
|
403
|
-
> Note: Each comment item must start with `@` which is similar to [JSDoc](https://jsdoc.app/).
|
|
404
|
-
|
|
405
|
-
For example, we want to add `owner` and `jira` or others for the cases, steps, and suites, or rewrite the step `title`
|
|
406
|
-
```js
|
|
407
|
-
/**
|
|
408
|
-
* for case
|
|
409
|
-
* @owner Kevin
|
|
410
|
-
* @jira MCR-16888
|
|
411
|
-
*/
|
|
412
|
-
test('case title', () => {
|
|
413
|
-
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* @description multiple lines text description
|
|
418
|
-
multiple lines text description
|
|
419
|
-
multiple lines text description
|
|
420
|
-
* @jira MCR-16888
|
|
421
|
-
*/
|
|
422
|
-
test('case description', () => {
|
|
423
|
-
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
```
|
|
427
|
-
```js
|
|
428
|
-
test('case title', ({ browserName }, testInfo) => {
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* rewrite assert step title "expect.toBe" to
|
|
432
|
-
* @title my custom assert step title
|
|
433
|
-
* @annotations important
|
|
434
|
-
*/
|
|
435
|
-
expect(testInfo).toBe(test.info());
|
|
436
|
-
|
|
437
|
-
// @owner Steve
|
|
438
|
-
await test.step('step title', () => {
|
|
439
|
-
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* rewrite "beforeAll hook" title to
|
|
446
|
-
* @title do something before all
|
|
447
|
-
*/
|
|
448
|
-
test.beforeAll(() => {
|
|
449
|
-
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* rewrite "beforeEach hook" title to
|
|
454
|
-
* @title do something before each
|
|
455
|
-
*/
|
|
456
|
-
test.beforeEach(() => {
|
|
457
|
-
|
|
458
|
-
});
|
|
459
|
-
```
|
|
460
|
-
```js
|
|
461
|
-
/**
|
|
462
|
-
* for describe
|
|
463
|
-
* @owner Mark
|
|
464
|
-
* @jira MCR-16900
|
|
465
|
-
*/
|
|
466
|
-
test.describe('suite title', () => {
|
|
467
|
-
|
|
468
|
-
});
|
|
469
|
-
```
|
|
470
|
-
```js
|
|
471
|
-
/**
|
|
472
|
-
* for file (comment file in the first line)
|
|
473
|
-
* @owner FO
|
|
474
|
-
*/
|
|
475
|
-
const { test, expect } = require('@playwright/test');
|
|
476
|
-
```
|
|
477
|
-
|
|
478
451
|
#### Remove Secrets and Sensitive Data
|
|
479
452
|
> The report may hosted outside of the organization’s internal boundaries, security becomes a big issue. Any secrets or sensitive data, such as usernames, passwords, tokens and API keys, should be handled with extreme care. The following example is removing the password and token from the report data with the string replacement in `visitor` function.
|
|
480
453
|
```js
|
|
@@ -484,7 +457,7 @@ module.exports = {
|
|
|
484
457
|
['monocart-reporter', {
|
|
485
458
|
name: "My Test Report",
|
|
486
459
|
outputFile: './test-results/report.html',
|
|
487
|
-
visitor: (data, metadata
|
|
460
|
+
visitor: (data, metadata) => {
|
|
488
461
|
const mySecrets = [process.env.PASSWORD, process.env.TOKEN];
|
|
489
462
|
mySecrets.forEach((secret) => {
|
|
490
463
|
// remove from title
|
|
@@ -503,7 +476,7 @@ module.exports = {
|
|
|
503
476
|
]
|
|
504
477
|
};
|
|
505
478
|
```
|
|
506
|
-
see example: [remove-secrets](https://github.com/cenfun/monocart-reporter-
|
|
479
|
+
see example: [remove-secrets](https://github.com/cenfun/monocart-reporter-examples/tree/main/tests/remove-secrets)
|
|
507
480
|
|
|
508
481
|
## Style Tags
|
|
509
482
|
* Add tag to test/describe title ( starts with `@` )
|
|
@@ -643,101 +616,18 @@ test('attach lighthouse audit report', async () => {
|
|
|
643
616
|
|
|
644
617
|
## Code Coverage Report
|
|
645
618
|
The reporter integrates [monocart-coverage-reports](https://github.com/cenfun/monocart-coverage-reports) for coverage reports, there are two APIs:
|
|
646
|
-
- `
|
|
647
|
-
- `data` There are two supported data inputs: [Istanbul](
|
|
619
|
+
- `addCoverageReport(data, testInfo)` Add coverage to global coverage report from a test. see [Global Coverage Report](#global-coverage-report)
|
|
620
|
+
- `data` There are two supported data inputs: [Istanbul](https://github.com/cenfun/monocart-coverage-reports?#collecting-istanbul-coverage-data) (Object) or [V8](https://github.com/cenfun/monocart-coverage-reports?#collecting-v8-coverage-data) (Array)
|
|
648
621
|
- `testInfo` see [TestInfo](https://playwright.dev/docs/api/class-testinfo)
|
|
622
|
+
- `attachCoverageReport(data, testInfo, options)` Attach a coverage report to a test. Arguments:
|
|
623
|
+
- `data` same as above
|
|
624
|
+
- `testInfo` same as above
|
|
649
625
|
- `options` (Object) see [Coverage Options](#coverage-options)
|
|
650
|
-
- `addCoverageReport(data, testInfo)` Add coverage to global coverage report from a test. see [Global Coverage Report](#global-coverage-report)
|
|
651
|
-
|
|
652
|
-
### Coverage Options
|
|
653
|
-
- Default [options](https://github.com/cenfun/monocart-coverage-reports/blob/main/lib/default/options.js)
|
|
654
|
-
- More examples [monocart-coverage-reports](https://github.com/cenfun/monocart-coverage-reports)
|
|
655
|
-
|
|
656
|
-
### [Istanbul](https://github.com/istanbuljs)
|
|
657
|
-
Requires your source code is instrumented. Usually we can use the tool [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) to build instrumenting code. (see example: [webpack.config-istanbul.js](https://github.com/cenfun/monocart-reporter-test/blob/main/packages/coverage/webpack.config-istanbul.js)) The instrumented code will automatically generate coverage data and save it on `window.__coverage__`. The Istanbul HTML report will be generated and attached to the test report as an attachment.
|
|
658
|
-
```js
|
|
659
|
-
import { test, expect } from '@playwright/test';
|
|
660
|
-
import { attachCoverageReport } from 'monocart-reporter';
|
|
661
|
-
|
|
662
|
-
test('Take Istanbul coverage report', async ({ page }) => {
|
|
663
|
-
|
|
664
|
-
await page.goto('http://localhost:8090/coverage/istanbul.html');
|
|
665
|
-
|
|
666
|
-
// delay for mock code execution
|
|
667
|
-
await new Promise((resolve) => {
|
|
668
|
-
setTimeout(resolve, 500);
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
// take Istanbul coverage
|
|
672
|
-
const coverageData = await page.evaluate(() => window.__coverage__);
|
|
673
|
-
await page.close();
|
|
674
|
-
expect(coverageData, 'expect found Istanbul data: __coverage__').toBeTruthy();
|
|
675
|
-
|
|
676
|
-
// coverage report
|
|
677
|
-
const report = await attachCoverageReport(coverageData, test.info(), {
|
|
678
|
-
lcov: true
|
|
679
|
-
});
|
|
680
|
-
console.log(report.summary);
|
|
681
|
-
|
|
682
|
-
});
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
### [V8](https://v8.dev/blog/javascript-code-coverage)
|
|
686
|
-
Simply take coverage data with [class-coverage](https://playwright.dev/docs/api/class-coverage) APIs, so it is [Chromium-based only](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#type-ScriptCoverage), the V8 HTML report will be generated.
|
|
687
|
-
```js
|
|
688
|
-
import { test, expect } from '@playwright/test';
|
|
689
|
-
import { attachCoverageReport } from 'monocart-reporter';
|
|
690
|
-
|
|
691
|
-
test('Take V8 and Istanbul coverage report', async ({ page }) => {
|
|
692
|
-
|
|
693
|
-
await Promise.all([
|
|
694
|
-
page.coverage.startJSCoverage({
|
|
695
|
-
resetOnNavigation: false
|
|
696
|
-
}),
|
|
697
|
-
page.coverage.startCSSCoverage({
|
|
698
|
-
resetOnNavigation: false
|
|
699
|
-
})
|
|
700
|
-
]);
|
|
701
|
-
|
|
702
|
-
await page.goto('http://localhost:8090/coverage/v8.html');
|
|
703
|
-
|
|
704
|
-
// delay for mock code execution
|
|
705
|
-
await new Promise((resolve) => {
|
|
706
|
-
setTimeout(resolve, 500);
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
710
|
-
page.coverage.stopJSCoverage(),
|
|
711
|
-
page.coverage.stopCSSCoverage()
|
|
712
|
-
]);
|
|
713
|
-
await page.close();
|
|
714
|
-
|
|
715
|
-
const coverageList = [... jsCoverage, ... cssCoverage];
|
|
716
|
-
|
|
717
|
-
const v8 = await attachCoverageReport(coverageList, test.info(), {
|
|
718
|
-
|
|
719
|
-
});
|
|
720
|
-
console.log(v8.summary);
|
|
721
|
-
|
|
722
|
-
});
|
|
723
|
-
```
|
|
724
626
|
|
|
725
627
|

|
|
726
628
|
|
|
727
|
-
### V8 to Istanbul
|
|
728
|
-
Take V8 coverage data and convert it to Istanbul's coverage format. The Istanbul HTML report will be generated.
|
|
729
|
-
```js
|
|
730
|
-
const report = await attachCoverageReport(coverageList, test.info(), {
|
|
731
|
-
reports: "html"
|
|
732
|
-
});
|
|
733
|
-
```
|
|
734
|
-
|
|
735
|
-
### Istanbul vs V8
|
|
736
|
-
- [Compare Istanbul, V8 and V8 to Istanbul Reports](https://github.com/cenfun/monocart-coverage-reports#compare-reports)
|
|
737
|
-
- [Compare Istanbul and V8 Workflows](https://github.com/cenfun/monocart-coverage-reports#compare-workflows)
|
|
738
|
-
|
|
739
629
|
### Global Coverage Report
|
|
740
|
-
The global coverage report will
|
|
630
|
+
The global coverage report will merge all coverages into one global report after all the tests are finished.
|
|
741
631
|
- The global coverage options see [Coverage Options](#coverage-options)
|
|
742
632
|
```js
|
|
743
633
|
// playwright.config.js
|
|
@@ -755,15 +645,16 @@ module.exports = {
|
|
|
755
645
|
]
|
|
756
646
|
};
|
|
757
647
|
```
|
|
758
|
-
-
|
|
648
|
+
- Adding coverage data for each test with [automatic fixtures](https://playwright.dev/docs/test-fixtures#automatic-fixtures)
|
|
759
649
|
```js
|
|
760
|
-
// fixtures.js for v8
|
|
650
|
+
// fixtures.js for v8 coverage
|
|
761
651
|
import { test as testBase, expect } from '@playwright/test';
|
|
762
652
|
import { addCoverageReport } from 'monocart-reporter';
|
|
763
653
|
|
|
764
654
|
const test = testBase.extend({
|
|
765
655
|
autoTestFixture: [async ({ page }, use) => {
|
|
766
656
|
|
|
657
|
+
// NOTE: it depends on your project name
|
|
767
658
|
const isChromium = test.info().project.name === 'Desktop Chromium';
|
|
768
659
|
|
|
769
660
|
// console.log('autoTestFixture setup...');
|
|
@@ -799,13 +690,54 @@ const test = testBase.extend({
|
|
|
799
690
|
});
|
|
800
691
|
export { test, expect };
|
|
801
692
|
```
|
|
693
|
+
- Adding server side coverage on global teardown
|
|
694
|
+
> For example, a Node.js web server start at the beginning of the test with the env `NODE_V8_COVERAGE=dir`, the V8 coverage data will be saved to `dir` with calling API `v8.takeCoverage()` manually or terminating server gracefully. On global teardown, reading all from `dir` and adding them to global coverage report. For Node.js, the V8 coverage data requires appending source manually.
|
|
695
|
+
```js
|
|
696
|
+
// global-teardown.js
|
|
697
|
+
import fs from 'fs';
|
|
698
|
+
import path from 'path';
|
|
699
|
+
import { fileURLToPath } from 'url';
|
|
700
|
+
import { addCoverageReport } from 'monocart-reporter';
|
|
701
|
+
|
|
702
|
+
export default async (config) => {
|
|
703
|
+
|
|
704
|
+
const dir = "your-v8-coverage-data-dir";
|
|
705
|
+
|
|
706
|
+
const files = fs.readdirSync(dir);
|
|
707
|
+
for (const filename of files) {
|
|
708
|
+
const content = fs.readFileSync(path.resolve(dir, filename)).toString('utf-8');
|
|
709
|
+
const json = JSON.parse(content);
|
|
710
|
+
let coverageList = json.result;
|
|
711
|
+
coverageList = coverageList.filter((entry) => entry.url && entry.url.startsWith('file:'));
|
|
712
|
+
|
|
713
|
+
// appending source
|
|
714
|
+
coverageList.forEach((entry) => {
|
|
715
|
+
entry.source = fs.readFileSync(fileURLToPath(entry.url)).toString('utf8');
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// there is no test info on teardown, just mock one with required config
|
|
719
|
+
const mockTestInfo = {
|
|
720
|
+
config
|
|
721
|
+
};
|
|
722
|
+
await addCoverageReport(coverageList, mockTestInfo);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
```
|
|
726
|
+
see [Node.js V8 Coverage Report for Server Side](https://github.com/cenfun/monocart-coverage-reports?#nodejs-v8-coverage-report-for-server-side)
|
|
727
|
+
|
|
728
|
+
### Coverage Options
|
|
729
|
+
- Default [options](https://github.com/cenfun/monocart-coverage-reports/blob/main/lib/default/options.js)
|
|
730
|
+
- [Available Reports](https://github.com/cenfun/monocart-coverage-reports?#available-reports)
|
|
731
|
+
- [Using entryFilter and sourceFilter to filter the results for V8 report](https://github.com/cenfun/monocart-coverage-reports?#using-entryfilter-and-sourcefilter-to-filter-the-results-for-v8-report)
|
|
732
|
+
- Checking thresholds with [onEnd Hook](https://github.com/cenfun/monocart-coverage-reports?#onend-hook)
|
|
733
|
+
- More Introduction [monocart-coverage-reports](https://github.com/cenfun/monocart-coverage-reports)
|
|
802
734
|
|
|
803
735
|
### Coverage Examples
|
|
804
736
|
- For Playwright component testing:
|
|
805
737
|
- [playwright-ct-vue](https://github.com/cenfun/playwright-ct-vue)
|
|
806
738
|
- [playwright-ct-react](https://github.com/cenfun/playwright-ct-react)
|
|
807
739
|
- [playwright-ct-svelte](https://github.com/cenfun/playwright-ct-svelte)
|
|
808
|
-
- [
|
|
740
|
+
- [nextjs-with-playwright](https://github.com/cenfun/nextjs-with-playwright)
|
|
809
741
|
- [code-coverage-with-monocart-reporter](https://github.com/edumserrano/playwright-adventures/blob/main/demos/code-coverage-with-monocart-reporter/)
|
|
810
742
|
|
|
811
743
|
## Attach Network Report
|
|
@@ -975,7 +907,7 @@ module.exports = {
|
|
|
975
907
|
]
|
|
976
908
|
};
|
|
977
909
|
```
|
|
978
|
-
see example: [Allow specified test cases to run in sequence mode with lock/unlock state](https://github.com/cenfun/monocart-reporter-
|
|
910
|
+
see example: [Allow specified test cases to run in sequence mode with lock/unlock state](https://github.com/cenfun/monocart-reporter-examples/tree/main/tests/global-state)
|
|
979
911
|
|
|
980
912
|
## Merge Shard Reports
|
|
981
913
|
There will be multiple reports to be generated if Playwright test executes in sharding mode. for example:
|
|
@@ -1008,7 +940,7 @@ await merge(reportDataList, {
|
|
|
1008
940
|
}
|
|
1009
941
|
});
|
|
1010
942
|
```
|
|
1011
|
-
|
|
943
|
+
see example [merge.js](https://github.com/cenfun/monocart-reporter-examples/blob/main/scripts/merge.js)
|
|
1012
944
|
|
|
1013
945
|
## onEnd Hook
|
|
1014
946
|
The `onEnd` function will be executed after report generated. Arguments:
|
|
@@ -1048,39 +980,39 @@ module.exports = {
|
|
|
1048
980
|
```
|
|
1049
981
|
## Send Email
|
|
1050
982
|
- Simply send email with [nodemailer](https://nodemailer.com)
|
|
1051
|
-
- Example: [send-email](https://github.com/cenfun/monocart-reporter-
|
|
983
|
+
- Example: [send-email](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/send-email)
|
|
1052
984
|
|
|
1053
985
|
## Testrail Integration
|
|
1054
986
|
- Send test results to your [Testrail](https://www.testrail.com/)
|
|
1055
|
-
- Example: [testrail](https://github.com/cenfun/monocart-reporter-
|
|
987
|
+
- Example: [testrail](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/testrail)
|
|
1056
988
|
|
|
1057
989
|
## Jira + Zephyr Scale Integration
|
|
1058
990
|
- Create test cycle and executions with [zephyr-scale-api](https://support.smartbear.com/zephyr-scale-cloud/api-docs/)
|
|
1059
|
-
- Example: [zephyr-scale](https://github.com/cenfun/monocart-reporter-
|
|
991
|
+
- Example: [zephyr-scale](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/zephyr-scale)
|
|
1060
992
|
|
|
1061
993
|
## Jira + Xray Integration
|
|
1062
994
|
- Import test execution results with [Xray REST API](https://docs.getxray.app/display/XRAYCLOUD/REST+API)
|
|
1063
995
|
- 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)
|
|
1064
|
-
- Example: [xray](https://github.com/cenfun/monocart-reporter-
|
|
996
|
+
- Example: [xray](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/xray)
|
|
1065
997
|
|
|
1066
998
|
## Slack Integration
|
|
1067
999
|
- Simply send message with [@slack/webhook](https://github.com/slackapi/node-slack-sdk)
|
|
1068
|
-
- Example: [slack-webhook](https://github.com/cenfun/monocart-reporter-
|
|
1000
|
+
- Example: [slack-webhook](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/slack-webhook)
|
|
1069
1001
|
- Post chat message and upload image with [@slack/web-api](https://github.com/slackapi/node-slack-sdk)
|
|
1070
|
-
- Example: [slack-web-api](https://github.com/cenfun/monocart-reporter-
|
|
1002
|
+
- Example: [slack-web-api](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/slack-web-api)
|
|
1071
1003
|
|
|
1072
1004
|
## Discord Integration
|
|
1073
1005
|
- Using [Discord webhooks](https://discord.com/developers/docs/resources/webhook) to post messages to channels.
|
|
1074
|
-
- Example: [discord-webhook](https://github.com/cenfun/monocart-reporter-
|
|
1006
|
+
- Example: [discord-webhook](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/discord-webhook)
|
|
1075
1007
|
|
|
1076
1008
|
## Teams Integration
|
|
1077
1009
|
- 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.
|
|
1078
|
-
- Example: [teams-webhook](https://github.com/cenfun/monocart-reporter-
|
|
1010
|
+
- Example: [teams-webhook](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/teams-webhook)
|
|
1079
1011
|
|
|
1080
1012
|
## Dingtalk/Weixin/Feishu Integration
|
|
1081
|
-
- [dingtalk-webhook](https://github.com/cenfun/monocart-reporter-
|
|
1082
|
-
- [weixin-webhook](https://github.com/cenfun/monocart-reporter-
|
|
1083
|
-
- [feishu-webhook](https://github.com/cenfun/monocart-reporter-
|
|
1013
|
+
- [dingtalk-webhook](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/dingtalk-webhook)
|
|
1014
|
+
- [weixin-webhook](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/weixin-webhook)
|
|
1015
|
+
- [feishu-webhook](https://github.com/cenfun/monocart-reporter-examples/tree/main/integrations/feishu-webhook)
|
|
1084
1016
|
|
|
1085
1017
|
|
|
1086
1018
|
## Contributing
|
package/lib/default/options.js
CHANGED
|
@@ -47,7 +47,10 @@ module.exports = {
|
|
|
47
47
|
|
|
48
48
|
// rows data handler (suite, case and step)
|
|
49
49
|
visitor: null,
|
|
50
|
-
// visitor: (data, metadata
|
|
50
|
+
// visitor: (data, metadata) => {},
|
|
51
|
+
|
|
52
|
+
// enable/disable custom fields in comments. Defaults to true.
|
|
53
|
+
customFieldsInComments: true,
|
|
51
54
|
|
|
52
55
|
// onEnd hook
|
|
53
56
|
onEnd: null
|
package/lib/generate-report.js
CHANGED
|
@@ -22,7 +22,7 @@ const generateHtml = async (outputDir, htmlFile, reportData, inline) => {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
jsFiles.push(Util.resolvePackage('monocart-common.js'));
|
|
25
|
-
jsFiles.push(Util.resolvePackage('monocart-reporter.js'));
|
|
25
|
+
jsFiles.push(Util.resolvePackage('monocart-reporter-app.js'));
|
|
26
26
|
|
|
27
27
|
const options = {
|
|
28
28
|
inline,
|
|
@@ -51,7 +51,7 @@ const sendEmail = (emailOptions) => {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
const showTestResults = (reportData) => {
|
|
54
|
-
Util.logInfo(
|
|
54
|
+
Util.logInfo(EC.cyan(reportData.name));
|
|
55
55
|
|
|
56
56
|
const summary = reportData.summary;
|
|
57
57
|
|
package/lib/index.d.ts
CHANGED
|
@@ -59,11 +59,11 @@ export type MonocartReporterOptions = {
|
|
|
59
59
|
// columns: (defaultColumns) => {},
|
|
60
60
|
|
|
61
61
|
// rows data handler (suite, case and step)
|
|
62
|
-
visitor?: (data: any, metadata: any
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
visitor?: (data: any, metadata: any) => void,
|
|
63
|
+
// visitor: (data, metadata) => {},
|
|
64
|
+
|
|
65
|
+
// enable/disable custom fields in comments. Defaults to true.
|
|
66
|
+
customFieldsInComments?: boolean,
|
|
67
67
|
|
|
68
68
|
// onEnd hook
|
|
69
69
|
onEnd?: (reportData: object, capability: {
|