Skip to content

Commit 51e5d3e

Browse files
committed
Example for Playwright Coverage Reports
1 parent e892f93 commit 51e5d3e

12 files changed

+327
-1
lines changed

.eslintrc.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// https://eslint.org/docs/rules/
2+
module.exports = {
3+
'root': true,
4+
// system globals
5+
'env': {
6+
'node': true,
7+
'browser': true,
8+
'amd': true,
9+
'commonjs': true,
10+
'es6': true
11+
},
12+
// other globals
13+
'globals': {
14+
},
15+
16+
'plugins': [
17+
],
18+
19+
'extends': [
20+
'plus'
21+
],
22+
23+
'parserOptions': {
24+
'ecmaVersion': 'latest',
25+
'sourceType': 'module'
26+
},
27+
28+
'rules': {
29+
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn'
30+
}
31+
};

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules/
2+
/test-results/
3+
/playwright-report/
4+
/blob-report/
5+
/playwright/.cache/
6+
7+
/coverage-reports
8+
/package-lock.json

.vscode/settings.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"[typescript]": {
3+
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
4+
},
5+
"[javascript]": {
6+
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
7+
},
8+
"editor.codeActionsOnSave": {
9+
"source.fixAll.eslint": "explicit"
10+
},
11+
"editor.formatOnSave": true,
12+
"eslint.format.enable": true,
13+
"eslint.validate": [
14+
"typescript",
15+
"javascript"
16+
],
17+
"git.ignoreLimitWarning": true
18+
}

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,19 @@
11
# playwright-coverage
2-
Playwright Coverage Reports
2+
Example for Playwright Coverage Reports
3+
4+
## Install
5+
```sh
6+
npm i monocart-coverage-reports -D
7+
```
8+
9+
- Create `autoTestFixture` for collecting coverage data, see [fixtures.ts](fixtures.ts)
10+
- Create [global.setup.ts](global.setup.ts) and [global-teardown.ts](global-teardown.ts) for generating coverage reports
11+
- Set coverage options in config [mcr.config.ts](mcr.config.ts)
12+
- Playwright config [playwright.config.ts](playwright.config.ts)
13+
14+
```sh
15+
npm run test
16+
```
17+
The coverage report will be found here: `coverage-reports/index.html`
18+
19+
Check repo [monocart coverage reports](https://github.com/cenfun/monocart-coverage-reports) for more options.

fixtures.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { test as testBase } from '@playwright/test';
2+
import MCR from 'monocart-coverage-reports';
3+
import coverageOptions from './mcr.config';
4+
5+
// fixtures
6+
const test = testBase.extend({
7+
autoTestFixture: [async ({ page }, use) => {
8+
9+
const isChromium = test.info().project.name === 'chromium';
10+
11+
// console.log('autoTestFixture setup...');
12+
// coverage API is chromium only
13+
if (isChromium) {
14+
await Promise.all([
15+
page.coverage.startJSCoverage({
16+
resetOnNavigation: false
17+
}),
18+
page.coverage.startCSSCoverage({
19+
resetOnNavigation: false
20+
})
21+
]);
22+
}
23+
24+
await use('autoTestFixture');
25+
26+
// console.log('autoTestFixture teardown...');
27+
if (isChromium) {
28+
const [jsCoverage, cssCoverage] = await Promise.all([
29+
page.coverage.stopJSCoverage(),
30+
page.coverage.stopCSSCoverage()
31+
]);
32+
const coverageList = [... jsCoverage, ... cssCoverage];
33+
// console.log(coverageList.map((item) => item.url));
34+
const mcr = MCR(coverageOptions);
35+
await mcr.add(coverageList);
36+
}
37+
38+
}, {
39+
scope: 'test',
40+
auto: true
41+
}]
42+
});
43+
44+
export { test };

global-teardown.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import MCR from 'monocart-coverage-reports';
2+
import coverageOptions from './mcr.config';
3+
4+
async function globalTeardown(config) {
5+
const mcr = MCR(coverageOptions);
6+
await mcr.generate();
7+
}
8+
9+
export default globalTeardown;

global.setup.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import MCR from 'monocart-coverage-reports';
2+
import coverageOptions from './mcr.config';
3+
4+
async function globalSetup(config) {
5+
const mcr = MCR(coverageOptions);
6+
await mcr.cleanCache();
7+
}
8+
9+
export default globalSetup;

mcr.config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default {
2+
3+
name: 'My Playwright Coverage Report',
4+
5+
reports: [
6+
'console-details',
7+
'v8'
8+
],
9+
10+
// entryFilter: {
11+
// '**/node_modules/**': false,
12+
// '**/*.js': true
13+
// },
14+
15+
outputDir: './coverage-reports'
16+
};

package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "playwright-coverage",
3+
"version": "1.0.0",
4+
"description": "Playwright Coverage Reports",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "npx playwright test"
8+
},
9+
"license": "MIT",
10+
"devDependencies": {
11+
"@playwright/test": "^1.42.1",
12+
"@types/node": "^20.11.30",
13+
"eslint": "^8.57.0",
14+
"eslint-config-plus": "^1.0.6",
15+
"monocart-coverage-reports": "^2.7.6"
16+
},
17+
"dependencies": {}
18+
}

