playwright-checkpoint 0.1.0-beta.0
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/LICENSE +21 -0
- package/README.md +665 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-F5A6XGLJ.js +104 -0
- package/dist/chunk-F5A6XGLJ.js.map +1 -0
- package/dist/chunk-K5DX32TO.js +214 -0
- package/dist/chunk-K5DX32TO.js.map +1 -0
- package/dist/chunk-KG37WSYS.js +1549 -0
- package/dist/chunk-KG37WSYS.js.map +1 -0
- package/dist/chunk-X5IPL32H.js +1484 -0
- package/dist/chunk-X5IPL32H.js.map +1 -0
- package/dist/cli/bin.cjs +3972 -0
- package/dist/cli/bin.cjs.map +1 -0
- package/dist/cli/bin.d.cts +1 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +43 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/index.cjs +1672 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +31 -0
- package/dist/cli/index.d.ts +31 -0
- package/dist/cli/index.js +17 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp-args.cjs +129 -0
- package/dist/cli/mcp-args.cjs.map +1 -0
- package/dist/cli/mcp-args.d.cts +32 -0
- package/dist/cli/mcp-args.d.ts +32 -0
- package/dist/cli/mcp-args.js +10 -0
- package/dist/cli/mcp-args.js.map +1 -0
- package/dist/components.cjs +53 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.d.cts +27 -0
- package/dist/components.d.ts +27 -0
- package/dist/components.js +26 -0
- package/dist/components.js.map +1 -0
- package/dist/core-CD4jHGgI.d.cts +51 -0
- package/dist/core-CZvnc0rE.d.ts +51 -0
- package/dist/core.cjs +1576 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +3 -0
- package/dist/core.d.ts +3 -0
- package/dist/core.js +32 -0
- package/dist/core.js.map +1 -0
- package/dist/index-BjYQX_hK.d.ts +8 -0
- package/dist/index-Cabk31qi.d.cts +8 -0
- package/dist/index.cjs +3318 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +94 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +285 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.cjs +3467 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +26 -0
- package/dist/mcp/index.d.ts +26 -0
- package/dist/mcp/index.js +586 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/teardown.cjs +1509 -0
- package/dist/teardown.cjs.map +1 -0
- package/dist/teardown.d.cts +5 -0
- package/dist/teardown.d.ts +5 -0
- package/dist/teardown.js +52 -0
- package/dist/teardown.js.map +1 -0
- package/dist/types-G7w4n8kR.d.cts +359 -0
- package/dist/types-G7w4n8kR.d.ts +359 -0
- package/package.json +109 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pm990320
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
# playwright-checkpoint
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/playwright-checkpoint)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
Structured page checkpoints for Playwright: screenshots, HTML snapshots, accessibility, web vitals, console/network errors, metadata, and post-run report generation.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -D playwright-checkpoint @playwright/test
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Use the built-in fixtures right away:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { test, expect } from 'playwright-checkpoint';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Add the drop-in HTML report teardown:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// playwright.config.ts
|
|
27
|
+
import { defineConfig } from '@playwright/test';
|
|
28
|
+
|
|
29
|
+
export default defineConfig({
|
|
30
|
+
globalTeardown: 'playwright-checkpoint/teardown',
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Example test:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { test, expect } from 'playwright-checkpoint';
|
|
38
|
+
|
|
39
|
+
test('sign in', async ({ page, checkpoint }) => {
|
|
40
|
+
await page.goto('https://example.com/login');
|
|
41
|
+
await checkpoint('Login page', {
|
|
42
|
+
description: 'Open the login page and verify the sign-in form is visible.',
|
|
43
|
+
step: 1,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await page.getByLabel('Email').fill('ada@example.com');
|
|
47
|
+
await page.getByLabel('Password').fill('correct horse battery staple');
|
|
48
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
49
|
+
|
|
50
|
+
await expect(page).toHaveURL(/dashboard/);
|
|
51
|
+
await checkpoint('Signed in dashboard', {
|
|
52
|
+
description: 'Submit valid credentials and confirm the dashboard loads.',
|
|
53
|
+
step: 2,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
After the run, checkpoint manifests are written into Playwright's `test-results` output tree and the default teardown generates an HTML report into `./report`.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## What it captures
|
|
63
|
+
|
|
64
|
+
All built-in collectors are registered automatically.
|
|
65
|
+
|
|
66
|
+
| Collector | Default | What it captures | Main artifact |
|
|
67
|
+
| --- | --- | --- | --- |
|
|
68
|
+
| `screenshot` | On | PNG screenshot for each checkpoint | `page.png` |
|
|
69
|
+
| `html` | On | Full page HTML at checkpoint time | `page.html` |
|
|
70
|
+
| `axe` | On | Accessibility audit via `@axe-core/playwright` when available | `axe.json` |
|
|
71
|
+
| `web-vitals` | On | CLS, FCP, LCP, INP, TTFB and related navigation timings | `web-vitals.json` |
|
|
72
|
+
| `console` | On | New console errors and page errors since the last checkpoint | `console-errors.json` |
|
|
73
|
+
| `network` | On | Failed requests and HTTP 4xx/5xx responses since the last checkpoint | `failed-requests.json` |
|
|
74
|
+
| `metadata` | On | Title, description, canonical URL, OG tags, language, viewport, JSON-LD | `metadata.json` |
|
|
75
|
+
| `aria-snapshot` | Off | Accessibility tree snapshot for machine-readable a11y state | `aria-snapshot.json` |
|
|
76
|
+
| `dom-stats` | Off | DOM size/depth and element counts | `dom-stats.json` |
|
|
77
|
+
| `forms` | Off | Visible form field state with configurable redaction | `form-state.json` |
|
|
78
|
+
| `storage` | Off | Cookie metadata and localStorage key/value state (optional values) | `storage-state.json` |
|
|
79
|
+
| `network-timing` | Off | Incremental response timing and transfer size breakdown | `network-timing.json` |
|
|
80
|
+
|
|
81
|
+
Notes:
|
|
82
|
+
|
|
83
|
+
- `@axe-core/playwright` is an optional dependency. If it is unavailable, the `axe` collector skips gracefully.
|
|
84
|
+
- Screenshot options such as `fullPage` and `highlightSelector` are passed per checkpoint.
|
|
85
|
+
- Extended collectors (`aria-snapshot`, `dom-stats`, `forms`, `storage`, `network-timing`) are opt-in by default.
|
|
86
|
+
- Collector artifacts are also attached to the Playwright test result when possible.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
### 1. Global configuration with `createCheckpoint()`
|
|
93
|
+
|
|
94
|
+
Use `createCheckpoint()` when you want project-wide defaults or custom collectors.
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { createCheckpoint, expect } from 'playwright-checkpoint';
|
|
98
|
+
|
|
99
|
+
export const { test } = createCheckpoint({
|
|
100
|
+
collectors: {
|
|
101
|
+
axe: { timeoutMs: 10_000 },
|
|
102
|
+
network: true,
|
|
103
|
+
console: true,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export { expect };
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`createCheckpoint()` returns a Playwright `test` object extended with these fixtures:
|
|
111
|
+
|
|
112
|
+
- `checkpoint(name, options?)`
|
|
113
|
+
- `checkpointManifest`
|
|
114
|
+
- `testCheckpointConfig`
|
|
115
|
+
- `deviceProfile`
|
|
116
|
+
|
|
117
|
+
### 2. Per-test configuration with `testCheckpointConfig`
|
|
118
|
+
|
|
119
|
+
Override defaults inside a single test or in a `beforeEach`.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { createCheckpoint, expect } from 'playwright-checkpoint';
|
|
123
|
+
|
|
124
|
+
const { test } = createCheckpoint();
|
|
125
|
+
|
|
126
|
+
test('checkout on mobile', async ({ page, checkpoint, testCheckpointConfig }) => {
|
|
127
|
+
testCheckpointConfig.set({
|
|
128
|
+
description: 'Mobile checkout happy path.',
|
|
129
|
+
collectors: {
|
|
130
|
+
'web-vitals': true,
|
|
131
|
+
axe: { timeoutMs: 15_000 },
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
await page.goto('https://example.com/checkout');
|
|
136
|
+
await checkpoint('Cart review');
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The per-test config merges onto global config. Collector overrides resolve in this order:
|
|
141
|
+
|
|
142
|
+
1. Global defaults from `createCheckpoint()`
|
|
143
|
+
2. Per-test config from `testCheckpointConfig.set()`
|
|
144
|
+
3. Per-checkpoint options from `checkpoint(name, options)`
|
|
145
|
+
|
|
146
|
+
### 3. Per-checkpoint options
|
|
147
|
+
|
|
148
|
+
Actual supported checkpoint-level options are:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
await checkpoint('Review order', {
|
|
152
|
+
description: 'Review the order summary before placing the order.',
|
|
153
|
+
step: 3,
|
|
154
|
+
fullPage: true,
|
|
155
|
+
highlightSelector: '[data-testid="order-summary"]',
|
|
156
|
+
collectors: {
|
|
157
|
+
axe: false,
|
|
158
|
+
screenshot: true,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Available checkpoint options:
|
|
164
|
+
|
|
165
|
+
- `description?: string`
|
|
166
|
+
- `step?: number`
|
|
167
|
+
- `fullPage?: boolean`
|
|
168
|
+
- `highlightSelector?: string`
|
|
169
|
+
- `collectors?: Partial<Record<string, boolean | CollectorOptions>>`
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Custom collectors
|
|
174
|
+
|
|
175
|
+
A collector implements `CheckpointCollector` and returns structured data, artifacts, and a summary.
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import fs from 'node:fs/promises';
|
|
179
|
+
import path from 'node:path';
|
|
180
|
+
import { createCheckpoint, type CheckpointCollector } from 'playwright-checkpoint';
|
|
181
|
+
|
|
182
|
+
const urlCollector: CheckpointCollector = {
|
|
183
|
+
name: 'url-fragment',
|
|
184
|
+
defaultEnabled: true,
|
|
185
|
+
|
|
186
|
+
async collect(ctx) {
|
|
187
|
+
const outputPath = path.join(ctx.checkpointDir, 'url-fragment.json');
|
|
188
|
+
const data = {
|
|
189
|
+
href: ctx.page.url(),
|
|
190
|
+
checkpoint: ctx.checkpointName,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
data,
|
|
197
|
+
artifacts: [
|
|
198
|
+
{
|
|
199
|
+
name: 'url-fragment',
|
|
200
|
+
path: outputPath,
|
|
201
|
+
contentType: 'application/json',
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
summary: {
|
|
205
|
+
href: data.href,
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export const { test } = createCheckpoint({
|
|
212
|
+
custom: [urlCollector],
|
|
213
|
+
collectors: {
|
|
214
|
+
'url-fragment': true,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
You can also register built-ins or shared collectors explicitly:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { registerBuiltinCollector } from 'playwright-checkpoint';
|
|
223
|
+
|
|
224
|
+
registerBuiltinCollector(urlCollector);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Report generation
|
|
230
|
+
|
|
231
|
+
There are three report-generation paths.
|
|
232
|
+
|
|
233
|
+
### 1. Drop-in global teardown
|
|
234
|
+
|
|
235
|
+
For the default HTML report only:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
export default defineConfig({
|
|
239
|
+
globalTeardown: 'playwright-checkpoint/teardown',
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
That entry point:
|
|
244
|
+
|
|
245
|
+
- loads manifests from `./test-results` by default
|
|
246
|
+
- writes reports to `./report` by default
|
|
247
|
+
- enables the built-in HTML reporter
|
|
248
|
+
- logs results to the console
|
|
249
|
+
- never crashes Playwright teardown on report errors
|
|
250
|
+
|
|
251
|
+
Optional environment overrides:
|
|
252
|
+
|
|
253
|
+
- `PLAYWRIGHT_CHECKPOINT_RESULTS_DIR`
|
|
254
|
+
- `PLAYWRIGHT_CHECKPOINT_REPORT_DIR`
|
|
255
|
+
|
|
256
|
+
### 2. CLI
|
|
257
|
+
|
|
258
|
+
Generate reports after a run:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
npx playwright-checkpoint report
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Custom directories:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
npx playwright-checkpoint report \
|
|
268
|
+
--results-dir ./test-results \
|
|
269
|
+
--output-dir ./report
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Choose reporters explicitly:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
npx playwright-checkpoint report --reporter html,markdown
|
|
276
|
+
npx playwright-checkpoint report --reporter markdown --output-dir ./docs/help
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 3. Programmatic API
|
|
280
|
+
|
|
281
|
+
Use `runReporters()` when you want markdown articles, custom reporters, or advanced config.
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { runReporters } from 'playwright-checkpoint';
|
|
285
|
+
|
|
286
|
+
await runReporters(
|
|
287
|
+
{
|
|
288
|
+
reporters: {
|
|
289
|
+
html: true,
|
|
290
|
+
markdown: {
|
|
291
|
+
frontmatter: true,
|
|
292
|
+
includeTags: ['@user-journey'],
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
'./test-results',
|
|
297
|
+
'./report',
|
|
298
|
+
);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Built-in reporters
|
|
304
|
+
|
|
305
|
+
### HTML report
|
|
306
|
+
|
|
307
|
+
- Enabled by default in `runReporters()`.
|
|
308
|
+
- Enabled by the drop-in teardown.
|
|
309
|
+
- Writes `index.html` into the chosen output directory.
|
|
310
|
+
- Groups runs by story and shows checkpoint artifacts, summaries, and per-project runs.
|
|
311
|
+
|
|
312
|
+
### Markdown article generator
|
|
313
|
+
|
|
314
|
+
- Reporter name: `markdown`
|
|
315
|
+
- Default: disabled
|
|
316
|
+
- Output: one Markdown file per story/test
|
|
317
|
+
- Copies screenshot assets into the report output folder by default
|
|
318
|
+
|
|
319
|
+
Supported markdown reporter config:
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
{
|
|
323
|
+
reporters: {
|
|
324
|
+
markdown: {
|
|
325
|
+
storiesDir: '.',
|
|
326
|
+
screenshotsDir: 'screenshots',
|
|
327
|
+
includeTags: ['@user-journey'],
|
|
328
|
+
preferredProject: 'desktop-light',
|
|
329
|
+
header: 'Intro copy shown before the steps.',
|
|
330
|
+
footer: 'Outro copy shown after the steps.',
|
|
331
|
+
frontmatter: true,
|
|
332
|
+
imagePathPrefix: '/static/help',
|
|
333
|
+
copyScreenshots: true,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Behavior:
|
|
340
|
+
|
|
341
|
+
- Generates one article per story/test title
|
|
342
|
+
- Strips `@tags` from the article title and filename
|
|
343
|
+
- Orders steps by explicit `step`, then capture order
|
|
344
|
+
- Uses `description` when present
|
|
345
|
+
- Falls back to an auto-generated sentence from page title + URL
|
|
346
|
+
- Includes URL and breadcrumb text for each step
|
|
347
|
+
- Only includes stories that either:
|
|
348
|
+
- have at least one checkpoint with `description` or `step`, or
|
|
349
|
+
- match `includeTags`
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Custom reporters
|
|
354
|
+
|
|
355
|
+
A custom reporter implements `ReportGenerator`.
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
import fs from 'node:fs/promises';
|
|
359
|
+
import path from 'node:path';
|
|
360
|
+
import {
|
|
361
|
+
registerBuiltinReporter,
|
|
362
|
+
type ReportGenerator,
|
|
363
|
+
} from 'playwright-checkpoint';
|
|
364
|
+
|
|
365
|
+
const jsonSummaryReporter: ReportGenerator = {
|
|
366
|
+
name: 'json-summary',
|
|
367
|
+
|
|
368
|
+
validateConfig(config) {
|
|
369
|
+
return config != null && typeof config === 'object' && !Array.isArray(config);
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
async generate(context) {
|
|
373
|
+
const outputPath = path.join(context.outputDir, 'summary.json');
|
|
374
|
+
await fs.mkdir(context.outputDir, { recursive: true });
|
|
375
|
+
await fs.writeFile(
|
|
376
|
+
outputPath,
|
|
377
|
+
`${JSON.stringify(
|
|
378
|
+
{
|
|
379
|
+
runCount: context.runs.length,
|
|
380
|
+
manifests: context.manifests.length,
|
|
381
|
+
},
|
|
382
|
+
null,
|
|
383
|
+
2,
|
|
384
|
+
)}\n`,
|
|
385
|
+
'utf8',
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
return {
|
|
389
|
+
files: [outputPath],
|
|
390
|
+
summary: `Generated JSON summary for ${context.runs.length} runs.`,
|
|
391
|
+
};
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
registerBuiltinReporter(jsonSummaryReporter);
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Then run it programmatically or via the CLI:
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
await runReporters(
|
|
402
|
+
{
|
|
403
|
+
reporters: {
|
|
404
|
+
html: false,
|
|
405
|
+
'json-summary': {},
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
'./test-results',
|
|
409
|
+
'./report',
|
|
410
|
+
);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Help article generation
|
|
416
|
+
|
|
417
|
+
Markdown articles work best when your checkpoints are annotated.
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
await checkpoint('Navigate to the login page', {
|
|
421
|
+
step: 1,
|
|
422
|
+
description: 'Open the login page and confirm the email/password fields are visible.',
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
await checkpoint('Enter credentials and sign in', {
|
|
426
|
+
step: 2,
|
|
427
|
+
description: 'Fill in valid credentials and submit the form.',
|
|
428
|
+
});
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Generate articles from the CLI:
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
npx playwright-checkpoint report --reporter markdown --output-dir ./docs/help
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Only include tests tagged for docs:
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
await runReporters(
|
|
441
|
+
{
|
|
442
|
+
reporters: {
|
|
443
|
+
html: false,
|
|
444
|
+
markdown: {
|
|
445
|
+
includeTags: ['@user-journey'],
|
|
446
|
+
frontmatter: true,
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
'./test-results',
|
|
451
|
+
'./docs/help',
|
|
452
|
+
);
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Example output shape:
|
|
456
|
+
|
|
457
|
+
```md
|
|
458
|
+
# Sign in to your account
|
|
459
|
+
|
|
460
|
+
## Step 1: Navigate to the login page
|
|
461
|
+
|
|
462
|
+

|
|
463
|
+
|
|
464
|
+
**URL:** `/login`
|
|
465
|
+
|
|
466
|
+
**Breadcrumb:** login
|
|
467
|
+
|
|
468
|
+
Open the login page and confirm the email/password fields are visible.
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## CLI reference
|
|
474
|
+
|
|
475
|
+
### `playwright-checkpoint report`
|
|
476
|
+
|
|
477
|
+
Generate reports from checkpoint manifests.
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
playwright-checkpoint report [--results-dir ./test-results] [--output-dir ./report] [--reporter html,markdown]
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Flags:
|
|
484
|
+
|
|
485
|
+
- `--results-dir <path>`: directory containing checkpoint manifests
|
|
486
|
+
- `--output-dir <path>`: destination directory for generated reports
|
|
487
|
+
- `--reporter <names>`: comma-separated reporter list
|
|
488
|
+
- `-h`, `--help`: usage help
|
|
489
|
+
|
|
490
|
+
Defaults:
|
|
491
|
+
|
|
492
|
+
- `resultsDir = ./test-results`
|
|
493
|
+
- `outputDir = ./report`
|
|
494
|
+
- `reporters = html`
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## API reference
|
|
499
|
+
|
|
500
|
+
### Main runtime exports
|
|
501
|
+
|
|
502
|
+
From `playwright-checkpoint`:
|
|
503
|
+
|
|
504
|
+
- `test` — default Playwright test fixture set with checkpoint support
|
|
505
|
+
- `expect` — re-export from `@playwright/test`
|
|
506
|
+
- `createCheckpoint(config?)`
|
|
507
|
+
- `createDeviceProfile(testInfo)`
|
|
508
|
+
- `settlePage(page)`
|
|
509
|
+
|
|
510
|
+
### Checkpoint helpers
|
|
511
|
+
|
|
512
|
+
Also exported for advanced use:
|
|
513
|
+
|
|
514
|
+
- `manifestTags(testInfo)`
|
|
515
|
+
- `checkpointSlug(name, existing)`
|
|
516
|
+
- `collectPageTitle(page)`
|
|
517
|
+
- `resolveCollectors(globalConfig, testConfig, checkpointOptions)`
|
|
518
|
+
- `createCheckpointManifestRecord(testInfo)`
|
|
519
|
+
- `writeCheckpointManifest(testInfo, manifest)`
|
|
520
|
+
- `captureCheckpointRecord(args)`
|
|
521
|
+
- `runCollectorSetup(collectors, page, testInfo)`
|
|
522
|
+
- `runCollectorTeardown(collectors, page, testInfo)`
|
|
523
|
+
- `sanitizeSegment(value)`
|
|
524
|
+
- `warn(message, error?)`
|
|
525
|
+
|
|
526
|
+
### Built-in collectors
|
|
527
|
+
|
|
528
|
+
Exported collector instances:
|
|
529
|
+
|
|
530
|
+
- `screenshotCollector`
|
|
531
|
+
- `htmlCollector`
|
|
532
|
+
- `axeCollector`
|
|
533
|
+
- `webVitalsCollector`
|
|
534
|
+
- `consoleCollector`
|
|
535
|
+
- `networkCollector`
|
|
536
|
+
- `metadataCollector`
|
|
537
|
+
- `ariaSnapshotCollector`
|
|
538
|
+
- `domStatsCollector`
|
|
539
|
+
- `formsCollector`
|
|
540
|
+
- `storageCollector`
|
|
541
|
+
- `networkTimingCollector`
|
|
542
|
+
|
|
543
|
+
Collector registry utilities:
|
|
544
|
+
|
|
545
|
+
- `registerBuiltinCollector(collector)`
|
|
546
|
+
- `registerBuiltinCollectors(collectors)`
|
|
547
|
+
- `getBuiltinCollectors()`
|
|
548
|
+
|
|
549
|
+
### Reporting exports
|
|
550
|
+
|
|
551
|
+
- `runReporters(config, testResultsDir, outputDir)`
|
|
552
|
+
- `loadRuns(testResultsDir)`
|
|
553
|
+
- `dedupeRuns(runs)`
|
|
554
|
+
- `groupByStory(runs)`
|
|
555
|
+
- `orderedCheckpointNames(runs)`
|
|
556
|
+
- `registerBuiltinReporter(reporter)`
|
|
557
|
+
- `htmlReporter`
|
|
558
|
+
- `markdownReporter`
|
|
559
|
+
|
|
560
|
+
### Types
|
|
561
|
+
|
|
562
|
+
Key exported types include:
|
|
563
|
+
|
|
564
|
+
- `CheckpointRecord`
|
|
565
|
+
- `CheckpointManifest`
|
|
566
|
+
- `CheckpointOptions`
|
|
567
|
+
- `CheckpointConfig`
|
|
568
|
+
- `TestCheckpointConfig`
|
|
569
|
+
- `CheckpointCollector`
|
|
570
|
+
- `CollectorResult`
|
|
571
|
+
- `CollectorArtifact`
|
|
572
|
+
- `CollectorContext`
|
|
573
|
+
- `CollectorOptions`
|
|
574
|
+
- `ResolvedCollectorConfig`
|
|
575
|
+
- `CollectorConfig`
|
|
576
|
+
- `BoundingBox`
|
|
577
|
+
- `ScreenshotCollectorData`
|
|
578
|
+
- `HtmlCollectorData`
|
|
579
|
+
- `AxeCollectorData`
|
|
580
|
+
- `WebVitalRating`
|
|
581
|
+
- `WebVitalMetric`
|
|
582
|
+
- `WebVitalsSnapshot`
|
|
583
|
+
- `ConsoleErrorRecord`
|
|
584
|
+
- `FailedRequestRecord`
|
|
585
|
+
- `PageMetadata`
|
|
586
|
+
- `AriaSnapshotCollectorData`
|
|
587
|
+
- `DomStatsCollectorData`
|
|
588
|
+
- `FormFieldValue`
|
|
589
|
+
- `FormFieldState`
|
|
590
|
+
- `FormsCollectorData`
|
|
591
|
+
- `StorageCookieState`
|
|
592
|
+
- `StorageEntryState`
|
|
593
|
+
- `StorageCollectorData`
|
|
594
|
+
- `NetworkTimingBreakdown`
|
|
595
|
+
- `NetworkTimingRecord`
|
|
596
|
+
- `NetworkTimingCollectorData`
|
|
597
|
+
- `ReporterConfig`
|
|
598
|
+
- `ReportGenerator`
|
|
599
|
+
- `ReportGeneratorContext`
|
|
600
|
+
- `ReportGeneratorResult`
|
|
601
|
+
- `ReportGenerationResults`
|
|
602
|
+
- `RunRecord`
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## Page Object Model pattern
|
|
607
|
+
|
|
608
|
+
A good pattern is to keep navigation and actions in the page object, and pass the `checkpoint` fixture into methods that should produce documentation.
|
|
609
|
+
|
|
610
|
+
```ts
|
|
611
|
+
import type { Page } from '@playwright/test';
|
|
612
|
+
import { test, expect } from 'playwright-checkpoint';
|
|
613
|
+
|
|
614
|
+
type CheckpointFn = Parameters<typeof test>[1] extends (args: infer T, ...rest: never[]) => unknown
|
|
615
|
+
? T extends { checkpoint: infer C }
|
|
616
|
+
? C
|
|
617
|
+
: never
|
|
618
|
+
: never;
|
|
619
|
+
|
|
620
|
+
class LoginPage {
|
|
621
|
+
constructor(private readonly page: Page) {}
|
|
622
|
+
|
|
623
|
+
async open(checkpoint: CheckpointFn) {
|
|
624
|
+
await this.page.goto('https://example.com/login');
|
|
625
|
+
await checkpoint('Login page', {
|
|
626
|
+
step: 1,
|
|
627
|
+
description: 'Open the login page and verify the form is present.',
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
async signIn(email: string, password: string, checkpoint: CheckpointFn) {
|
|
632
|
+
await this.page.getByLabel('Email').fill(email);
|
|
633
|
+
await this.page.getByLabel('Password').fill(password);
|
|
634
|
+
await this.page.getByRole('button', { name: 'Sign in' }).click();
|
|
635
|
+
await checkpoint('Signed in', {
|
|
636
|
+
step: 2,
|
|
637
|
+
description: 'Submit valid credentials and wait for the authenticated destination.',
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
test('login flow', async ({ page, checkpoint }) => {
|
|
643
|
+
const loginPage = new LoginPage(page);
|
|
644
|
+
|
|
645
|
+
await loginPage.open(checkpoint);
|
|
646
|
+
await loginPage.signIn('ada@example.com', 'secret', checkpoint);
|
|
647
|
+
|
|
648
|
+
await expect(page).toHaveURL(/dashboard/);
|
|
649
|
+
});
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
If you prefer, you can define your own local alias for the checkpoint function type instead of extracting it from `test`.
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## Development notes
|
|
657
|
+
|
|
658
|
+
- Build: `npm run build`
|
|
659
|
+
- Lint: `npm run lint`
|
|
660
|
+
- Type-check: `npm run check-types`
|
|
661
|
+
- Tests: `npm test`
|
|
662
|
+
|
|
663
|
+
## License
|
|
664
|
+
|
|
665
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__require
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|