monocart-reporter 1.6.19 → 1.6.21
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 +123 -63
- package/lib/generate-report.js +2 -2
- package/lib/helper/audit.js +1 -0
- package/lib/helper/network.js +1 -0
- package/lib/merge-data.js +1 -1
- package/lib/runtime/monocart-code-viewer.js +1 -1
- package/lib/runtime/monocart-formatter.js +1 -1
- 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 +2 -2
- package/lib/visitor.js +59 -0
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -17,16 +17,17 @@
|
|
|
17
17
|
* [Install](#install)
|
|
18
18
|
* [Playwright Config](#playwright-config)
|
|
19
19
|
* [Examples](#examples)
|
|
20
|
-
* [Output](#output) HTML
|
|
21
|
-
* [
|
|
20
|
+
* [Output](#output) HTML and JSON
|
|
21
|
+
* [View Trace Online](#view-trace-online)
|
|
22
22
|
* [Reporter Options](#reporter-options)
|
|
23
|
-
* [Custom Columns](#custom-columns) (
|
|
23
|
+
* [Custom Columns](#custom-columns) (Extra properties for suite/case/step)
|
|
24
24
|
- [Custom Formatter](#custom-formatter)
|
|
25
25
|
- [Searchable Fields](#searchable-fields)
|
|
26
|
-
* [Data
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
|
|
26
|
+
* [Custom Data Visitor](#custom-data-visitor) (Extra data collection for suite/case/step)
|
|
27
|
+
- [Collect Data from the Title](#collect-data-from-the-title)
|
|
28
|
+
- [Collect Data from the Annotations](#collect-data-from-the-annotations)
|
|
29
|
+
- [Collect Data from the Comments](#collect-data-from-the-comments) (Recommended)
|
|
30
|
+
- [Remove Secrets and Sensitive Data](#remove-secrets-and-sensitive-data)
|
|
30
31
|
* [Style Tags](#style-tags)
|
|
31
32
|
* [Metadata](#metadata)
|
|
32
33
|
* [Trend Chart](#trend-chart)
|
|
@@ -77,14 +78,12 @@ module.exports = {
|
|
|
77
78
|
Playwright Docs [https://playwright.dev/docs/test-reporters](https://playwright.dev/docs/test-reporters)
|
|
78
79
|
|
|
79
80
|
## Examples
|
|
80
|
-
- [tests
|
|
81
|
-
- [
|
|
82
|
-
- [tests/home-page/home-page.spec.js](/tests/home-page/home-page.spec.js)
|
|
83
|
-
|
|
81
|
+
- [tests](/tests/)
|
|
82
|
+
- [more](https://github.com/cenfun/monocart-reporter-test/tree/main/tests)
|
|
84
83
|
## Output
|
|
85
84
|
- path-to/your-filename.html
|
|
86
85
|
Single HTML file (data compressed), easy to transfer/deploy or open directly anywhere
|
|
87
|
-
> Note:
|
|
86
|
+
> Note: Test attachments (screenshots images/videos) are not included but linked with relative path in report. All attachments will be found in [playwrightConfig.outputDir](https://playwright.dev/docs/api/class-testconfig#test-config-output-dir)
|
|
88
87
|
```js
|
|
89
88
|
// playwright.config.js
|
|
90
89
|
// attachments outputDir and report outputFile used same folder
|
|
@@ -105,7 +104,7 @@ module.exports = {
|
|
|
105
104
|
- path-to/your-filename.json
|
|
106
105
|
Separated metadata file (Already included in the above HTML and compressed, it can be deleted). Can be used for debugging or custom data collection.
|
|
107
106
|
|
|
108
|
-
##
|
|
107
|
+
## View Trace Online
|
|
109
108
|
> 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:
|
|
110
109
|
```sh
|
|
111
110
|
npx monocart show-report <your-outputFile-path>
|
|
@@ -122,7 +121,7 @@ npx monocart show-report <your-outputFile-path>
|
|
|
122
121
|
|
|
123
122
|
// attachment path handler
|
|
124
123
|
attachmentPath: null,
|
|
125
|
-
// attachmentPath: (currentPath, extras) => `https://
|
|
124
|
+
// attachmentPath: (currentPath, extras) => `https://another-path/${currentPath}`,
|
|
126
125
|
|
|
127
126
|
// trend data handler
|
|
128
127
|
trend: null,
|
|
@@ -209,7 +208,7 @@ module.exports = {
|
|
|
209
208
|
};
|
|
210
209
|
```
|
|
211
210
|
### Custom Formatter
|
|
212
|
-
> Note:
|
|
211
|
+
> Note: The `formatter` function will be serialized into string via JSON, so closures, contexts, etc. will not work!
|
|
213
212
|
```js
|
|
214
213
|
// playwright.config.js
|
|
215
214
|
module.exports = {
|
|
@@ -264,14 +263,74 @@ module.exports = {
|
|
|
264
263
|
};
|
|
265
264
|
```
|
|
266
265
|
|
|
267
|
-
## Data
|
|
266
|
+
## Custom Data Visitor
|
|
268
267
|
The `visitor` function will be executed for each row item (suite, case and step). Arguments:
|
|
269
|
-
- `data` data item (suite/case/step) for reporter, you can
|
|
268
|
+
- `data` data item (suite/case/step) for reporter, you can rewrite some of its properties or add more
|
|
270
269
|
- `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)
|
|
271
|
-
- `collect`
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
- `collect` see [collect data from the comments](#collect-data-from-the-comments)
|
|
271
|
+
|
|
272
|
+
### Collect Data from the Title
|
|
273
|
+
For example, we want to parse out the jira key from the title:
|
|
274
|
+
```js
|
|
275
|
+
test('[MCR-123] collect data from the title', () => {
|
|
276
|
+
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
You can simply use regular expressions to parse and get jira key:
|
|
280
|
+
```js
|
|
281
|
+
// playwright.config.js
|
|
282
|
+
module.exports = {
|
|
283
|
+
reporter: [
|
|
284
|
+
['monocart-reporter', {
|
|
285
|
+
name: "My Test Report",
|
|
286
|
+
outputFile: './test-results/report.html',
|
|
287
|
+
visitor: (data, metadata, collect) => {
|
|
288
|
+
// [MCR-123] collect data from the title
|
|
289
|
+
const matchResult = metadata.title.match(/\[(.+)\]/);
|
|
290
|
+
if (matchResult && matchResult[1]) {
|
|
291
|
+
data.jira = matchResult[1];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}]
|
|
295
|
+
]
|
|
296
|
+
};
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Collect Data from the Annotations
|
|
300
|
+
It should be easier than getting from title. see [custom annotations](https://playwright.dev/docs/test-annotations#custom-annotations) via `test.info().annotations`
|
|
301
|
+
```js
|
|
302
|
+
test('collect data from the annotations', () => {
|
|
303
|
+
test.info().annotations.push({
|
|
304
|
+
type: "jira",
|
|
305
|
+
description: "MCR-123"
|
|
306
|
+
})
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
```js
|
|
310
|
+
// playwright.config.js
|
|
311
|
+
module.exports = {
|
|
312
|
+
reporter: [
|
|
313
|
+
['monocart-reporter', {
|
|
314
|
+
name: "My Test Report",
|
|
315
|
+
outputFile: './test-results/report.html',
|
|
316
|
+
visitor: (data, metadata, collect) => {
|
|
317
|
+
// collect data from the annotations
|
|
318
|
+
if (metadata.annotations) {
|
|
319
|
+
const jiraItem = metadata.annotations.find((item) => item.type === 'jira');
|
|
320
|
+
if (jiraItem && jiraItem.description) {
|
|
321
|
+
data.jira = jiraItem.description;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}]
|
|
326
|
+
]
|
|
327
|
+
};
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Collect Data from the Comments
|
|
331
|
+
> The code comments are good enough to provide extra information without breaking existing code, and no dependencies, clean, easy to read, etc.
|
|
332
|
+
- First, add the collection of comments in the visitor.
|
|
333
|
+
> 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.
|
|
275
334
|
```js
|
|
276
335
|
// playwright.config.js
|
|
277
336
|
module.exports = {
|
|
@@ -281,30 +340,37 @@ module.exports = {
|
|
|
281
340
|
outputFile: './test-results/report.html',
|
|
282
341
|
// additional custom visitor for columns
|
|
283
342
|
visitor: (data, metadata, collect) => {
|
|
284
|
-
|
|
343
|
+
|
|
344
|
+
// auto collect data from the comments
|
|
285
345
|
const parserOptions = {
|
|
286
346
|
// Indicate the mode the code should be parsed in.
|
|
287
347
|
// Can be one of "script", "module", or "unambiguous". Defaults to "script".
|
|
288
348
|
// sourceType: 'module',
|
|
289
349
|
|
|
290
|
-
// enable typescript syntax.
|
|
350
|
+
// enable typescript syntax.
|
|
291
351
|
// plugins: ['typescript']
|
|
352
|
+
|
|
353
|
+
// more https://babeljs.io/docs/babel-parser
|
|
292
354
|
};
|
|
293
355
|
const comments = collect.comments(parserOptions);
|
|
294
356
|
if (comments) {
|
|
357
|
+
// Append all collected comments data to report data
|
|
295
358
|
Object.assign(data, comments);
|
|
296
359
|
}
|
|
360
|
+
|
|
297
361
|
}
|
|
298
362
|
}]
|
|
299
363
|
]
|
|
300
364
|
};
|
|
301
365
|
```
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
366
|
+
|
|
367
|
+
- Then, add comments to your tests
|
|
368
|
+
> Note: Each comment item must start with `@` which is similar to [JSDoc](https://jsdoc.app/).
|
|
369
|
+
|
|
370
|
+
For example, we want to add `owner` and `jira` or others for the cases, steps, and suites, or rewrite the step `title`
|
|
305
371
|
```js
|
|
306
372
|
/**
|
|
307
|
-
*
|
|
373
|
+
* for case
|
|
308
374
|
* @owner Kevin
|
|
309
375
|
* @jira MCR-16888
|
|
310
376
|
*/
|
|
@@ -323,23 +389,11 @@ test('case description', () => {
|
|
|
323
389
|
});
|
|
324
390
|
|
|
325
391
|
```
|
|
326
|
-
* Describe
|
|
327
|
-
```js
|
|
328
|
-
/**
|
|
329
|
-
* add extra information for describe
|
|
330
|
-
* @owner Mark
|
|
331
|
-
* @jira MCR-16900
|
|
332
|
-
*/
|
|
333
|
-
test.describe('suite title', () => {
|
|
334
|
-
|
|
335
|
-
});
|
|
336
|
-
```
|
|
337
|
-
* Step
|
|
338
392
|
```js
|
|
339
393
|
test('case title', ({ browserName }, testInfo) => {
|
|
340
394
|
|
|
341
395
|
/**
|
|
342
|
-
*
|
|
396
|
+
* rewrite assert step title "expect.toBe" to
|
|
343
397
|
* @title my custom assert step title
|
|
344
398
|
* @annotations important
|
|
345
399
|
*/
|
|
@@ -351,11 +405,9 @@ test('case title', ({ browserName }, testInfo) => {
|
|
|
351
405
|
});
|
|
352
406
|
|
|
353
407
|
});
|
|
354
|
-
|
|
355
|
-
* Hooks
|
|
356
|
-
```js
|
|
408
|
+
|
|
357
409
|
/**
|
|
358
|
-
*
|
|
410
|
+
* rewrite "beforeAll hook" title to
|
|
359
411
|
* @title do something before all
|
|
360
412
|
*/
|
|
361
413
|
test.beforeAll(() => {
|
|
@@ -363,37 +415,45 @@ test.beforeAll(() => {
|
|
|
363
415
|
});
|
|
364
416
|
|
|
365
417
|
/**
|
|
366
|
-
*
|
|
418
|
+
* rewrite "beforeEach hook" title to
|
|
367
419
|
* @title do something before each
|
|
368
420
|
*/
|
|
369
421
|
test.beforeEach(() => {
|
|
370
422
|
|
|
371
423
|
});
|
|
372
424
|
```
|
|
373
|
-
* File
|
|
374
425
|
```js
|
|
375
426
|
/**
|
|
376
|
-
*
|
|
427
|
+
* for describe
|
|
428
|
+
* @owner Mark
|
|
429
|
+
* @jira MCR-16900
|
|
430
|
+
*/
|
|
431
|
+
test.describe('suite title', () => {
|
|
432
|
+
|
|
433
|
+
});
|
|
434
|
+
```
|
|
435
|
+
```js
|
|
436
|
+
/**
|
|
437
|
+
* for file (comment file in the first line)
|
|
377
438
|
* @owner FO
|
|
378
439
|
*/
|
|
379
440
|
const { test, expect } = require('@playwright/test');
|
|
380
441
|
```
|
|
381
|
-
* Project (Can't use comments but use project `metadata`)
|
|
382
442
|
```js
|
|
443
|
+
// for project (Can't use comments but use project level `metadata`)
|
|
383
444
|
// playwright.config.js
|
|
384
445
|
module.exports = {
|
|
385
|
-
projects: [
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
owner: 'PO'
|
|
390
|
-
}
|
|
446
|
+
projects: [{
|
|
447
|
+
name: 'Desktop Chromium',
|
|
448
|
+
metadata: {
|
|
449
|
+
owner: 'PO'
|
|
391
450
|
}
|
|
392
|
-
]
|
|
451
|
+
}]
|
|
393
452
|
};
|
|
394
453
|
```
|
|
395
|
-
|
|
396
|
-
|
|
454
|
+
|
|
455
|
+
### Remove Secrets and Sensitive Data
|
|
456
|
+
> 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.
|
|
397
457
|
```js
|
|
398
458
|
// playwright.config.js
|
|
399
459
|
module.exports = {
|
|
@@ -464,9 +524,7 @@ module.exports = {
|
|
|
464
524
|
executor: 'Mono',
|
|
465
525
|
|
|
466
526
|
// test home page object model
|
|
467
|
-
url: 'https://www.npmjs.org/package/monocart-reporter'
|
|
468
|
-
// test addInitScript
|
|
469
|
-
clientPath: 'tests/common/client.js'
|
|
527
|
+
url: 'https://www.npmjs.org/package/monocart-reporter'
|
|
470
528
|
},
|
|
471
529
|
reporter: [
|
|
472
530
|
['monocart-reporter', {
|
|
@@ -490,7 +548,7 @@ export default async (config) => {
|
|
|
490
548
|
```
|
|
491
549
|
|
|
492
550
|
## Trend Chart
|
|
493
|
-
> Note:
|
|
551
|
+
> Note: The trend chart requires historical data generally stored in the server database. There is a serverless solution which is connecting and collecting historical trend data from previous report data before test every time.
|
|
494
552
|
- If a report is generated in the same place every time, you can simply connect the data with the report JSON path (the data is not 100% safe if there is any runtime error, the previous output dir will be empty by Playwright but the reporter processing not finish)
|
|
495
553
|
```js
|
|
496
554
|
// playwright.config.js
|
|
@@ -558,6 +616,7 @@ test('attach lighthouse audit report', async () => {
|
|
|
558
616
|
});
|
|
559
617
|
|
|
560
618
|
```
|
|
619
|
+
Preview [Audit HTML Report](https://cenfun.github.io/monocart-reporter/audit-78a0a1cc4420ee9da113/index.html)
|
|
561
620
|
|
|
562
621
|
## Attach Code Coverage Report
|
|
563
622
|
Attach a code coverage report with API `attachCoverageReport(data, testInfo, options)`. Arguments:
|
|
@@ -709,7 +768,7 @@ test.describe('attach network report 1', () => {
|
|
|
709
768
|
});
|
|
710
769
|
});
|
|
711
770
|
```
|
|
712
|
-
Generate
|
|
771
|
+
Generate HAR with [playwright-har](https://github.com/janzaremski/playwright-har)
|
|
713
772
|
```js
|
|
714
773
|
import { test } from '@playwright/test';
|
|
715
774
|
import { attachNetworkReport } from 'monocart-reporter';
|
|
@@ -738,6 +797,7 @@ test('finally, attach HAR', async () => {
|
|
|
738
797
|
await attachNetworkReport(harPath, test.info());
|
|
739
798
|
});
|
|
740
799
|
```
|
|
800
|
+
Preview [Network HTML Report](https://cenfun.github.io/monocart-reporter/network-1a18723ee59b36867898/index.html)
|
|
741
801
|
|
|
742
802
|
## Merge Shard Reports
|
|
743
803
|
There will be multiple reports to be generated if Playwright test executes in sharding mode. for example:
|
|
@@ -747,7 +807,7 @@ npx playwright test --shard=2/3
|
|
|
747
807
|
npx playwright test --shard=3/3
|
|
748
808
|
```
|
|
749
809
|
There are 3 reports will be generated. Using `merge(reportDataList, options)` API to merge all reports into one.
|
|
750
|
-
> Note:
|
|
810
|
+
> Note: One more suite level "shard" will be added, its title will be the machine hostname, and the summary will be restated. You may need to transfer the attachments by yourself and update the path of the attachments with `attachmentPath` API.
|
|
751
811
|
```js
|
|
752
812
|
import { merge } from 'monocart-reporter';
|
|
753
813
|
|
package/lib/generate-report.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const EC = require('eight-colors');
|
|
4
4
|
const CG = require('console-grid');
|
|
5
|
-
const {
|
|
5
|
+
const { deflateSync } = require('lz-utils');
|
|
6
6
|
const { nodemailer } = require('./runtime/monocart-vendor.js');
|
|
7
7
|
const Util = require('./utils/util.js');
|
|
8
8
|
const emailHelper = require('./helper/email.js');
|
|
@@ -28,7 +28,7 @@ const generateHtml = (outputDir, filename, reportData) => {
|
|
|
28
28
|
EC.logRed(errMsg);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const reportDataStr =
|
|
31
|
+
const reportDataStr = deflateSync(JSON.stringify(reportData));
|
|
32
32
|
const content = `<script>\nwindow.reportData = '${reportDataStr}';\n${reportJs}\n</script>`;
|
|
33
33
|
|
|
34
34
|
// replace template
|
package/lib/helper/audit.js
CHANGED
package/lib/helper/network.js
CHANGED
package/lib/merge-data.js
CHANGED
|
@@ -155,7 +155,7 @@ const mergeDataList = async (dataList, options) => {
|
|
|
155
155
|
rows
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
// tag style can be
|
|
158
|
+
// tag style can be rewrite with new options tags
|
|
159
159
|
options.tags = options.tags || mergedData.tags;
|
|
160
160
|
calculateSummary(mergedData, options);
|
|
161
161
|
|