playwright.config.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
/**
4+
* Read environment variables from file.
5+
* https://github.com/motdotla/dotenv
6+
*/
7+
// require('dotenv').config();
8+
9+
/**
10+
* See https://playwright.dev/docs/test-configuration.
11+
*/
12+
export default defineConfig({
13+
testDir: './tests',
14+
15+
/* Run tests in files in parallel */
16+
fullyParallel: true,
17+
18+
/* Fail the build on CI if you accidentally left test.only in the source code. */
19+
forbidOnly: Boolean(process.env.CI),
20+
21+
/* Retry on CI only */
22+
retries: process.env.CI ? 2 : 0,
23+
24+
/* Opt out of parallel tests on CI. */
25+
// workers: process.env.CI ? 1 : undefined,
26+
27+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
28+
reporter: 'html',
29+
30+
globalSetup: 'global.setup.ts',
31+
globalTeardown: 'global-teardown.ts',
32+
33+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
34+
use: {
35+
36+
/* Base URL to use in actions like `await page.goto('/')`. */
37+
// baseURL: 'http://127.0.0.1:3000',
38+
39+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
40+
trace: 'on-first-retry'
41+
},
42+
43+
/* Configure projects for major browsers */
44+
projects: [
45+
{
46+
name: 'chromium',
47+
use: {
48+
... devices['Desktop Chrome']
49+
}
50+
},
51+
52+
{
53+
name: 'firefox',
54+
use: {
55+
... devices['Desktop Firefox']
56+
}
57+
},
58+
59+
{
60+
name: 'webkit',
61+
use: {
62+
... devices['Desktop Safari']
63+
}
64+
}
65+
66+
/* Test against mobile viewports. */
67+
// {
68+
// name: 'Mobile Chrome',
69+
// use: { ...devices['Pixel 5'] },
70+
// },
71+
// {
72+
// name: 'Mobile Safari',
73+
// use: { ...devices['iPhone 12'] },
74+
// },
75+
76+
/* Test against branded browsers. */
77+
// {
78+
// name: 'Microsoft Edge',
79+
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
80+
// },
81+
// {
82+
// name: 'Google Chrome',
83+
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
84+
// },
85+
]
86+
87+
/* Run your local dev server before starting the tests */
88+
// webServer: {
89+
// command: 'npm run start',
90+
// url: 'http://127.0.0.1:3000',
91+
// reuseExistingServer: !process.env.CI,
92+
// },
93+
});

tests/demo-todo-app.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { expect } from '@playwright/test';
2+
import { test } from '../fixtures';
3+
4+
test.beforeEach(async ({ page }) => {
5+
await page.goto('https://demo.playwright.dev/todomvc');
6+
});
7+
8+
const TODO_ITEMS = [
9+
'buy some cheese',
10+
'feed the cat',
11+
'book a doctors appointment'
12+
];
13+
14+
test.describe('New Todo', () => {
15+
test('should allow me to add todo items', async ({ page }) => {
16+
// create a new todo locator
17+
const newTodo = page.getByPlaceholder('What needs to be done?');
18+
19+
// Create 1st todo.
20+
await newTodo.fill(TODO_ITEMS[0]);
21+
await newTodo.press('Enter');
22+
23+
// Make sure the list only has one todo item.
24+
await expect(page.getByTestId('todo-title')).toHaveText([
25+
TODO_ITEMS[0]
26+
]);
27+
28+
// Create 2nd todo.
29+
await newTodo.fill(TODO_ITEMS[1]);
30+
await newTodo.press('Enter');
31+
32+
// Make sure the list now has two todo items.
33+
await expect(page.getByTestId('todo-title')).toHaveText([
34+
TODO_ITEMS[0],
35+
TODO_ITEMS[1]
36+
]);
37+
38+
39+
});
40+
41+
test('should clear text input field when an item is added', async ({ page }) => {
42+
// create a new todo locator
43+
const newTodo = page.getByPlaceholder('What needs to be done?');
44+
45+
// Create one todo item.
46+
await newTodo.fill(TODO_ITEMS[0]);
47+
await newTodo.press('Enter');
48+
49+
// Check that input is empty.
50+
await expect(newTodo).toBeEmpty();
51+
52+
});
53+
54+
});

tests/example.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { expect } from '@playwright/test';
2+
import { test } from '../fixtures';
3+
4+
test('has title', async ({ page }) => {
5+
await page.goto('https://playwright.dev/');
6+
7+
// Expect a title "to contain" a substring.
8+
await expect(page).toHaveTitle(/Playwright/);
9+
});

0 commit comments

Comments
 (0)