playwright-checkpoint 0.1.0-beta.0 → 0.4.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.
Files changed (43) hide show
  1. package/README.md +57 -0
  2. package/dist/{chunk-KG37WSYS.js → chunk-M3BRR3LT.js} +9 -3
  3. package/dist/{chunk-KG37WSYS.js.map → chunk-M3BRR3LT.js.map} +1 -1
  4. package/dist/{chunk-X5IPL32H.js → chunk-WXZOP7XI.js} +153 -35
  5. package/dist/chunk-WXZOP7XI.js.map +1 -0
  6. package/dist/{chunk-K5DX32TO.js → chunk-YUFXGGZM.js} +2 -2
  7. package/dist/cli/bin.cjs +2502 -2387
  8. package/dist/cli/bin.cjs.map +1 -1
  9. package/dist/cli/bin.js +3 -2
  10. package/dist/cli/bin.js.map +1 -1
  11. package/dist/cli/index.cjs +1405 -68
  12. package/dist/cli/index.cjs.map +1 -1
  13. package/dist/cli/index.d.cts +2 -2
  14. package/dist/cli/index.d.ts +2 -2
  15. package/dist/cli/index.js +3 -2
  16. package/dist/{core-CD4jHGgI.d.cts → core-6gyzs35M.d.ts} +2 -1
  17. package/dist/{core-CZvnc0rE.d.ts → core-Dd3WLuTs.d.cts} +2 -1
  18. package/dist/core.cjs +8 -2
  19. package/dist/core.cjs.map +1 -1
  20. package/dist/core.d.cts +2 -2
  21. package/dist/core.d.ts +2 -2
  22. package/dist/core.js +1 -1
  23. package/dist/{index-BjYQX_hK.d.ts → index-CvcgBzvl.d.ts} +1 -1
  24. package/dist/{index-Cabk31qi.d.cts → index-OQx9qcVO.d.cts} +1 -1
  25. package/dist/index.cjs +216 -42
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +5 -5
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.js +73 -19
  30. package/dist/index.js.map +1 -1
  31. package/dist/mcp/index.cjs +149 -35
  32. package/dist/mcp/index.cjs.map +1 -1
  33. package/dist/mcp/index.js +5 -5
  34. package/dist/mcp/index.js.map +1 -1
  35. package/dist/teardown.cjs +1409 -72
  36. package/dist/teardown.cjs.map +1 -1
  37. package/dist/teardown.js +3 -2
  38. package/dist/teardown.js.map +1 -1
  39. package/dist/{types-G7w4n8kR.d.cts → types-wX4eB9mb.d.cts} +16 -1
  40. package/dist/{types-G7w4n8kR.d.ts → types-wX4eB9mb.d.ts} +16 -1
  41. package/package.json +2 -1
  42. package/dist/chunk-X5IPL32H.js.map +0 -1
  43. /package/dist/{chunk-K5DX32TO.js.map → chunk-YUFXGGZM.js.map} +0 -0
package/README.md CHANGED
@@ -126,6 +126,11 @@ const { test } = createCheckpoint();
126
126
  test('checkout on mobile', async ({ page, checkpoint, testCheckpointConfig }) => {
127
127
  testCheckpointConfig.set({
128
128
  description: 'Mobile checkout happy path.',
129
+ article: {
130
+ title: 'How to complete checkout on mobile',
131
+ description: 'Capture customer-facing copy for the generated help article.',
132
+ slug: 'mobile-checkout-guide',
133
+ },
129
134
  collectors: {
130
135
  'web-vitals': true,
131
136
  axe: { timeoutMs: 15_000 },
@@ -331,6 +336,7 @@ Supported markdown reporter config:
331
336
  frontmatter: true,
332
337
  imagePathPrefix: '/static/help',
333
338
  copyScreenshots: true,
339
+ requireExplicitStep: true,
334
340
  },
335
341
  },
336
342
  }
@@ -344,6 +350,8 @@ Behavior:
344
350
  - Uses `description` when present
345
351
  - Falls back to an auto-generated sentence from page title + URL
346
352
  - Includes URL and breadcrumb text for each step
353
+ - Uses `testCheckpointConfig.set({ article })` metadata to override the article title, intro paragraph, and filename slug
354
+ - Set `requireExplicitStep: true` to exclude checkpoints without a numeric `step`
347
355
  - Only includes stories that either:
348
356
  - have at least one checkpoint with `description` or `step`, or
349
357
  - match `includeTags`
@@ -416,6 +424,44 @@ await runReporters(
416
424
 
417
425
  Markdown articles work best when your checkpoints are annotated.
418
426
 
427
+ You can also override customer-facing article metadata separately from the Playwright test title:
428
+
429
+ ```ts
430
+ testCheckpointConfig.set({
431
+ article: {
432
+ title: 'How to import leads from a CSV into your campaign',
433
+ description: 'Learn how to upload your CSV, map each column, and review duplicates before publishing.',
434
+ slug: 'import-leads-from-csv',
435
+ frontmatter: {
436
+ collection: 'Software Guides',
437
+ gleap_doc_id: 179,
438
+ author: 'engineering',
439
+ },
440
+ },
441
+ });
442
+ ```
443
+
444
+ For larger journeys, you can emit multiple help articles from a single test run and reuse shared checkpoints:
445
+
446
+ ```ts
447
+ testCheckpointConfig.set({
448
+ articles: [
449
+ {
450
+ slug: 'edit-cta',
451
+ title: 'How to edit the CTA button',
452
+ description: 'Change the call-to-action text and link on your video.',
453
+ steps: ['editor-open', 'components-tab', 'cta-saved'],
454
+ },
455
+ {
456
+ slug: 'add-outro',
457
+ title: 'How to add an outro video',
458
+ description: 'Attach a closing clip after the main video.',
459
+ steps: ['editor-open', 'components-tab', 'outro-saved'],
460
+ },
461
+ ],
462
+ });
463
+ ```
464
+
419
465
  ```ts
420
466
  await checkpoint('Navigate to the login page', {
421
467
  step: 1,
@@ -457,6 +503,8 @@ Example output shape:
457
503
  ```md
458
504
  # Sign in to your account
459
505
 
506
+ Learn how to upload your CSV, map each column, and review duplicates before publishing.
507
+
460
508
  ## Step 1: Navigate to the login page
461
509
 
462
510
  ![Login page](./screenshots/sign-in-to-your-account/01-navigate-to-the-login-page.png)
@@ -468,6 +516,15 @@ Example output shape:
468
516
  Open the login page and confirm the email/password fields are visible.
469
517
  ```
470
518
 
519
+ ### Multi-article journeys
520
+
521
+ Use `testCheckpointConfig.set({ articles: [...] })` when one Playwright test should produce multiple markdown guides that share the same captured intro steps.
522
+
523
+ - `steps` is an ordered list of checkpoint names to include in that article
524
+ - shared checkpoints are copied once and referenced by multiple generated articles
525
+ - missing checkpoint names only warn; generation continues
526
+ - if `articles` is empty, the reporter falls back to the default single-article behavior
527
+
471
528
  ---
472
529
 
473
530
  ## CLI reference
@@ -1275,6 +1275,12 @@ function createManifest(sessionMetadata) {
1275
1275
  checkpoints: []
1276
1276
  };
1277
1277
  }
1278
+ function resolveTestConfig(testConfig) {
1279
+ if (typeof testConfig === "function") {
1280
+ return testConfig();
1281
+ }
1282
+ return testConfig ?? null;
1283
+ }
1278
1284
  async function writeManifestFile(manifestPath, manifest) {
1279
1285
  await fs12.mkdir(path13.dirname(manifestPath), { recursive: true });
1280
1286
  await fs12.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
@@ -1480,7 +1486,7 @@ async function createCheckpointSession(page, options) {
1480
1486
  }
1481
1487
  }
1482
1488
  await fs12.mkdir(outputDir, { recursive: true });
1483
- await ensureCollectorsSetup(resolveCollectors(sessionConfig));
1489
+ await ensureCollectorsSetup(resolveCollectors(sessionConfig, resolveTestConfig(options.testConfig)));
1484
1490
  return {
1485
1491
  outputDir,
1486
1492
  manifest,
@@ -1488,7 +1494,7 @@ async function createCheckpointSession(page, options) {
1488
1494
  if (finalizePromise) {
1489
1495
  throw new Error("Checkpoint session has already been finalized.");
1490
1496
  }
1491
- const resolvedCollectors = resolveCollectors(sessionConfig, null, checkpointOptions);
1497
+ const resolvedCollectors = resolveCollectors(sessionConfig, resolveTestConfig(options.testConfig), checkpointOptions);
1492
1498
  await ensureCollectorsSetup(resolvedCollectors);
1493
1499
  return runCollectorPipeline({
1494
1500
  page,
@@ -1546,4 +1552,4 @@ export {
1546
1552
  captureCheckpoint,
1547
1553
  createCheckpointSession
1548
1554
  };
1549
- //# sourceMappingURL=chunk-KG37WSYS.js.map
1555
+ //# sourceMappingURL=chunk-M3BRR3LT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts","../src/collectors/aria-snapshot.ts","../src/collectors/axe.ts","../src/page-utils.ts","../src/collectors/console.ts","../src/collectors/dom-stats.ts","../src/collectors/forms.ts","../src/collectors/html.ts","../src/collectors/metadata.ts","../src/collectors/network.ts","../src/collectors/network-timing.ts","../src/collectors/screenshot.ts","../src/collectors/storage.ts","../src/collectors/web-vitals.ts","../src/collectors/builtin-collectors.ts","../src/collectors/registry.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page, TestInfo } from '@playwright/test';\nimport { builtinCollectors as defaultBuiltinCollectors } from './collectors/builtin-collectors';\nimport { getBuiltinCollectors, registerBuiltinCollector, registerBuiltinCollectors } from './collectors/registry';\nimport { settlePage } from './page-utils';\nimport type {\n CheckpointCollector,\n CheckpointConfig,\n CheckpointManifest,\n CheckpointOptions,\n CheckpointRecord,\n CollectorArtifact,\n CollectorConfig,\n CollectorOptions,\n CollectorResult,\n ResolvedCollectorConfig,\n TestCheckpointConfig,\n} from './types';\n\ntype CollectorInput = boolean | CollectorOptions | CollectorConfig | undefined;\n\ntype MutableCollectorState = {\n enabled: boolean;\n config: ResolvedCollectorConfig;\n};\n\nexport type CheckpointSessionMetadata = Partial<\n Pick<CheckpointManifest, 'environment' | 'project' | 'testId' | 'title' | 'tags'>\n>;\n\nexport type CheckpointSessionOptions = Omit<CheckpointConfig, 'collectors'> & {\n outputDir: string;\n collectors?: Partial<Record<string, boolean | CollectorConfig>>;\n sessionMetadata?: CheckpointSessionMetadata;\n manifest?: CheckpointManifest;\n manifestPath?: string;\n testInfo?: TestInfo;\n adjustTimeout?: (ms: number) => void;\n};\n\nexport type CaptureCheckpointOptions = CheckpointSessionOptions & CheckpointOptions;\n\nexport type CheckpointSession = {\n outputDir: string;\n manifest: CheckpointManifest;\n checkpoint(name: string, options?: CheckpointOptions): Promise<CheckpointRecord>;\n finalize(): Promise<CheckpointManifest>;\n};\n\nexport type RunCollectorPipelineArgs = {\n page: Page;\n name: string;\n outputDir: string;\n resolvedCollectors: Map<string, ResolvedCollectorConfig>;\n registry: Map<string, CheckpointCollector>;\n options?: CheckpointOptions;\n manifest?: CheckpointManifest;\n slug?: string;\n redact?: string[];\n testInfo?: TestInfo;\n adjustTimeout?: (ms: number) => void;\n};\n\nregisterBuiltinCollectors(defaultBuiltinCollectors);\n\nfunction cloneResolvedConfig(config: ResolvedCollectorConfig): ResolvedCollectorConfig {\n return { ...config };\n}\n\nfunction cloneCollectorState(state: MutableCollectorState | undefined): MutableCollectorState {\n return {\n enabled: state?.enabled ?? false,\n config: cloneResolvedConfig(state?.config ?? {}),\n };\n}\n\nfunction applyCollectorInput(state: MutableCollectorState | undefined, input: CollectorInput): MutableCollectorState {\n const next = cloneCollectorState(state);\n\n if (input === undefined) {\n return next;\n }\n\n if (input === false) {\n return {\n enabled: false,\n config: {},\n };\n }\n\n if (input === true) {\n return {\n enabled: true,\n config: next.config,\n };\n }\n\n return {\n enabled: true,\n config: {\n ...next.config,\n ...input,\n },\n };\n}\n\nfunction collectorRegistryFor(config: CheckpointConfig = {}): Map<string, CheckpointCollector> {\n const registry = getBuiltinCollectors();\n\n for (const collector of config.custom ?? []) {\n registry.set(collector.name, collector);\n }\n\n return registry;\n}\n\nfunction cloneCheckpointOptions(options: CheckpointOptions): CheckpointOptions {\n return {\n ...options,\n ...(options.collectors ? { collectors: { ...options.collectors } } : {}),\n };\n}\n\nfunction defaultManifestEnvironment(): string {\n return process.env.PLAYWRIGHT_CHECKPOINT_ENV || process.env.NODE_ENV || 'test';\n}\n\nfunction createManifest(sessionMetadata: CheckpointSessionMetadata | undefined): CheckpointManifest {\n return {\n environment: sessionMetadata?.environment ?? defaultManifestEnvironment(),\n project: sessionMetadata?.project ?? '',\n testId: sessionMetadata?.testId ?? '',\n title: sessionMetadata?.title ?? '',\n tags: [...(sessionMetadata?.tags ?? [])],\n startedAt: new Date().toISOString(),\n checkpoints: [],\n };\n}\n\nasync function writeManifestFile(manifestPath: string, manifest: CheckpointManifest): Promise<string> {\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, 'utf8');\n return manifestPath;\n}\n\nexport function warn(message: string, error?: unknown): void {\n if (error instanceof Error) {\n console.warn(`[playwright-checkpoint] ${message}`, error);\n return;\n }\n\n if (error !== undefined) {\n console.warn(`[playwright-checkpoint] ${message}`, String(error));\n return;\n }\n\n console.warn(`[playwright-checkpoint] ${message}`);\n}\n\nexport function sanitizeSegment(value: string): string {\n return (\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'checkpoint'\n );\n}\n\nexport function checkpointSlug(name: string, existing: CheckpointRecord[]): string {\n const base = sanitizeSegment(name);\n const existingSlugs = new Set(existing.map((record) => record.slug));\n\n if (!existingSlugs.has(base)) {\n return base;\n }\n\n let index = 2;\n let candidate = `${base}-${index}`;\n while (existingSlugs.has(candidate)) {\n index += 1;\n candidate = `${base}-${index}`;\n }\n\n return candidate;\n}\n\nasync function attachArtifacts(\n testInfo: TestInfo | undefined,\n checkpointSlugValue: string,\n collectorName: string,\n artifacts: CollectorArtifact[],\n): Promise<void> {\n const attach = testInfo?.attach;\n if (typeof attach !== 'function') {\n return;\n }\n\n for (const artifact of artifacts) {\n try {\n await attach.call(testInfo, `${checkpointSlugValue}/${collectorName}/${artifact.name}`, {\n path: artifact.path,\n contentType: artifact.contentType,\n });\n } catch (error) {\n warn(`Failed to attach artifact \"${artifact.name}\" from collector \"${collectorName}\".`, error);\n }\n }\n}\n\nexport async function collectPageTitle(page: Page): Promise<string> {\n try {\n return await page.title();\n } catch {\n return '';\n }\n}\n\nexport async function runCollectorSetup(\n collectors: Iterable<CheckpointCollector>,\n page: Page,\n testInfo?: TestInfo,\n): Promise<void> {\n for (const collector of collectors) {\n if (!collector.setup) {\n continue;\n }\n\n try {\n await collector.setup({ page, testInfo });\n } catch (error) {\n warn(`Collector \"${collector.name}\" setup failed.`, error);\n }\n }\n}\n\nexport async function runCollectorTeardown(\n collectors: Iterable<CheckpointCollector>,\n page: Page,\n testInfo?: TestInfo,\n): Promise<void> {\n const collectorList = Array.from(collectors).reverse();\n\n for (const collector of collectorList) {\n if (!collector.teardown) {\n continue;\n }\n\n try {\n await collector.teardown({ page, testInfo });\n } catch (error) {\n warn(`Collector \"${collector.name}\" teardown failed.`, error);\n }\n }\n}\n\nexport function resolveCollectors(\n globalConfig: CheckpointConfig = {},\n testConfig: TestCheckpointConfig | null = null,\n checkpointOptions: CheckpointOptions = {},\n): Map<string, ResolvedCollectorConfig> {\n const registry = collectorRegistryFor(globalConfig);\n const states = new Map<string, MutableCollectorState>();\n\n for (const collector of registry.values()) {\n states.set(collector.name, {\n enabled: collector.defaultEnabled,\n config: {},\n });\n }\n\n const levels = [globalConfig.collectors, testConfig?.collectors, checkpointOptions.collectors];\n\n for (const level of levels) {\n for (const [name, input] of Object.entries(level ?? {})) {\n states.set(name, applyCollectorInput(states.get(name), input));\n }\n }\n\n const resolved = new Map<string, ResolvedCollectorConfig>();\n\n for (const [name, state] of states) {\n if (state.enabled) {\n resolved.set(name, cloneResolvedConfig(state.config));\n }\n }\n\n return resolved;\n}\n\nexport async function runCollectorPipeline(args: RunCollectorPipelineArgs): Promise<CheckpointRecord> {\n const options = cloneCheckpointOptions(args.options ?? {});\n const slug = args.slug ?? checkpointSlug(args.name, args.manifest?.checkpoints ?? []);\n const checkpointDir = path.join(args.outputDir, slug);\n const collectorResults: Record<string, CollectorResult> = {};\n\n await fs.mkdir(checkpointDir, { recursive: true });\n await settlePage(args.page);\n\n for (const [collectorName, collectorConfig] of args.resolvedCollectors) {\n const collector = args.registry.get(collectorName);\n if (!collector) {\n warn(`Collector \"${collectorName}\" is enabled but no implementation is registered.`);\n continue;\n }\n\n try {\n const result = await collector.collect({\n page: args.page,\n testInfo: args.testInfo,\n checkpointDir,\n checkpointName: args.name,\n checkpointSlug: slug,\n redact: [...(args.redact ?? [])],\n config: cloneResolvedConfig(collectorConfig),\n options,\n adjustTimeout: args.adjustTimeout,\n });\n\n collectorResults[collectorName] = result;\n await attachArtifacts(args.testInfo, slug, collectorName, result.artifacts);\n } catch (error) {\n warn(`Collector \"${collectorName}\" failed during checkpoint \"${args.name}\".`, error);\n }\n }\n\n const record: CheckpointRecord = {\n name: args.name,\n slug,\n url: args.page.url(),\n title: await collectPageTitle(args.page),\n timestamp: new Date().toISOString(),\n ...(options.description ? { description: options.description } : {}),\n ...(typeof options.step === 'number' ? { step: options.step } : {}),\n collectors: collectorResults,\n };\n\n args.manifest?.checkpoints.push(record);\n return record;\n}\n\nexport async function captureCheckpoint(\n page: Page,\n name: string,\n options: CaptureCheckpointOptions,\n): Promise<CheckpointRecord> {\n const sessionConfig: CheckpointConfig = {\n collectors: options.collectors,\n custom: options.custom,\n redact: options.redact,\n };\n const registry = collectorRegistryFor(sessionConfig);\n const resolvedCollectors = resolveCollectors(sessionConfig, null, options);\n const enabledCollectors = Array.from(resolvedCollectors.keys())\n .map((collectorName) => registry.get(collectorName))\n .filter((collector): collector is CheckpointCollector => Boolean(collector));\n\n await fs.mkdir(options.outputDir, { recursive: true });\n await runCollectorSetup(enabledCollectors, page, options.testInfo);\n\n try {\n return await runCollectorPipeline({\n page,\n name,\n outputDir: options.outputDir,\n resolvedCollectors,\n registry,\n options,\n redact: options.redact,\n testInfo: options.testInfo,\n adjustTimeout: options.adjustTimeout,\n slug: checkpointSlug(name, []),\n });\n } finally {\n await runCollectorTeardown(enabledCollectors, page, options.testInfo);\n }\n}\n\nexport async function createCheckpointSession(page: Page, options: CheckpointSessionOptions): Promise<CheckpointSession> {\n const sessionConfig: CheckpointConfig = {\n collectors: options.collectors,\n custom: options.custom,\n redact: options.redact,\n };\n const outputDir = options.outputDir;\n const registry = collectorRegistryFor(sessionConfig);\n const manifest = options.manifest ?? createManifest(options.sessionMetadata);\n const setupCollectorNames = new Set<string>();\n const setupCollectors: CheckpointCollector[] = [];\n let finalizePromise: Promise<CheckpointManifest> | null = null;\n\n async function ensureCollectorsSetup(resolvedCollectors: Map<string, ResolvedCollectorConfig>): Promise<void> {\n for (const collectorName of resolvedCollectors.keys()) {\n if (setupCollectorNames.has(collectorName)) {\n continue;\n }\n\n const collector = registry.get(collectorName);\n if (!collector) {\n warn(`Collector \"${collectorName}\" is enabled but no implementation is registered.`);\n continue;\n }\n\n setupCollectorNames.add(collectorName);\n setupCollectors.push(collector);\n await runCollectorSetup([collector], page, options.testInfo);\n }\n }\n\n await fs.mkdir(outputDir, { recursive: true });\n await ensureCollectorsSetup(resolveCollectors(sessionConfig));\n\n return {\n outputDir,\n manifest,\n async checkpoint(name, checkpointOptions = {}) {\n if (finalizePromise) {\n throw new Error('Checkpoint session has already been finalized.');\n }\n\n const resolvedCollectors = resolveCollectors(sessionConfig, null, checkpointOptions);\n await ensureCollectorsSetup(resolvedCollectors);\n\n return runCollectorPipeline({\n page,\n name,\n outputDir,\n resolvedCollectors,\n registry,\n options: checkpointOptions,\n manifest,\n redact: options.redact,\n testInfo: options.testInfo,\n adjustTimeout: options.adjustTimeout,\n });\n },\n finalize() {\n if (!finalizePromise) {\n finalizePromise = (async () => {\n await runCollectorTeardown(setupCollectors, page, options.testInfo);\n await writeManifestFile(options.manifestPath ?? path.join(outputDir, 'checkpoint-manifest.json'), manifest);\n return manifest;\n })();\n }\n\n return finalizePromise;\n },\n };\n}\n\nexport { registerBuiltinCollector, registerBuiltinCollectors, settlePage };\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointCollector, AriaSnapshotCollectorData } from '../types';\n\nfunction countSnapshotNodes(value: unknown): number {\n if (value == null) {\n return 0;\n }\n\n if (Array.isArray(value)) {\n return value.reduce((total, item) => total + countSnapshotNodes(item), 0);\n }\n\n if (typeof value !== 'object') {\n return 1;\n }\n\n const node = value as { children?: unknown };\n const children = Array.isArray(node.children) ? node.children : [];\n return 1 + children.reduce((total, child) => total + countSnapshotNodes(child), 0);\n}\n\nasync function captureAriaSnapshot(page: {\n locator: (selector: string) => { ariaSnapshot?: () => Promise<unknown> };\n accessibility?: { snapshot?: (options?: { interestingOnly?: boolean }) => Promise<unknown> };\n}): Promise<unknown | null> {\n try {\n const root = page.locator(':root');\n if (typeof root.ariaSnapshot === 'function') {\n const snapshot = await root.ariaSnapshot();\n return snapshot ?? null;\n }\n } catch {\n // Fall through to accessibility.snapshot.\n }\n\n if (typeof page.accessibility?.snapshot === 'function') {\n try {\n const snapshot = await page.accessibility.snapshot({ interestingOnly: false });\n return snapshot ?? null;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\nexport const ariaSnapshotCollector: CheckpointCollector = {\n name: 'aria-snapshot',\n defaultEnabled: false,\n\n async collect(ctx) {\n const snapshot = await captureAriaSnapshot(ctx.page as unknown as Parameters<typeof captureAriaSnapshot>[0]);\n const nodeCount = countSnapshotNodes(snapshot);\n const outputPath = path.join(ctx.checkpointDir, 'aria-snapshot.json');\n\n const data: AriaSnapshotCollectorData = {\n snapshot,\n nodeCount,\n };\n\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'aria-snapshot',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n nodeCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page } from '@playwright/test';\nimport { settlePage } from '../page-utils';\nimport type { AxeCollectorData, CheckpointCollector } from '../types';\n\ntype AxeBuilderInstance = {\n analyze(): Promise<unknown>;\n};\n\ntype AxeBuilderConstructor = new (options: { page: Page }) => AxeBuilderInstance;\n\ntype AxeModule = {\n default?: AxeBuilderConstructor;\n AxeBuilder?: AxeBuilderConstructor;\n};\n\nlet axeLoader: () => Promise<AxeModule> = () => import('@axe-core/playwright');\nlet warnedAboutMissingAxe = false;\n\nfunction warnOnce(message: string, error?: unknown): void {\n if (warnedAboutMissingAxe) {\n return;\n }\n\n warnedAboutMissingAxe = true;\n if (error instanceof Error) {\n console.warn(`[playwright-checkpoint] ${message}`, error);\n return;\n }\n\n if (error !== undefined) {\n console.warn(`[playwright-checkpoint] ${message}`, String(error));\n return;\n }\n\n console.warn(`[playwright-checkpoint] ${message}`);\n}\n\nfunction resolveAxeBuilder(module: AxeModule): AxeBuilderConstructor | null {\n return module.default ?? module.AxeBuilder ?? null;\n}\n\nasync function analyzeAccessibility(page: Page, AxeBuilder: AxeBuilderConstructor): Promise<unknown> {\n try {\n await settlePage(page);\n return await new AxeBuilder({ page }).analyze();\n } catch {\n await page.waitForTimeout(500);\n await settlePage(page);\n return await new AxeBuilder({ page }).analyze();\n }\n}\n\nfunction skippedAxeResult(reason: string): {\n data: AxeCollectorData;\n artifacts: [];\n summary: { violations: number };\n} {\n return {\n data: {\n skipped: true,\n reason,\n violations: 0,\n results: null,\n },\n artifacts: [],\n summary: {\n violations: 0,\n },\n };\n}\n\nexport function setAxeLoaderForTests(loader: (() => Promise<AxeModule>) | null): void {\n axeLoader = loader ?? (() => import('@axe-core/playwright'));\n warnedAboutMissingAxe = false;\n}\n\nexport const axeCollector: CheckpointCollector = {\n name: 'axe',\n defaultEnabled: true,\n\n async collect(ctx) {\n const timeoutBudgetMs = typeof ctx.config.timeoutMs === 'number' ? ctx.config.timeoutMs : 5_000;\n\n if (timeoutBudgetMs > 0) {\n if (typeof ctx.adjustTimeout === 'function') {\n ctx.adjustTimeout(timeoutBudgetMs);\n } else if (ctx.testInfo && typeof ctx.testInfo.setTimeout === 'function') {\n ctx.testInfo.setTimeout(ctx.testInfo.timeout + timeoutBudgetMs);\n }\n }\n\n let module: AxeModule;\n try {\n module = await axeLoader();\n } catch (error) {\n warnOnce('Skipping axe collector because @axe-core/playwright is unavailable.', error);\n return skippedAxeResult('@axe-core/playwright is unavailable');\n }\n\n const AxeBuilder = resolveAxeBuilder(module);\n if (!AxeBuilder) {\n warnOnce('Skipping axe collector because @axe-core/playwright did not expose an AxeBuilder export.');\n return skippedAxeResult('@axe-core/playwright did not expose AxeBuilder');\n }\n\n const results = await analyzeAccessibility(ctx.page, AxeBuilder);\n const violations =\n results &&\n typeof results === 'object' &&\n Array.isArray((results as { violations?: unknown }).violations)\n ? (results as { violations: unknown[] }).violations.length\n : 0;\n const axePath = path.join(ctx.checkpointDir, 'axe.json');\n\n await fs.writeFile(axePath, `${JSON.stringify(results, null, 2)}\\n`, 'utf8');\n\n return {\n data: {\n skipped: false,\n reason: null,\n violations,\n results,\n } satisfies AxeCollectorData,\n artifacts: [\n {\n name: 'axe',\n path: axePath,\n contentType: 'application/json',\n },\n ],\n summary: {\n violations,\n },\n };\n },\n};\n","import type { Page } from '@playwright/test';\n\nexport async function settlePage(page: Page): Promise<void> {\n await page.waitForLoadState('domcontentloaded').catch(() => undefined);\n await page.waitForLoadState('load', { timeout: 3_000 }).catch(() => undefined);\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { ConsoleMessage, Page } from '@playwright/test';\nimport type { CheckpointCollector, ConsoleErrorRecord } from '../types';\n\ntype ConsoleCollectorState = {\n entries: ConsoleErrorRecord[];\n offset: number;\n recordConsoleMessage: (message: ConsoleMessage) => void | Promise<void>;\n recordPageError: (error: Error) => void;\n};\n\nconst consoleStates = new WeakMap<Page, ConsoleCollectorState>();\n\nfunction getLocation(message: ConsoleMessage): ConsoleErrorRecord['location'] {\n const location = message.location();\n if (!location.url && location.lineNumber == null && location.columnNumber == null) {\n return null;\n }\n\n return {\n ...(location.url ? { url: location.url } : {}),\n ...(location.lineNumber == null ? {} : { lineNumber: location.lineNumber }),\n ...(location.columnNumber == null ? {} : { columnNumber: location.columnNumber }),\n };\n}\n\nexport const consoleCollector: CheckpointCollector = {\n name: 'console',\n defaultEnabled: true,\n\n async setup({ page }) {\n if (consoleStates.has(page)) {\n return;\n }\n\n const entries: ConsoleErrorRecord[] = [];\n\n const recordConsoleMessage = (message: ConsoleMessage): void => {\n if (message.type() !== 'error') {\n return;\n }\n\n entries.push({\n type: message.type(),\n text: message.text(),\n location: getLocation(message),\n timestamp: new Date().toISOString(),\n });\n };\n\n const recordPageError = (error: Error): void => {\n entries.push({\n type: 'pageerror',\n text: error.message,\n location: null,\n timestamp: new Date().toISOString(),\n });\n };\n\n page.on('console', recordConsoleMessage);\n page.on('pageerror', recordPageError);\n\n consoleStates.set(page, {\n entries,\n offset: 0,\n recordConsoleMessage,\n recordPageError,\n });\n },\n\n async collect(ctx) {\n const state = consoleStates.get(ctx.page);\n const checkpointEntries = state ? state.entries.slice(state.offset) : [];\n\n if (state) {\n state.offset = state.entries.length;\n }\n\n const outputPath = path.join(ctx.checkpointDir, 'console-errors.json');\n await fs.writeFile(outputPath, `${JSON.stringify(checkpointEntries, null, 2)}\\n`, 'utf8');\n\n return {\n data: checkpointEntries,\n artifacts: [\n {\n name: 'console-errors',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n consoleErrorCount: checkpointEntries.length,\n },\n };\n },\n\n async teardown({ page }) {\n const state = consoleStates.get(page);\n if (!state) {\n return;\n }\n\n page.off('console', state.recordConsoleMessage);\n page.off('pageerror', state.recordPageError);\n consoleStates.delete(page);\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointCollector, DomStatsCollectorData } from '../types';\n\nexport const domStatsCollector: CheckpointCollector = {\n name: 'dom-stats',\n defaultEnabled: false,\n\n async collect(ctx) {\n const stats = await ctx.page.evaluate(() => {\n const allNodes = document.querySelectorAll('*');\n\n const maxDepthFrom = (root: Element | null): number => {\n if (!root) {\n return 0;\n }\n\n let maxDepth = 1;\n const queue: Array<{ node: Element; depth: number }> = [{ node: root, depth: 1 }];\n\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current) {\n continue;\n }\n\n maxDepth = Math.max(maxDepth, current.depth);\n for (const child of Array.from(current.node.children)) {\n queue.push({ node: child, depth: current.depth + 1 });\n }\n }\n\n return maxDepth;\n };\n\n const maybeGetEventListeners =\n (globalThis as { getEventListeners?: (target: EventTarget) => Record<string, unknown[]> }).getEventListeners;\n\n let eventListenerCount: number | null = null;\n if (typeof maybeGetEventListeners === 'function') {\n eventListenerCount = 0;\n const targets: EventTarget[] = [window, document, ...Array.from(allNodes)];\n\n for (const target of targets) {\n try {\n const listeners = maybeGetEventListeners(target) ?? {};\n for (const entries of Object.values(listeners)) {\n eventListenerCount += Array.isArray(entries) ? entries.length : 0;\n }\n } catch {\n // Ignore inaccessible targets.\n }\n }\n }\n\n return {\n nodeCount: allNodes.length,\n maxDepth: maxDepthFrom(document.documentElement),\n formCount: document.querySelectorAll('form').length,\n imageCount: document.querySelectorAll('img').length,\n scriptCount: document.querySelectorAll('script').length,\n stylesheetCount: document.styleSheets.length,\n eventListenerCount,\n };\n });\n\n const data: DomStatsCollectorData = {\n nodeCount: stats.nodeCount,\n maxDepth: stats.maxDepth,\n formCount: stats.formCount,\n imageCount: stats.imageCount,\n scriptCount: stats.scriptCount,\n stylesheetCount: stats.stylesheetCount,\n eventListenerCount: stats.eventListenerCount,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'dom-stats.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'dom-stats',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n nodeCount: data.nodeCount,\n maxDepth: data.maxDepth,\n formCount: data.formCount,\n imageCount: data.imageCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n CheckpointCollector,\n FormFieldState,\n FormFieldValue,\n FormsCollectorData,\n} from '../types';\n\nconst REDACTED = '[REDACTED]';\nconst DEFAULT_REDACT_PATTERNS = ['password', 'token', 'secret', 'api[_-]?key', 'authorization', 'bearer'];\nconst EMAIL_LIKE_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\ntype RawFieldState = Omit<FormFieldState, 'redacted'>;\n\nfunction toRegex(pattern: string): RegExp | null {\n const trimmed = pattern.trim();\n if (!trimmed) {\n return null;\n }\n\n try {\n return new RegExp(trimmed, 'i');\n } catch {\n return null;\n }\n}\n\nfunction redactionRegexes(ctx: { redact: string[]; config: Record<string, unknown> }): RegExp[] {\n const fromConfig = Array.isArray(ctx.config.redact)\n ? ctx.config.redact.filter((entry): entry is string => typeof entry === 'string')\n : [];\n\n return [...DEFAULT_REDACT_PATTERNS, ...ctx.redact, ...fromConfig]\n .map((pattern) => toRegex(pattern))\n .filter((value): value is RegExp => value instanceof RegExp);\n}\n\nfunction shouldRedactText(value: string, regexes: RegExp[]): boolean {\n if (EMAIL_LIKE_REGEX.test(value.trim())) {\n return true;\n }\n\n return regexes.some((regex) => regex.test(value));\n}\n\nfunction fieldIdentifier(field: RawFieldState): string {\n return [field.type, field.name, field.id, field.label, field.placeholder].filter((value): value is string => !!value).join(' ');\n}\n\nfunction redactValue(value: FormFieldValue): FormFieldValue {\n if (value == null) {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(() => REDACTED);\n }\n\n return REDACTED;\n}\n\nfunction fieldNeedsRedaction(field: RawFieldState, regexes: RegExp[]): boolean {\n if (shouldRedactText(fieldIdentifier(field), regexes)) {\n return true;\n }\n\n if (field.value == null) {\n return false;\n }\n\n if (Array.isArray(field.value)) {\n return field.value.some((entry) => shouldRedactText(entry, regexes));\n }\n\n return shouldRedactText(field.value, regexes);\n}\n\nexport const formsCollector: CheckpointCollector = {\n name: 'forms',\n defaultEnabled: false,\n\n async collect(ctx) {\n const rawFields = await ctx.page.evaluate(() => {\n const elements = Array.from(document.querySelectorAll('input, select, textarea'));\n\n const isVisible = (element: Element): boolean => {\n if (!(element instanceof HTMLElement)) {\n return false;\n }\n\n const inputType = element instanceof HTMLInputElement ? element.type.toLowerCase() : null;\n if (inputType === 'hidden') {\n return false;\n }\n\n if (element.hasAttribute('hidden') || element.getAttribute('aria-hidden') === 'true') {\n return false;\n }\n\n const style = window.getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden' || Number(style.opacity) === 0) {\n return false;\n }\n\n const rect = element.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n };\n\n const readLabel = (element: Element): string | null => {\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n const fromLabels = element.labels && element.labels.length > 0 ? element.labels[0]?.textContent?.trim() : null;\n if (fromLabels) {\n return fromLabels;\n }\n }\n\n return element.getAttribute('aria-label')?.trim() ?? null;\n };\n\n const readValue = (element: Element): { value: string | string[] | null; checked: boolean | null; type: string | null } => {\n if (element instanceof HTMLSelectElement) {\n if (element.multiple) {\n return {\n value: Array.from(element.selectedOptions).map((option) => option.value),\n checked: null,\n type: 'select-multiple',\n };\n }\n\n return {\n value: element.value,\n checked: null,\n type: 'select-one',\n };\n }\n\n if (element instanceof HTMLTextAreaElement) {\n return {\n value: element.value,\n checked: null,\n type: 'textarea',\n };\n }\n\n if (element instanceof HTMLInputElement) {\n const inputType = element.type.toLowerCase();\n if (inputType === 'checkbox' || inputType === 'radio') {\n return {\n value: element.checked ? element.value || 'on' : null,\n checked: element.checked,\n type: inputType,\n };\n }\n\n if (inputType === 'file') {\n return {\n value: element.files ? Array.from(element.files).map((file) => file.name) : [],\n checked: null,\n type: inputType,\n };\n }\n\n return {\n value: element.value,\n checked: null,\n type: inputType || null,\n };\n }\n\n return {\n value: null,\n checked: null,\n type: null,\n };\n };\n\n return elements\n .filter((element) => isVisible(element))\n .map((element) => {\n const { value, checked, type } = readValue(element);\n\n return {\n tagName: element.tagName.toLowerCase() as 'input' | 'select' | 'textarea',\n type,\n name: element.getAttribute('name'),\n id: element.getAttribute('id'),\n label: readLabel(element),\n placeholder: element.getAttribute('placeholder'),\n value,\n checked,\n disabled: (element as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).disabled,\n required: (element as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).required,\n };\n });\n });\n\n const regexes = redactionRegexes({ redact: ctx.redact, config: ctx.config });\n let redactedCount = 0;\n\n const fields: FormFieldState[] = (rawFields as RawFieldState[]).map((field) => {\n const redacted = fieldNeedsRedaction(field, regexes);\n if (redacted) {\n redactedCount += 1;\n }\n\n return {\n ...field,\n redacted,\n value: redacted ? redactValue(field.value) : field.value,\n };\n });\n\n const data: FormsCollectorData = {\n fieldCount: fields.length,\n redactedCount,\n fields,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'form-state.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'form-state',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n fieldCount: data.fieldCount,\n redactedCount: data.redactedCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page } from '@playwright/test';\nimport { settlePage } from '../page-utils';\nimport type { CheckpointCollector, HtmlCollectorData } from '../types';\n\nasync function readPageContent(page: Page): Promise<string> {\n try {\n await settlePage(page);\n return await page.content();\n } catch {\n await page.waitForTimeout(500);\n await settlePage(page);\n return await page.content();\n }\n}\n\nexport const htmlCollector: CheckpointCollector = {\n name: 'html',\n defaultEnabled: true,\n\n async collect(ctx) {\n const htmlPath = path.join(ctx.checkpointDir, 'page.html');\n const html = await readPageContent(ctx.page);\n\n await fs.writeFile(htmlPath, html, 'utf8');\n\n return {\n data: {\n contentLength: html.length,\n } satisfies HtmlCollectorData,\n artifacts: [\n {\n name: 'html',\n path: htmlPath,\n contentType: 'text/html',\n },\n ],\n summary: {\n htmlPath: 'page.html',\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointCollector, PageMetadata } from '../types';\n\nfunction normalizeStructuredData(scriptContents: Array<string | null>): unknown[] {\n const values: unknown[] = [];\n\n for (const content of scriptContents) {\n const value = content?.trim();\n if (!value) {\n continue;\n }\n\n try {\n values.push(JSON.parse(value));\n } catch {\n values.push({\n parseError: 'Invalid JSON-LD',\n raw: value,\n });\n }\n }\n\n return values;\n}\n\nexport const metadataCollector: CheckpointCollector = {\n name: 'metadata',\n defaultEnabled: true,\n\n async collect(ctx) {\n const metadata = await ctx.page.evaluate(() => {\n const meta = (selector: string): string | null => document.querySelector(selector)?.getAttribute('content') ?? null;\n const canonicalLink = document.querySelector('link[rel=\"canonical\"]');\n const html = document.documentElement;\n const structuredDataScripts = Array.from(document.querySelectorAll('script[type=\"application/ld+json\"]')).map((script) => script.textContent ?? null);\n\n return {\n url: location.href,\n title: document.title,\n description: meta('meta[name=\"description\"]'),\n openGraph: {\n title: meta('meta[property=\"og:title\"]'),\n description: meta('meta[property=\"og:description\"]'),\n image: meta('meta[property=\"og:image\"]'),\n },\n canonicalUrl: canonicalLink?.getAttribute('href') ?? null,\n lang: html.getAttribute('lang'),\n viewport: meta('meta[name=\"viewport\"]'),\n structuredDataScripts,\n };\n });\n\n const normalizedMetadata: PageMetadata = {\n url: metadata.url,\n title: metadata.title,\n description: metadata.description,\n openGraph: metadata.openGraph,\n canonicalUrl: metadata.canonicalUrl,\n lang: metadata.lang,\n viewport: metadata.viewport,\n structuredData: normalizeStructuredData(metadata.structuredDataScripts),\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'metadata.json');\n await fs.writeFile(outputPath, `${JSON.stringify(normalizedMetadata, null, 2)}\\n`, 'utf8');\n\n return {\n data: normalizedMetadata,\n artifacts: [\n {\n name: 'metadata',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n url: normalizedMetadata.url,\n title: normalizedMetadata.title,\n lang: normalizedMetadata.lang,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page, Request, Response } from '@playwright/test';\nimport type { CheckpointCollector, FailedRequestRecord } from '../types';\n\ntype NetworkCollectorState = {\n entries: FailedRequestRecord[];\n offset: number;\n recordRequestFailure: (request: Request) => void;\n recordHttpError: (response: Response) => void;\n};\n\nconst networkStates = new WeakMap<Page, NetworkCollectorState>();\n\nexport const networkCollector: CheckpointCollector = {\n name: 'network',\n defaultEnabled: true,\n\n async setup({ page }) {\n if (networkStates.has(page)) {\n return;\n }\n\n const entries: FailedRequestRecord[] = [];\n\n const recordRequestFailure = (request: Request): void => {\n entries.push({\n kind: 'requestfailed',\n url: request.url(),\n method: request.method(),\n status: null,\n statusText: null,\n failureText: request.failure()?.errorText ?? null,\n timestamp: new Date().toISOString(),\n });\n };\n\n const recordHttpError = (response: Response): void => {\n if (response.status() < 400) {\n return;\n }\n\n entries.push({\n kind: 'http-error',\n url: response.url(),\n method: response.request().method(),\n status: response.status(),\n statusText: response.statusText(),\n failureText: null,\n timestamp: new Date().toISOString(),\n });\n };\n\n page.on('requestfailed', recordRequestFailure);\n page.on('response', recordHttpError);\n\n networkStates.set(page, {\n entries,\n offset: 0,\n recordRequestFailure,\n recordHttpError,\n });\n },\n\n async collect(ctx) {\n const state = networkStates.get(ctx.page);\n const checkpointEntries = state ? state.entries.slice(state.offset) : [];\n\n if (state) {\n state.offset = state.entries.length;\n }\n\n const outputPath = path.join(ctx.checkpointDir, 'failed-requests.json');\n await fs.writeFile(outputPath, `${JSON.stringify(checkpointEntries, null, 2)}\\n`, 'utf8');\n\n return {\n data: checkpointEntries,\n artifacts: [\n {\n name: 'failed-requests',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n failedRequestCount: checkpointEntries.length,\n },\n };\n },\n\n async teardown({ page }) {\n const state = networkStates.get(page);\n if (!state) {\n return;\n }\n\n page.off('requestfailed', state.recordRequestFailure);\n page.off('response', state.recordHttpError);\n networkStates.delete(page);\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page, Response } from '@playwright/test';\nimport type {\n CheckpointCollector,\n NetworkTimingCollectorData,\n NetworkTimingRecord,\n} from '../types';\n\ntype ResponseEventRecord = {\n url: string;\n status: number | null;\n statusText: string | null;\n resourceType: string | null;\n timestamp: string;\n};\n\ntype ResourceTimingRecord = {\n name: string;\n duration: number;\n transferSize: number;\n encodedBodySize: number;\n decodedBodySize: number;\n nextHopProtocol: string;\n startTime: number;\n redirectStart: number;\n redirectEnd: number;\n domainLookupStart: number;\n domainLookupEnd: number;\n connectStart: number;\n connectEnd: number;\n secureConnectionStart: number;\n requestStart: number;\n responseStart: number;\n responseEnd: number;\n};\n\ntype NetworkTimingCollectorState = {\n responses: ResponseEventRecord[];\n responseOffset: number;\n resourceOffsetByUrl: Map<string, number>;\n recordResponse: (response: Response) => void;\n};\n\nconst timingStates = new WeakMap<Page, NetworkTimingCollectorState>();\n\nfunction maybeDuration(start: number, end: number): number | null {\n if (start <= 0 || end <= 0 || end < start) {\n return null;\n }\n\n return end - start;\n}\n\nfunction toNetworkRecord(response: ResponseEventRecord, timing: ResourceTimingRecord | null): NetworkTimingRecord {\n return {\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n resourceType: response.resourceType,\n timestamp: response.timestamp,\n durationMs: timing ? timing.duration : null,\n transferSize: timing ? timing.transferSize : null,\n encodedBodySize: timing ? timing.encodedBodySize : null,\n decodedBodySize: timing ? timing.decodedBodySize : null,\n nextHopProtocol: timing ? timing.nextHopProtocol || null : null,\n timing: {\n startTimeMs: timing ? timing.startTime : null,\n redirectMs: timing ? maybeDuration(timing.redirectStart, timing.redirectEnd) : null,\n dnsMs: timing ? maybeDuration(timing.domainLookupStart, timing.domainLookupEnd) : null,\n connectMs: timing ? maybeDuration(timing.connectStart, timing.connectEnd) : null,\n tlsMs: timing ? maybeDuration(timing.secureConnectionStart, timing.connectEnd) : null,\n requestMs: timing ? maybeDuration(timing.requestStart, timing.responseStart) : null,\n responseMs: timing ? maybeDuration(timing.responseStart, timing.responseEnd) : null,\n },\n };\n}\n\nexport const networkTimingCollector: CheckpointCollector = {\n name: 'network-timing',\n defaultEnabled: false,\n\n async setup({ page }) {\n if (timingStates.has(page)) {\n return;\n }\n\n const responses: ResponseEventRecord[] = [];\n\n const recordResponse = (response: Response): void => {\n responses.push({\n url: response.url(),\n status: response.status(),\n statusText: response.statusText(),\n resourceType: response.request().resourceType(),\n timestamp: new Date().toISOString(),\n });\n };\n\n page.on('response', recordResponse);\n\n timingStates.set(page, {\n responses,\n responseOffset: 0,\n resourceOffsetByUrl: new Map<string, number>(),\n recordResponse,\n });\n },\n\n async collect(ctx) {\n const state = timingStates.get(ctx.page);\n const recentResponses = state ? state.responses.slice(state.responseOffset) : [];\n\n if (state) {\n state.responseOffset = state.responses.length;\n }\n\n const resourceTimings = (await ctx.page.evaluate(() => {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n return entries.map((entry) => ({\n name: entry.name,\n duration: entry.duration,\n transferSize: entry.transferSize,\n encodedBodySize: entry.encodedBodySize,\n decodedBodySize: entry.decodedBodySize,\n nextHopProtocol: entry.nextHopProtocol,\n startTime: entry.startTime,\n redirectStart: entry.redirectStart,\n redirectEnd: entry.redirectEnd,\n domainLookupStart: entry.domainLookupStart,\n domainLookupEnd: entry.domainLookupEnd,\n connectStart: entry.connectStart,\n connectEnd: entry.connectEnd,\n secureConnectionStart: entry.secureConnectionStart,\n requestStart: entry.requestStart,\n responseStart: entry.responseStart,\n responseEnd: entry.responseEnd,\n }));\n })) as ResourceTimingRecord[];\n\n const timingsByUrl = new Map<string, ResourceTimingRecord[]>();\n for (const timing of resourceTimings) {\n const list = timingsByUrl.get(timing.name);\n if (list) {\n list.push(timing);\n } else {\n timingsByUrl.set(timing.name, [timing]);\n }\n }\n\n const requests: NetworkTimingRecord[] = recentResponses.map((response) => {\n if (!state) {\n return toNetworkRecord(response, null);\n }\n\n const list = timingsByUrl.get(response.url) ?? [];\n const currentOffset = state.resourceOffsetByUrl.get(response.url) ?? 0;\n const match = list[currentOffset] ?? null;\n\n if (match) {\n state.resourceOffsetByUrl.set(response.url, currentOffset + 1);\n }\n\n return toNetworkRecord(response, match);\n });\n\n const totalBytes = requests.reduce((total, request) => {\n if (typeof request.transferSize !== 'number' || request.transferSize < 0) {\n return total;\n }\n\n return total + request.transferSize;\n }, 0);\n\n const slowestRequestMs = requests.reduce((slowest, request) => {\n if (typeof request.durationMs !== 'number') {\n return slowest;\n }\n\n return Math.max(slowest, request.durationMs);\n }, 0);\n\n const data: NetworkTimingCollectorData = {\n requestCount: requests.length,\n totalBytes,\n slowestRequestMs,\n requests,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'network-timing.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'network-timing',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n requestCount: data.requestCount,\n totalBytes: data.totalBytes,\n slowestRequestMs: data.slowestRequestMs,\n },\n };\n },\n\n async teardown({ page }) {\n const state = timingStates.get(page);\n if (!state) {\n return;\n }\n\n page.off('response', state.recordResponse);\n timingStates.delete(page);\n },\n};\n","import path from 'node:path';\nimport type { CheckpointCollector, ScreenshotCollectorData } from '../types';\n\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n\nfunction readPngSize(buffer: Buffer): ScreenshotCollectorData['imageSize'] {\n if (buffer.length < 24 || !buffer.subarray(0, 8).equals(PNG_SIGNATURE)) {\n return null;\n }\n\n if (buffer.toString('ascii', 12, 16) !== 'IHDR') {\n return null;\n }\n\n return {\n width: buffer.readUInt32BE(16),\n height: buffer.readUInt32BE(20),\n };\n}\n\nexport const screenshotCollector: CheckpointCollector = {\n name: 'screenshot',\n defaultEnabled: true,\n\n async collect(ctx) {\n const fullPage = ctx.options.fullPage ?? true;\n const screenshotPath = path.join(ctx.checkpointDir, 'page.png');\n const screenshotBuffer = await ctx.page.screenshot({ path: screenshotPath, fullPage });\n\n let highlightBounds: ScreenshotCollectorData['highlightBounds'] = null;\n if (ctx.options.highlightSelector) {\n highlightBounds = await ctx.page\n .locator(ctx.options.highlightSelector)\n .boundingBox()\n .catch(() => null);\n }\n\n return {\n data: {\n fullPage,\n highlightBounds,\n highlightSelector: ctx.options.highlightSelector ?? null,\n imageSize: Buffer.isBuffer(screenshotBuffer) ? readPngSize(screenshotBuffer) : null,\n } satisfies ScreenshotCollectorData,\n artifacts: [\n {\n name: 'screenshot',\n path: screenshotPath,\n contentType: 'image/png',\n },\n ],\n summary: {\n screenshotPath: 'page.png',\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n CheckpointCollector,\n StorageCollectorData,\n StorageCookieState,\n StorageEntryState,\n} from '../types';\n\nconst REDACTED = '[REDACTED]';\nconst DEFAULT_REDACT_PATTERNS = ['password', 'token', 'secret', 'api[_-]?key', 'authorization', 'session', 'email'];\nconst EMAIL_LIKE_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\ntype RawCookie = {\n name: string;\n domain: string;\n path: string;\n value: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: string;\n};\n\ntype RawStorageEntry = {\n key: string;\n value: string;\n};\n\nfunction toRegex(pattern: string): RegExp | null {\n const trimmed = pattern.trim();\n if (!trimmed) {\n return null;\n }\n\n try {\n return new RegExp(trimmed, 'i');\n } catch {\n return null;\n }\n}\n\nfunction buildRedactionRegexes(ctx: { redact: string[]; config: Record<string, unknown> }): RegExp[] {\n const fromConfig = Array.isArray(ctx.config.redact)\n ? ctx.config.redact.filter((entry): entry is string => typeof entry === 'string')\n : [];\n\n return [...DEFAULT_REDACT_PATTERNS, ...ctx.redact, ...fromConfig]\n .map((pattern) => toRegex(pattern))\n .filter((value): value is RegExp => value instanceof RegExp);\n}\n\nfunction shouldRedact(identifier: string, value: string | null, regexes: RegExp[]): boolean {\n if (regexes.some((regex) => regex.test(identifier))) {\n return true;\n }\n\n if (!value) {\n return false;\n }\n\n if (EMAIL_LIKE_REGEX.test(value.trim())) {\n return true;\n }\n\n return regexes.some((regex) => regex.test(value));\n}\n\nexport const storageCollector: CheckpointCollector = {\n name: 'storage',\n defaultEnabled: false,\n\n async collect(ctx) {\n const includeCookieValues = ctx.config.includeCookieValues === true;\n const includeLocalStorageValues = ctx.config.includeLocalStorageValues === true;\n const redactValues = ctx.config.redactValues !== false;\n const regexes = buildRedactionRegexes({ redact: ctx.redact, config: ctx.config });\n\n const cookies = (await ctx.page.context().cookies()) as RawCookie[];\n const localStorageEntries = await ctx.page.evaluate(() =>\n Object.keys(localStorage).map((key) => ({\n key,\n value: localStorage.getItem(key) ?? '',\n })),\n );\n\n const normalizedCookies: StorageCookieState[] = cookies.map((cookie) => {\n const rawValue = includeCookieValues ? cookie.value : null;\n const redacted = redactValues && shouldRedact(cookie.name, rawValue, regexes);\n\n return {\n name: cookie.name,\n domain: cookie.domain,\n path: cookie.path,\n value: rawValue == null ? null : redacted ? REDACTED : rawValue,\n redacted,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n };\n });\n\n const normalizedLocalStorage: StorageEntryState[] = (localStorageEntries as RawStorageEntry[]).map((entry) => {\n const rawValue = includeLocalStorageValues ? entry.value : null;\n const redacted = redactValues && shouldRedact(entry.key, rawValue, regexes);\n\n return {\n key: entry.key,\n value: rawValue == null ? null : redacted ? REDACTED : rawValue,\n redacted,\n };\n });\n\n const data: StorageCollectorData = {\n cookieCount: normalizedCookies.length,\n localStorageKeyCount: normalizedLocalStorage.length,\n cookies: normalizedCookies,\n localStorage: normalizedLocalStorage,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'storage-state.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'storage-state',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n cookieCount: data.cookieCount,\n localStorageKeyCount: data.localStorageKeyCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page } from '@playwright/test';\nimport type {\n CheckpointCollector,\n WebVitalMetric,\n WebVitalRating,\n WebVitalsSnapshot,\n} from '../types';\n\ntype RawWebVitals = {\n cls: number | null;\n fcp: number | null;\n lcp: number | null;\n inp: number | null;\n ttfb: number | null;\n domContentLoaded: number | null;\n loadEvent: number | null;\n url: string;\n};\n\nconst initializedPages = new WeakSet<Page>();\n\nfunction rateMetric(\n value: number | null,\n thresholds: { good: number; needsImprovement: number },\n): WebVitalRating {\n if (value == null || Number.isNaN(value)) {\n return 'unknown';\n }\n if (value <= thresholds.good) {\n return 'good';\n }\n if (value <= thresholds.needsImprovement) {\n return 'needs-improvement';\n }\n return 'poor';\n}\n\nfunction metric(value: number | null, thresholds: { good: number; needsImprovement: number }): WebVitalMetric {\n return {\n value,\n rating: rateMetric(value, thresholds),\n };\n}\n\nasync function captureWebVitals(page: Page): Promise<WebVitalsSnapshot> {\n const raw = await page.evaluate(() => {\n const globalState = globalThis as typeof globalThis & {\n __e2eWebVitals?: {\n cls: number;\n fcp: number | null;\n lcp: number | null;\n inp: number | null;\n };\n };\n\n const state = globalState.__e2eWebVitals ?? {\n cls: 0,\n fcp: null,\n lcp: null,\n inp: null,\n };\n const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;\n\n return {\n cls: state.cls,\n fcp: state.fcp,\n lcp: state.lcp,\n inp: state.inp,\n ttfb: navigation ? navigation.responseStart : null,\n domContentLoaded: navigation ? navigation.domContentLoadedEventEnd : null,\n loadEvent: navigation ? navigation.loadEventEnd : null,\n url: location.href,\n } satisfies RawWebVitals;\n });\n\n return {\n url: raw.url,\n capturedAt: new Date().toISOString(),\n cls: metric(raw.cls, { good: 0.1, needsImprovement: 0.25 }),\n fcpMs: metric(raw.fcp, { good: 1800, needsImprovement: 3000 }),\n lcpMs: metric(raw.lcp, { good: 2500, needsImprovement: 4000 }),\n inpMs: metric(raw.inp, { good: 200, needsImprovement: 500 }),\n ttfbMs: metric(raw.ttfb, { good: 800, needsImprovement: 1800 }),\n domContentLoadedMs: raw.domContentLoaded,\n loadEventMs: raw.loadEvent,\n };\n}\n\nexport const webVitalsCollector: CheckpointCollector = {\n name: 'web-vitals',\n defaultEnabled: true,\n\n async setup({ page }) {\n if (initializedPages.has(page)) {\n return;\n }\n\n initializedPages.add(page);\n\n await page.addInitScript(() => {\n const globalState = globalThis as typeof globalThis & {\n __e2eWebVitals?: {\n cls: number;\n fcp: number | null;\n lcp: number | null;\n inp: number | null;\n };\n };\n\n if (!globalState.__e2eWebVitals) {\n globalState.__e2eWebVitals = {\n cls: 0,\n fcp: null,\n lcp: null,\n inp: null,\n };\n }\n\n const state = globalState.__e2eWebVitals;\n\n try {\n const paintObserver = new PerformanceObserver((entryList) => {\n for (const entry of entryList.getEntries()) {\n if (entry.name === 'first-contentful-paint') {\n state.fcp = entry.startTime;\n }\n }\n });\n paintObserver.observe({ type: 'paint', buffered: true });\n } catch {\n // Unsupported in this browser context.\n }\n\n try {\n const lcpObserver = new PerformanceObserver((entryList) => {\n const entries = entryList.getEntries();\n const lastEntry = entries[entries.length - 1];\n if (lastEntry) {\n state.lcp = lastEntry.startTime;\n }\n });\n lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });\n addEventListener('pagehide', () => lcpObserver.disconnect(), { once: true });\n } catch {\n // Unsupported in this browser context.\n }\n\n try {\n const clsObserver = new PerformanceObserver((entryList) => {\n for (const entry of entryList.getEntries() as Array<PerformanceEntry & { hadRecentInput?: boolean; value?: number }>) {\n if (!entry.hadRecentInput) {\n state.cls += entry.value ?? 0;\n }\n }\n });\n clsObserver.observe({ type: 'layout-shift', buffered: true });\n addEventListener('pagehide', () => clsObserver.disconnect(), { once: true });\n } catch {\n // Unsupported in this browser context.\n }\n\n try {\n const inpObserver = new PerformanceObserver((entryList) => {\n for (const entry of entryList.getEntries() as Array<PerformanceEntry & { duration?: number }>) {\n const duration = entry.duration ?? 0;\n if (state.inp == null || duration > state.inp) {\n state.inp = duration;\n }\n }\n });\n inpObserver.observe({ type: 'event', buffered: true, durationThreshold: 40 } as PerformanceObserverInit);\n addEventListener('pagehide', () => inpObserver.disconnect(), { once: true });\n } catch {\n // Unsupported in this browser context.\n }\n });\n },\n\n async collect(ctx) {\n const snapshot = await captureWebVitals(ctx.page);\n const outputPath = path.join(ctx.checkpointDir, 'web-vitals.json');\n\n await fs.writeFile(outputPath, `${JSON.stringify(snapshot, null, 2)}\\n`, 'utf8');\n\n return {\n data: snapshot,\n artifacts: [\n {\n name: 'web-vitals',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n cls: snapshot.cls,\n fcp: snapshot.fcpMs,\n lcp: snapshot.lcpMs,\n inp: snapshot.inpMs,\n ttfb: snapshot.ttfbMs,\n },\n };\n },\n\n async teardown({ page }) {\n initializedPages.delete(page);\n },\n};\n","import { ariaSnapshotCollector } from './aria-snapshot';\nimport { axeCollector } from './axe';\nimport { consoleCollector } from './console';\nimport { domStatsCollector } from './dom-stats';\nimport { formsCollector } from './forms';\nimport { htmlCollector } from './html';\nimport { metadataCollector } from './metadata';\nimport { networkCollector } from './network';\nimport { networkTimingCollector } from './network-timing';\nimport { screenshotCollector } from './screenshot';\nimport { storageCollector } from './storage';\nimport { webVitalsCollector } from './web-vitals';\n\nexport const builtinCollectors = [\n screenshotCollector,\n htmlCollector,\n axeCollector,\n webVitalsCollector,\n consoleCollector,\n networkCollector,\n metadataCollector,\n ariaSnapshotCollector,\n domStatsCollector,\n formsCollector,\n storageCollector,\n networkTimingCollector,\n];\n","import type { CheckpointCollector } from '../types';\n\nconst builtinCollectors = new Map<string, CheckpointCollector>();\nlet builtinsRegistered = false;\n\nexport function registerBuiltinCollector(collector: CheckpointCollector): void {\n builtinCollectors.set(collector.name, collector);\n}\n\nexport function registerBuiltinCollectors(collectors: CheckpointCollector[]): void {\n if (builtinsRegistered) {\n return;\n }\n\n for (const collector of collectors) {\n registerBuiltinCollector(collector);\n }\n\n builtinsRegistered = true;\n}\n\nexport function getBuiltinCollectors(): Map<string, CheckpointCollector> {\n return new Map(builtinCollectors);\n}\n"],"mappings":"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","names":["fs","path","fs","path","path","fs","fs","path","location","fs","path","fs","path","fs","path","path","fs","fs","path","fs","path","fs","path","path","fs","path","REDACTED","DEFAULT_REDACT_PATTERNS","EMAIL_LIKE_REGEX","toRegex","fs","path","builtinCollectors","fs","path"]}
1
+ {"version":3,"sources":["../src/core.ts","../src/collectors/aria-snapshot.ts","../src/collectors/axe.ts","../src/page-utils.ts","../src/collectors/console.ts","../src/collectors/dom-stats.ts","../src/collectors/forms.ts","../src/collectors/html.ts","../src/collectors/metadata.ts","../src/collectors/network.ts","../src/collectors/network-timing.ts","../src/collectors/screenshot.ts","../src/collectors/storage.ts","../src/collectors/web-vitals.ts","../src/collectors/builtin-collectors.ts","../src/collectors/registry.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page, TestInfo } from '@playwright/test';\nimport { builtinCollectors as defaultBuiltinCollectors } from './collectors/builtin-collectors';\nimport { getBuiltinCollectors, registerBuiltinCollector, registerBuiltinCollectors } from './collectors/registry';\nimport { settlePage } from './page-utils';\nimport type {\n CheckpointCollector,\n CheckpointConfig,\n CheckpointManifest,\n CheckpointOptions,\n CheckpointRecord,\n CollectorArtifact,\n CollectorConfig,\n CollectorOptions,\n CollectorResult,\n ResolvedCollectorConfig,\n TestCheckpointConfig,\n} from './types';\n\ntype CollectorInput = boolean | CollectorOptions | CollectorConfig | undefined;\n\ntype MutableCollectorState = {\n enabled: boolean;\n config: ResolvedCollectorConfig;\n};\n\nexport type CheckpointSessionMetadata = Partial<\n Pick<CheckpointManifest, 'environment' | 'project' | 'testId' | 'title' | 'tags'>\n>;\n\nexport type CheckpointSessionOptions = Omit<CheckpointConfig, 'collectors'> & {\n outputDir: string;\n collectors?: Partial<Record<string, boolean | CollectorConfig>>;\n testConfig?: TestCheckpointConfig | null | (() => TestCheckpointConfig | null);\n sessionMetadata?: CheckpointSessionMetadata;\n manifest?: CheckpointManifest;\n manifestPath?: string;\n testInfo?: TestInfo;\n adjustTimeout?: (ms: number) => void;\n};\n\nexport type CaptureCheckpointOptions = CheckpointSessionOptions & CheckpointOptions;\n\nexport type CheckpointSession = {\n outputDir: string;\n manifest: CheckpointManifest;\n checkpoint(name: string, options?: CheckpointOptions): Promise<CheckpointRecord>;\n finalize(): Promise<CheckpointManifest>;\n};\n\nexport type RunCollectorPipelineArgs = {\n page: Page;\n name: string;\n outputDir: string;\n resolvedCollectors: Map<string, ResolvedCollectorConfig>;\n registry: Map<string, CheckpointCollector>;\n options?: CheckpointOptions;\n manifest?: CheckpointManifest;\n slug?: string;\n redact?: string[];\n testInfo?: TestInfo;\n adjustTimeout?: (ms: number) => void;\n};\n\nregisterBuiltinCollectors(defaultBuiltinCollectors);\n\nfunction cloneResolvedConfig(config: ResolvedCollectorConfig): ResolvedCollectorConfig {\n return { ...config };\n}\n\nfunction cloneCollectorState(state: MutableCollectorState | undefined): MutableCollectorState {\n return {\n enabled: state?.enabled ?? false,\n config: cloneResolvedConfig(state?.config ?? {}),\n };\n}\n\nfunction applyCollectorInput(state: MutableCollectorState | undefined, input: CollectorInput): MutableCollectorState {\n const next = cloneCollectorState(state);\n\n if (input === undefined) {\n return next;\n }\n\n if (input === false) {\n return {\n enabled: false,\n config: {},\n };\n }\n\n if (input === true) {\n return {\n enabled: true,\n config: next.config,\n };\n }\n\n return {\n enabled: true,\n config: {\n ...next.config,\n ...input,\n },\n };\n}\n\nfunction collectorRegistryFor(config: CheckpointConfig = {}): Map<string, CheckpointCollector> {\n const registry = getBuiltinCollectors();\n\n for (const collector of config.custom ?? []) {\n registry.set(collector.name, collector);\n }\n\n return registry;\n}\n\nfunction cloneCheckpointOptions(options: CheckpointOptions): CheckpointOptions {\n return {\n ...options,\n ...(options.collectors ? { collectors: { ...options.collectors } } : {}),\n };\n}\n\nfunction defaultManifestEnvironment(): string {\n return process.env.PLAYWRIGHT_CHECKPOINT_ENV || process.env.NODE_ENV || 'test';\n}\n\nfunction createManifest(sessionMetadata: CheckpointSessionMetadata | undefined): CheckpointManifest {\n return {\n environment: sessionMetadata?.environment ?? defaultManifestEnvironment(),\n project: sessionMetadata?.project ?? '',\n testId: sessionMetadata?.testId ?? '',\n title: sessionMetadata?.title ?? '',\n tags: [...(sessionMetadata?.tags ?? [])],\n startedAt: new Date().toISOString(),\n checkpoints: [],\n };\n}\n\nfunction resolveTestConfig(\n testConfig: CheckpointSessionOptions['testConfig'],\n): TestCheckpointConfig | null {\n if (typeof testConfig === 'function') {\n return testConfig();\n }\n\n return testConfig ?? null;\n}\n\nasync function writeManifestFile(manifestPath: string, manifest: CheckpointManifest): Promise<string> {\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, 'utf8');\n return manifestPath;\n}\n\nexport function warn(message: string, error?: unknown): void {\n if (error instanceof Error) {\n console.warn(`[playwright-checkpoint] ${message}`, error);\n return;\n }\n\n if (error !== undefined) {\n console.warn(`[playwright-checkpoint] ${message}`, String(error));\n return;\n }\n\n console.warn(`[playwright-checkpoint] ${message}`);\n}\n\nexport function sanitizeSegment(value: string): string {\n return (\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'checkpoint'\n );\n}\n\nexport function checkpointSlug(name: string, existing: CheckpointRecord[]): string {\n const base = sanitizeSegment(name);\n const existingSlugs = new Set(existing.map((record) => record.slug));\n\n if (!existingSlugs.has(base)) {\n return base;\n }\n\n let index = 2;\n let candidate = `${base}-${index}`;\n while (existingSlugs.has(candidate)) {\n index += 1;\n candidate = `${base}-${index}`;\n }\n\n return candidate;\n}\n\nasync function attachArtifacts(\n testInfo: TestInfo | undefined,\n checkpointSlugValue: string,\n collectorName: string,\n artifacts: CollectorArtifact[],\n): Promise<void> {\n const attach = testInfo?.attach;\n if (typeof attach !== 'function') {\n return;\n }\n\n for (const artifact of artifacts) {\n try {\n await attach.call(testInfo, `${checkpointSlugValue}/${collectorName}/${artifact.name}`, {\n path: artifact.path,\n contentType: artifact.contentType,\n });\n } catch (error) {\n warn(`Failed to attach artifact \"${artifact.name}\" from collector \"${collectorName}\".`, error);\n }\n }\n}\n\nexport async function collectPageTitle(page: Page): Promise<string> {\n try {\n return await page.title();\n } catch {\n return '';\n }\n}\n\nexport async function runCollectorSetup(\n collectors: Iterable<CheckpointCollector>,\n page: Page,\n testInfo?: TestInfo,\n): Promise<void> {\n for (const collector of collectors) {\n if (!collector.setup) {\n continue;\n }\n\n try {\n await collector.setup({ page, testInfo });\n } catch (error) {\n warn(`Collector \"${collector.name}\" setup failed.`, error);\n }\n }\n}\n\nexport async function runCollectorTeardown(\n collectors: Iterable<CheckpointCollector>,\n page: Page,\n testInfo?: TestInfo,\n): Promise<void> {\n const collectorList = Array.from(collectors).reverse();\n\n for (const collector of collectorList) {\n if (!collector.teardown) {\n continue;\n }\n\n try {\n await collector.teardown({ page, testInfo });\n } catch (error) {\n warn(`Collector \"${collector.name}\" teardown failed.`, error);\n }\n }\n}\n\nexport function resolveCollectors(\n globalConfig: CheckpointConfig = {},\n testConfig: TestCheckpointConfig | null = null,\n checkpointOptions: CheckpointOptions = {},\n): Map<string, ResolvedCollectorConfig> {\n const registry = collectorRegistryFor(globalConfig);\n const states = new Map<string, MutableCollectorState>();\n\n for (const collector of registry.values()) {\n states.set(collector.name, {\n enabled: collector.defaultEnabled,\n config: {},\n });\n }\n\n const levels = [globalConfig.collectors, testConfig?.collectors, checkpointOptions.collectors];\n\n for (const level of levels) {\n for (const [name, input] of Object.entries(level ?? {})) {\n states.set(name, applyCollectorInput(states.get(name), input));\n }\n }\n\n const resolved = new Map<string, ResolvedCollectorConfig>();\n\n for (const [name, state] of states) {\n if (state.enabled) {\n resolved.set(name, cloneResolvedConfig(state.config));\n }\n }\n\n return resolved;\n}\n\nexport async function runCollectorPipeline(args: RunCollectorPipelineArgs): Promise<CheckpointRecord> {\n const options = cloneCheckpointOptions(args.options ?? {});\n const slug = args.slug ?? checkpointSlug(args.name, args.manifest?.checkpoints ?? []);\n const checkpointDir = path.join(args.outputDir, slug);\n const collectorResults: Record<string, CollectorResult> = {};\n\n await fs.mkdir(checkpointDir, { recursive: true });\n await settlePage(args.page);\n\n for (const [collectorName, collectorConfig] of args.resolvedCollectors) {\n const collector = args.registry.get(collectorName);\n if (!collector) {\n warn(`Collector \"${collectorName}\" is enabled but no implementation is registered.`);\n continue;\n }\n\n try {\n const result = await collector.collect({\n page: args.page,\n testInfo: args.testInfo,\n checkpointDir,\n checkpointName: args.name,\n checkpointSlug: slug,\n redact: [...(args.redact ?? [])],\n config: cloneResolvedConfig(collectorConfig),\n options,\n adjustTimeout: args.adjustTimeout,\n });\n\n collectorResults[collectorName] = result;\n await attachArtifacts(args.testInfo, slug, collectorName, result.artifacts);\n } catch (error) {\n warn(`Collector \"${collectorName}\" failed during checkpoint \"${args.name}\".`, error);\n }\n }\n\n const record: CheckpointRecord = {\n name: args.name,\n slug,\n url: args.page.url(),\n title: await collectPageTitle(args.page),\n timestamp: new Date().toISOString(),\n ...(options.description ? { description: options.description } : {}),\n ...(typeof options.step === 'number' ? { step: options.step } : {}),\n collectors: collectorResults,\n };\n\n args.manifest?.checkpoints.push(record);\n return record;\n}\n\nexport async function captureCheckpoint(\n page: Page,\n name: string,\n options: CaptureCheckpointOptions,\n): Promise<CheckpointRecord> {\n const sessionConfig: CheckpointConfig = {\n collectors: options.collectors,\n custom: options.custom,\n redact: options.redact,\n };\n const registry = collectorRegistryFor(sessionConfig);\n const resolvedCollectors = resolveCollectors(sessionConfig, null, options);\n const enabledCollectors = Array.from(resolvedCollectors.keys())\n .map((collectorName) => registry.get(collectorName))\n .filter((collector): collector is CheckpointCollector => Boolean(collector));\n\n await fs.mkdir(options.outputDir, { recursive: true });\n await runCollectorSetup(enabledCollectors, page, options.testInfo);\n\n try {\n return await runCollectorPipeline({\n page,\n name,\n outputDir: options.outputDir,\n resolvedCollectors,\n registry,\n options,\n redact: options.redact,\n testInfo: options.testInfo,\n adjustTimeout: options.adjustTimeout,\n slug: checkpointSlug(name, []),\n });\n } finally {\n await runCollectorTeardown(enabledCollectors, page, options.testInfo);\n }\n}\n\nexport async function createCheckpointSession(page: Page, options: CheckpointSessionOptions): Promise<CheckpointSession> {\n const sessionConfig: CheckpointConfig = {\n collectors: options.collectors,\n custom: options.custom,\n redact: options.redact,\n };\n const outputDir = options.outputDir;\n const registry = collectorRegistryFor(sessionConfig);\n const manifest = options.manifest ?? createManifest(options.sessionMetadata);\n const setupCollectorNames = new Set<string>();\n const setupCollectors: CheckpointCollector[] = [];\n let finalizePromise: Promise<CheckpointManifest> | null = null;\n\n async function ensureCollectorsSetup(resolvedCollectors: Map<string, ResolvedCollectorConfig>): Promise<void> {\n for (const collectorName of resolvedCollectors.keys()) {\n if (setupCollectorNames.has(collectorName)) {\n continue;\n }\n\n const collector = registry.get(collectorName);\n if (!collector) {\n warn(`Collector \"${collectorName}\" is enabled but no implementation is registered.`);\n continue;\n }\n\n setupCollectorNames.add(collectorName);\n setupCollectors.push(collector);\n await runCollectorSetup([collector], page, options.testInfo);\n }\n }\n\n await fs.mkdir(outputDir, { recursive: true });\n await ensureCollectorsSetup(resolveCollectors(sessionConfig, resolveTestConfig(options.testConfig)));\n\n return {\n outputDir,\n manifest,\n async checkpoint(name, checkpointOptions = {}) {\n if (finalizePromise) {\n throw new Error('Checkpoint session has already been finalized.');\n }\n\n const resolvedCollectors = resolveCollectors(sessionConfig, resolveTestConfig(options.testConfig), checkpointOptions);\n await ensureCollectorsSetup(resolvedCollectors);\n\n return runCollectorPipeline({\n page,\n name,\n outputDir,\n resolvedCollectors,\n registry,\n options: checkpointOptions,\n manifest,\n redact: options.redact,\n testInfo: options.testInfo,\n adjustTimeout: options.adjustTimeout,\n });\n },\n finalize() {\n if (!finalizePromise) {\n finalizePromise = (async () => {\n await runCollectorTeardown(setupCollectors, page, options.testInfo);\n await writeManifestFile(options.manifestPath ?? path.join(outputDir, 'checkpoint-manifest.json'), manifest);\n return manifest;\n })();\n }\n\n return finalizePromise;\n },\n };\n}\n\nexport { registerBuiltinCollector, registerBuiltinCollectors, settlePage };\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointCollector, AriaSnapshotCollectorData } from '../types';\n\nfunction countSnapshotNodes(value: unknown): number {\n if (value == null) {\n return 0;\n }\n\n if (Array.isArray(value)) {\n return value.reduce((total, item) => total + countSnapshotNodes(item), 0);\n }\n\n if (typeof value !== 'object') {\n return 1;\n }\n\n const node = value as { children?: unknown };\n const children = Array.isArray(node.children) ? node.children : [];\n return 1 + children.reduce((total, child) => total + countSnapshotNodes(child), 0);\n}\n\nasync function captureAriaSnapshot(page: {\n locator: (selector: string) => { ariaSnapshot?: () => Promise<unknown> };\n accessibility?: { snapshot?: (options?: { interestingOnly?: boolean }) => Promise<unknown> };\n}): Promise<unknown | null> {\n try {\n const root = page.locator(':root');\n if (typeof root.ariaSnapshot === 'function') {\n const snapshot = await root.ariaSnapshot();\n return snapshot ?? null;\n }\n } catch {\n // Fall through to accessibility.snapshot.\n }\n\n if (typeof page.accessibility?.snapshot === 'function') {\n try {\n const snapshot = await page.accessibility.snapshot({ interestingOnly: false });\n return snapshot ?? null;\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\nexport const ariaSnapshotCollector: CheckpointCollector = {\n name: 'aria-snapshot',\n defaultEnabled: false,\n\n async collect(ctx) {\n const snapshot = await captureAriaSnapshot(ctx.page as unknown as Parameters<typeof captureAriaSnapshot>[0]);\n const nodeCount = countSnapshotNodes(snapshot);\n const outputPath = path.join(ctx.checkpointDir, 'aria-snapshot.json');\n\n const data: AriaSnapshotCollectorData = {\n snapshot,\n nodeCount,\n };\n\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'aria-snapshot',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n nodeCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page } from '@playwright/test';\nimport { settlePage } from '../page-utils';\nimport type { AxeCollectorData, CheckpointCollector } from '../types';\n\ntype AxeBuilderInstance = {\n analyze(): Promise<unknown>;\n};\n\ntype AxeBuilderConstructor = new (options: { page: Page }) => AxeBuilderInstance;\n\ntype AxeModule = {\n default?: AxeBuilderConstructor;\n AxeBuilder?: AxeBuilderConstructor;\n};\n\nlet axeLoader: () => Promise<AxeModule> = () => import('@axe-core/playwright');\nlet warnedAboutMissingAxe = false;\n\nfunction warnOnce(message: string, error?: unknown): void {\n if (warnedAboutMissingAxe) {\n return;\n }\n\n warnedAboutMissingAxe = true;\n if (error instanceof Error) {\n console.warn(`[playwright-checkpoint] ${message}`, error);\n return;\n }\n\n if (error !== undefined) {\n console.warn(`[playwright-checkpoint] ${message}`, String(error));\n return;\n }\n\n console.warn(`[playwright-checkpoint] ${message}`);\n}\n\nfunction resolveAxeBuilder(module: AxeModule): AxeBuilderConstructor | null {\n return module.default ?? module.AxeBuilder ?? null;\n}\n\nasync function analyzeAccessibility(page: Page, AxeBuilder: AxeBuilderConstructor): Promise<unknown> {\n try {\n await settlePage(page);\n return await new AxeBuilder({ page }).analyze();\n } catch {\n await page.waitForTimeout(500);\n await settlePage(page);\n return await new AxeBuilder({ page }).analyze();\n }\n}\n\nfunction skippedAxeResult(reason: string): {\n data: AxeCollectorData;\n artifacts: [];\n summary: { violations: number };\n} {\n return {\n data: {\n skipped: true,\n reason,\n violations: 0,\n results: null,\n },\n artifacts: [],\n summary: {\n violations: 0,\n },\n };\n}\n\nexport function setAxeLoaderForTests(loader: (() => Promise<AxeModule>) | null): void {\n axeLoader = loader ?? (() => import('@axe-core/playwright'));\n warnedAboutMissingAxe = false;\n}\n\nexport const axeCollector: CheckpointCollector = {\n name: 'axe',\n defaultEnabled: true,\n\n async collect(ctx) {\n const timeoutBudgetMs = typeof ctx.config.timeoutMs === 'number' ? ctx.config.timeoutMs : 5_000;\n\n if (timeoutBudgetMs > 0) {\n if (typeof ctx.adjustTimeout === 'function') {\n ctx.adjustTimeout(timeoutBudgetMs);\n } else if (ctx.testInfo && typeof ctx.testInfo.setTimeout === 'function') {\n ctx.testInfo.setTimeout(ctx.testInfo.timeout + timeoutBudgetMs);\n }\n }\n\n let module: AxeModule;\n try {\n module = await axeLoader();\n } catch (error) {\n warnOnce('Skipping axe collector because @axe-core/playwright is unavailable.', error);\n return skippedAxeResult('@axe-core/playwright is unavailable');\n }\n\n const AxeBuilder = resolveAxeBuilder(module);\n if (!AxeBuilder) {\n warnOnce('Skipping axe collector because @axe-core/playwright did not expose an AxeBuilder export.');\n return skippedAxeResult('@axe-core/playwright did not expose AxeBuilder');\n }\n\n const results = await analyzeAccessibility(ctx.page, AxeBuilder);\n const violations =\n results &&\n typeof results === 'object' &&\n Array.isArray((results as { violations?: unknown }).violations)\n ? (results as { violations: unknown[] }).violations.length\n : 0;\n const axePath = path.join(ctx.checkpointDir, 'axe.json');\n\n await fs.writeFile(axePath, `${JSON.stringify(results, null, 2)}\\n`, 'utf8');\n\n return {\n data: {\n skipped: false,\n reason: null,\n violations,\n results,\n } satisfies AxeCollectorData,\n artifacts: [\n {\n name: 'axe',\n path: axePath,\n contentType: 'application/json',\n },\n ],\n summary: {\n violations,\n },\n };\n },\n};\n","import type { Page } from '@playwright/test';\n\nexport async function settlePage(page: Page): Promise<void> {\n await page.waitForLoadState('domcontentloaded').catch(() => undefined);\n await page.waitForLoadState('load', { timeout: 3_000 }).catch(() => undefined);\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { ConsoleMessage, Page } from '@playwright/test';\nimport type { CheckpointCollector, ConsoleErrorRecord } from '../types';\n\ntype ConsoleCollectorState = {\n entries: ConsoleErrorRecord[];\n offset: number;\n recordConsoleMessage: (message: ConsoleMessage) => void | Promise<void>;\n recordPageError: (error: Error) => void;\n};\n\nconst consoleStates = new WeakMap<Page, ConsoleCollectorState>();\n\nfunction getLocation(message: ConsoleMessage): ConsoleErrorRecord['location'] {\n const location = message.location();\n if (!location.url && location.lineNumber == null && location.columnNumber == null) {\n return null;\n }\n\n return {\n ...(location.url ? { url: location.url } : {}),\n ...(location.lineNumber == null ? {} : { lineNumber: location.lineNumber }),\n ...(location.columnNumber == null ? {} : { columnNumber: location.columnNumber }),\n };\n}\n\nexport const consoleCollector: CheckpointCollector = {\n name: 'console',\n defaultEnabled: true,\n\n async setup({ page }) {\n if (consoleStates.has(page)) {\n return;\n }\n\n const entries: ConsoleErrorRecord[] = [];\n\n const recordConsoleMessage = (message: ConsoleMessage): void => {\n if (message.type() !== 'error') {\n return;\n }\n\n entries.push({\n type: message.type(),\n text: message.text(),\n location: getLocation(message),\n timestamp: new Date().toISOString(),\n });\n };\n\n const recordPageError = (error: Error): void => {\n entries.push({\n type: 'pageerror',\n text: error.message,\n location: null,\n timestamp: new Date().toISOString(),\n });\n };\n\n page.on('console', recordConsoleMessage);\n page.on('pageerror', recordPageError);\n\n consoleStates.set(page, {\n entries,\n offset: 0,\n recordConsoleMessage,\n recordPageError,\n });\n },\n\n async collect(ctx) {\n const state = consoleStates.get(ctx.page);\n const checkpointEntries = state ? state.entries.slice(state.offset) : [];\n\n if (state) {\n state.offset = state.entries.length;\n }\n\n const outputPath = path.join(ctx.checkpointDir, 'console-errors.json');\n await fs.writeFile(outputPath, `${JSON.stringify(checkpointEntries, null, 2)}\\n`, 'utf8');\n\n return {\n data: checkpointEntries,\n artifacts: [\n {\n name: 'console-errors',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n consoleErrorCount: checkpointEntries.length,\n },\n };\n },\n\n async teardown({ page }) {\n const state = consoleStates.get(page);\n if (!state) {\n return;\n }\n\n page.off('console', state.recordConsoleMessage);\n page.off('pageerror', state.recordPageError);\n consoleStates.delete(page);\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointCollector, DomStatsCollectorData } from '../types';\n\nexport const domStatsCollector: CheckpointCollector = {\n name: 'dom-stats',\n defaultEnabled: false,\n\n async collect(ctx) {\n const stats = await ctx.page.evaluate(() => {\n const allNodes = document.querySelectorAll('*');\n\n const maxDepthFrom = (root: Element | null): number => {\n if (!root) {\n return 0;\n }\n\n let maxDepth = 1;\n const queue: Array<{ node: Element; depth: number }> = [{ node: root, depth: 1 }];\n\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current) {\n continue;\n }\n\n maxDepth = Math.max(maxDepth, current.depth);\n for (const child of Array.from(current.node.children)) {\n queue.push({ node: child, depth: current.depth + 1 });\n }\n }\n\n return maxDepth;\n };\n\n const maybeGetEventListeners =\n (globalThis as { getEventListeners?: (target: EventTarget) => Record<string, unknown[]> }).getEventListeners;\n\n let eventListenerCount: number | null = null;\n if (typeof maybeGetEventListeners === 'function') {\n eventListenerCount = 0;\n const targets: EventTarget[] = [window, document, ...Array.from(allNodes)];\n\n for (const target of targets) {\n try {\n const listeners = maybeGetEventListeners(target) ?? {};\n for (const entries of Object.values(listeners)) {\n eventListenerCount += Array.isArray(entries) ? entries.length : 0;\n }\n } catch {\n // Ignore inaccessible targets.\n }\n }\n }\n\n return {\n nodeCount: allNodes.length,\n maxDepth: maxDepthFrom(document.documentElement),\n formCount: document.querySelectorAll('form').length,\n imageCount: document.querySelectorAll('img').length,\n scriptCount: document.querySelectorAll('script').length,\n stylesheetCount: document.styleSheets.length,\n eventListenerCount,\n };\n });\n\n const data: DomStatsCollectorData = {\n nodeCount: stats.nodeCount,\n maxDepth: stats.maxDepth,\n formCount: stats.formCount,\n imageCount: stats.imageCount,\n scriptCount: stats.scriptCount,\n stylesheetCount: stats.stylesheetCount,\n eventListenerCount: stats.eventListenerCount,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'dom-stats.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'dom-stats',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n nodeCount: data.nodeCount,\n maxDepth: data.maxDepth,\n formCount: data.formCount,\n imageCount: data.imageCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n CheckpointCollector,\n FormFieldState,\n FormFieldValue,\n FormsCollectorData,\n} from '../types';\n\nconst REDACTED = '[REDACTED]';\nconst DEFAULT_REDACT_PATTERNS = ['password', 'token', 'secret', 'api[_-]?key', 'authorization', 'bearer'];\nconst EMAIL_LIKE_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\ntype RawFieldState = Omit<FormFieldState, 'redacted'>;\n\nfunction toRegex(pattern: string): RegExp | null {\n const trimmed = pattern.trim();\n if (!trimmed) {\n return null;\n }\n\n try {\n return new RegExp(trimmed, 'i');\n } catch {\n return null;\n }\n}\n\nfunction redactionRegexes(ctx: { redact: string[]; config: Record<string, unknown> }): RegExp[] {\n const fromConfig = Array.isArray(ctx.config.redact)\n ? ctx.config.redact.filter((entry): entry is string => typeof entry === 'string')\n : [];\n\n return [...DEFAULT_REDACT_PATTERNS, ...ctx.redact, ...fromConfig]\n .map((pattern) => toRegex(pattern))\n .filter((value): value is RegExp => value instanceof RegExp);\n}\n\nfunction shouldRedactText(value: string, regexes: RegExp[]): boolean {\n if (EMAIL_LIKE_REGEX.test(value.trim())) {\n return true;\n }\n\n return regexes.some((regex) => regex.test(value));\n}\n\nfunction fieldIdentifier(field: RawFieldState): string {\n return [field.type, field.name, field.id, field.label, field.placeholder].filter((value): value is string => !!value).join(' ');\n}\n\nfunction redactValue(value: FormFieldValue): FormFieldValue {\n if (value == null) {\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map(() => REDACTED);\n }\n\n return REDACTED;\n}\n\nfunction fieldNeedsRedaction(field: RawFieldState, regexes: RegExp[]): boolean {\n if (shouldRedactText(fieldIdentifier(field), regexes)) {\n return true;\n }\n\n if (field.value == null) {\n return false;\n }\n\n if (Array.isArray(field.value)) {\n return field.value.some((entry) => shouldRedactText(entry, regexes));\n }\n\n return shouldRedactText(field.value, regexes);\n}\n\nexport const formsCollector: CheckpointCollector = {\n name: 'forms',\n defaultEnabled: false,\n\n async collect(ctx) {\n const rawFields = await ctx.page.evaluate(() => {\n const elements = Array.from(document.querySelectorAll('input, select, textarea'));\n\n const isVisible = (element: Element): boolean => {\n if (!(element instanceof HTMLElement)) {\n return false;\n }\n\n const inputType = element instanceof HTMLInputElement ? element.type.toLowerCase() : null;\n if (inputType === 'hidden') {\n return false;\n }\n\n if (element.hasAttribute('hidden') || element.getAttribute('aria-hidden') === 'true') {\n return false;\n }\n\n const style = window.getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden' || Number(style.opacity) === 0) {\n return false;\n }\n\n const rect = element.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n };\n\n const readLabel = (element: Element): string | null => {\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n const fromLabels = element.labels && element.labels.length > 0 ? element.labels[0]?.textContent?.trim() : null;\n if (fromLabels) {\n return fromLabels;\n }\n }\n\n return element.getAttribute('aria-label')?.trim() ?? null;\n };\n\n const readValue = (element: Element): { value: string | string[] | null; checked: boolean | null; type: string | null } => {\n if (element instanceof HTMLSelectElement) {\n if (element.multiple) {\n return {\n value: Array.from(element.selectedOptions).map((option) => option.value),\n checked: null,\n type: 'select-multiple',\n };\n }\n\n return {\n value: element.value,\n checked: null,\n type: 'select-one',\n };\n }\n\n if (element instanceof HTMLTextAreaElement) {\n return {\n value: element.value,\n checked: null,\n type: 'textarea',\n };\n }\n\n if (element instanceof HTMLInputElement) {\n const inputType = element.type.toLowerCase();\n if (inputType === 'checkbox' || inputType === 'radio') {\n return {\n value: element.checked ? element.value || 'on' : null,\n checked: element.checked,\n type: inputType,\n };\n }\n\n if (inputType === 'file') {\n return {\n value: element.files ? Array.from(element.files).map((file) => file.name) : [],\n checked: null,\n type: inputType,\n };\n }\n\n return {\n value: element.value,\n checked: null,\n type: inputType || null,\n };\n }\n\n return {\n value: null,\n checked: null,\n type: null,\n };\n };\n\n return elements\n .filter((element) => isVisible(element))\n .map((element) => {\n const { value, checked, type } = readValue(element);\n\n return {\n tagName: element.tagName.toLowerCase() as 'input' | 'select' | 'textarea',\n type,\n name: element.getAttribute('name'),\n id: element.getAttribute('id'),\n label: readLabel(element),\n placeholder: element.getAttribute('placeholder'),\n value,\n checked,\n disabled: (element as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).disabled,\n required: (element as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).required,\n };\n });\n });\n\n const regexes = redactionRegexes({ redact: ctx.redact, config: ctx.config });\n let redactedCount = 0;\n\n const fields: FormFieldState[] = (rawFields as RawFieldState[]).map((field) => {\n const redacted = fieldNeedsRedaction(field, regexes);\n if (redacted) {\n redactedCount += 1;\n }\n\n return {\n ...field,\n redacted,\n value: redacted ? redactValue(field.value) : field.value,\n };\n });\n\n const data: FormsCollectorData = {\n fieldCount: fields.length,\n redactedCount,\n fields,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'form-state.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'form-state',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n fieldCount: data.fieldCount,\n redactedCount: data.redactedCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page } from '@playwright/test';\nimport { settlePage } from '../page-utils';\nimport type { CheckpointCollector, HtmlCollectorData } from '../types';\n\nasync function readPageContent(page: Page): Promise<string> {\n try {\n await settlePage(page);\n return await page.content();\n } catch {\n await page.waitForTimeout(500);\n await settlePage(page);\n return await page.content();\n }\n}\n\nexport const htmlCollector: CheckpointCollector = {\n name: 'html',\n defaultEnabled: true,\n\n async collect(ctx) {\n const htmlPath = path.join(ctx.checkpointDir, 'page.html');\n const html = await readPageContent(ctx.page);\n\n await fs.writeFile(htmlPath, html, 'utf8');\n\n return {\n data: {\n contentLength: html.length,\n } satisfies HtmlCollectorData,\n artifacts: [\n {\n name: 'html',\n path: htmlPath,\n contentType: 'text/html',\n },\n ],\n summary: {\n htmlPath: 'page.html',\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { CheckpointCollector, PageMetadata } from '../types';\n\nfunction normalizeStructuredData(scriptContents: Array<string | null>): unknown[] {\n const values: unknown[] = [];\n\n for (const content of scriptContents) {\n const value = content?.trim();\n if (!value) {\n continue;\n }\n\n try {\n values.push(JSON.parse(value));\n } catch {\n values.push({\n parseError: 'Invalid JSON-LD',\n raw: value,\n });\n }\n }\n\n return values;\n}\n\nexport const metadataCollector: CheckpointCollector = {\n name: 'metadata',\n defaultEnabled: true,\n\n async collect(ctx) {\n const metadata = await ctx.page.evaluate(() => {\n const meta = (selector: string): string | null => document.querySelector(selector)?.getAttribute('content') ?? null;\n const canonicalLink = document.querySelector('link[rel=\"canonical\"]');\n const html = document.documentElement;\n const structuredDataScripts = Array.from(document.querySelectorAll('script[type=\"application/ld+json\"]')).map((script) => script.textContent ?? null);\n\n return {\n url: location.href,\n title: document.title,\n description: meta('meta[name=\"description\"]'),\n openGraph: {\n title: meta('meta[property=\"og:title\"]'),\n description: meta('meta[property=\"og:description\"]'),\n image: meta('meta[property=\"og:image\"]'),\n },\n canonicalUrl: canonicalLink?.getAttribute('href') ?? null,\n lang: html.getAttribute('lang'),\n viewport: meta('meta[name=\"viewport\"]'),\n structuredDataScripts,\n };\n });\n\n const normalizedMetadata: PageMetadata = {\n url: metadata.url,\n title: metadata.title,\n description: metadata.description,\n openGraph: metadata.openGraph,\n canonicalUrl: metadata.canonicalUrl,\n lang: metadata.lang,\n viewport: metadata.viewport,\n structuredData: normalizeStructuredData(metadata.structuredDataScripts),\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'metadata.json');\n await fs.writeFile(outputPath, `${JSON.stringify(normalizedMetadata, null, 2)}\\n`, 'utf8');\n\n return {\n data: normalizedMetadata,\n artifacts: [\n {\n name: 'metadata',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n url: normalizedMetadata.url,\n title: normalizedMetadata.title,\n lang: normalizedMetadata.lang,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page, Request, Response } from '@playwright/test';\nimport type { CheckpointCollector, FailedRequestRecord } from '../types';\n\ntype NetworkCollectorState = {\n entries: FailedRequestRecord[];\n offset: number;\n recordRequestFailure: (request: Request) => void;\n recordHttpError: (response: Response) => void;\n};\n\nconst networkStates = new WeakMap<Page, NetworkCollectorState>();\n\nexport const networkCollector: CheckpointCollector = {\n name: 'network',\n defaultEnabled: true,\n\n async setup({ page }) {\n if (networkStates.has(page)) {\n return;\n }\n\n const entries: FailedRequestRecord[] = [];\n\n const recordRequestFailure = (request: Request): void => {\n entries.push({\n kind: 'requestfailed',\n url: request.url(),\n method: request.method(),\n status: null,\n statusText: null,\n failureText: request.failure()?.errorText ?? null,\n timestamp: new Date().toISOString(),\n });\n };\n\n const recordHttpError = (response: Response): void => {\n if (response.status() < 400) {\n return;\n }\n\n entries.push({\n kind: 'http-error',\n url: response.url(),\n method: response.request().method(),\n status: response.status(),\n statusText: response.statusText(),\n failureText: null,\n timestamp: new Date().toISOString(),\n });\n };\n\n page.on('requestfailed', recordRequestFailure);\n page.on('response', recordHttpError);\n\n networkStates.set(page, {\n entries,\n offset: 0,\n recordRequestFailure,\n recordHttpError,\n });\n },\n\n async collect(ctx) {\n const state = networkStates.get(ctx.page);\n const checkpointEntries = state ? state.entries.slice(state.offset) : [];\n\n if (state) {\n state.offset = state.entries.length;\n }\n\n const outputPath = path.join(ctx.checkpointDir, 'failed-requests.json');\n await fs.writeFile(outputPath, `${JSON.stringify(checkpointEntries, null, 2)}\\n`, 'utf8');\n\n return {\n data: checkpointEntries,\n artifacts: [\n {\n name: 'failed-requests',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n failedRequestCount: checkpointEntries.length,\n },\n };\n },\n\n async teardown({ page }) {\n const state = networkStates.get(page);\n if (!state) {\n return;\n }\n\n page.off('requestfailed', state.recordRequestFailure);\n page.off('response', state.recordHttpError);\n networkStates.delete(page);\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page, Response } from '@playwright/test';\nimport type {\n CheckpointCollector,\n NetworkTimingCollectorData,\n NetworkTimingRecord,\n} from '../types';\n\ntype ResponseEventRecord = {\n url: string;\n status: number | null;\n statusText: string | null;\n resourceType: string | null;\n timestamp: string;\n};\n\ntype ResourceTimingRecord = {\n name: string;\n duration: number;\n transferSize: number;\n encodedBodySize: number;\n decodedBodySize: number;\n nextHopProtocol: string;\n startTime: number;\n redirectStart: number;\n redirectEnd: number;\n domainLookupStart: number;\n domainLookupEnd: number;\n connectStart: number;\n connectEnd: number;\n secureConnectionStart: number;\n requestStart: number;\n responseStart: number;\n responseEnd: number;\n};\n\ntype NetworkTimingCollectorState = {\n responses: ResponseEventRecord[];\n responseOffset: number;\n resourceOffsetByUrl: Map<string, number>;\n recordResponse: (response: Response) => void;\n};\n\nconst timingStates = new WeakMap<Page, NetworkTimingCollectorState>();\n\nfunction maybeDuration(start: number, end: number): number | null {\n if (start <= 0 || end <= 0 || end < start) {\n return null;\n }\n\n return end - start;\n}\n\nfunction toNetworkRecord(response: ResponseEventRecord, timing: ResourceTimingRecord | null): NetworkTimingRecord {\n return {\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n resourceType: response.resourceType,\n timestamp: response.timestamp,\n durationMs: timing ? timing.duration : null,\n transferSize: timing ? timing.transferSize : null,\n encodedBodySize: timing ? timing.encodedBodySize : null,\n decodedBodySize: timing ? timing.decodedBodySize : null,\n nextHopProtocol: timing ? timing.nextHopProtocol || null : null,\n timing: {\n startTimeMs: timing ? timing.startTime : null,\n redirectMs: timing ? maybeDuration(timing.redirectStart, timing.redirectEnd) : null,\n dnsMs: timing ? maybeDuration(timing.domainLookupStart, timing.domainLookupEnd) : null,\n connectMs: timing ? maybeDuration(timing.connectStart, timing.connectEnd) : null,\n tlsMs: timing ? maybeDuration(timing.secureConnectionStart, timing.connectEnd) : null,\n requestMs: timing ? maybeDuration(timing.requestStart, timing.responseStart) : null,\n responseMs: timing ? maybeDuration(timing.responseStart, timing.responseEnd) : null,\n },\n };\n}\n\nexport const networkTimingCollector: CheckpointCollector = {\n name: 'network-timing',\n defaultEnabled: false,\n\n async setup({ page }) {\n if (timingStates.has(page)) {\n return;\n }\n\n const responses: ResponseEventRecord[] = [];\n\n const recordResponse = (response: Response): void => {\n responses.push({\n url: response.url(),\n status: response.status(),\n statusText: response.statusText(),\n resourceType: response.request().resourceType(),\n timestamp: new Date().toISOString(),\n });\n };\n\n page.on('response', recordResponse);\n\n timingStates.set(page, {\n responses,\n responseOffset: 0,\n resourceOffsetByUrl: new Map<string, number>(),\n recordResponse,\n });\n },\n\n async collect(ctx) {\n const state = timingStates.get(ctx.page);\n const recentResponses = state ? state.responses.slice(state.responseOffset) : [];\n\n if (state) {\n state.responseOffset = state.responses.length;\n }\n\n const resourceTimings = (await ctx.page.evaluate(() => {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n return entries.map((entry) => ({\n name: entry.name,\n duration: entry.duration,\n transferSize: entry.transferSize,\n encodedBodySize: entry.encodedBodySize,\n decodedBodySize: entry.decodedBodySize,\n nextHopProtocol: entry.nextHopProtocol,\n startTime: entry.startTime,\n redirectStart: entry.redirectStart,\n redirectEnd: entry.redirectEnd,\n domainLookupStart: entry.domainLookupStart,\n domainLookupEnd: entry.domainLookupEnd,\n connectStart: entry.connectStart,\n connectEnd: entry.connectEnd,\n secureConnectionStart: entry.secureConnectionStart,\n requestStart: entry.requestStart,\n responseStart: entry.responseStart,\n responseEnd: entry.responseEnd,\n }));\n })) as ResourceTimingRecord[];\n\n const timingsByUrl = new Map<string, ResourceTimingRecord[]>();\n for (const timing of resourceTimings) {\n const list = timingsByUrl.get(timing.name);\n if (list) {\n list.push(timing);\n } else {\n timingsByUrl.set(timing.name, [timing]);\n }\n }\n\n const requests: NetworkTimingRecord[] = recentResponses.map((response) => {\n if (!state) {\n return toNetworkRecord(response, null);\n }\n\n const list = timingsByUrl.get(response.url) ?? [];\n const currentOffset = state.resourceOffsetByUrl.get(response.url) ?? 0;\n const match = list[currentOffset] ?? null;\n\n if (match) {\n state.resourceOffsetByUrl.set(response.url, currentOffset + 1);\n }\n\n return toNetworkRecord(response, match);\n });\n\n const totalBytes = requests.reduce((total, request) => {\n if (typeof request.transferSize !== 'number' || request.transferSize < 0) {\n return total;\n }\n\n return total + request.transferSize;\n }, 0);\n\n const slowestRequestMs = requests.reduce((slowest, request) => {\n if (typeof request.durationMs !== 'number') {\n return slowest;\n }\n\n return Math.max(slowest, request.durationMs);\n }, 0);\n\n const data: NetworkTimingCollectorData = {\n requestCount: requests.length,\n totalBytes,\n slowestRequestMs,\n requests,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'network-timing.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'network-timing',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n requestCount: data.requestCount,\n totalBytes: data.totalBytes,\n slowestRequestMs: data.slowestRequestMs,\n },\n };\n },\n\n async teardown({ page }) {\n const state = timingStates.get(page);\n if (!state) {\n return;\n }\n\n page.off('response', state.recordResponse);\n timingStates.delete(page);\n },\n};\n","import path from 'node:path';\nimport type { CheckpointCollector, ScreenshotCollectorData } from '../types';\n\nconst PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);\n\nfunction readPngSize(buffer: Buffer): ScreenshotCollectorData['imageSize'] {\n if (buffer.length < 24 || !buffer.subarray(0, 8).equals(PNG_SIGNATURE)) {\n return null;\n }\n\n if (buffer.toString('ascii', 12, 16) !== 'IHDR') {\n return null;\n }\n\n return {\n width: buffer.readUInt32BE(16),\n height: buffer.readUInt32BE(20),\n };\n}\n\nexport const screenshotCollector: CheckpointCollector = {\n name: 'screenshot',\n defaultEnabled: true,\n\n async collect(ctx) {\n const fullPage = ctx.options.fullPage ?? true;\n const screenshotPath = path.join(ctx.checkpointDir, 'page.png');\n const screenshotBuffer = await ctx.page.screenshot({ path: screenshotPath, fullPage });\n\n let highlightBounds: ScreenshotCollectorData['highlightBounds'] = null;\n if (ctx.options.highlightSelector) {\n highlightBounds = await ctx.page\n .locator(ctx.options.highlightSelector)\n .boundingBox()\n .catch(() => null);\n }\n\n return {\n data: {\n fullPage,\n highlightBounds,\n highlightSelector: ctx.options.highlightSelector ?? null,\n imageSize: Buffer.isBuffer(screenshotBuffer) ? readPngSize(screenshotBuffer) : null,\n } satisfies ScreenshotCollectorData,\n artifacts: [\n {\n name: 'screenshot',\n path: screenshotPath,\n contentType: 'image/png',\n },\n ],\n summary: {\n screenshotPath: 'page.png',\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n CheckpointCollector,\n StorageCollectorData,\n StorageCookieState,\n StorageEntryState,\n} from '../types';\n\nconst REDACTED = '[REDACTED]';\nconst DEFAULT_REDACT_PATTERNS = ['password', 'token', 'secret', 'api[_-]?key', 'authorization', 'session', 'email'];\nconst EMAIL_LIKE_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\ntype RawCookie = {\n name: string;\n domain: string;\n path: string;\n value: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: string;\n};\n\ntype RawStorageEntry = {\n key: string;\n value: string;\n};\n\nfunction toRegex(pattern: string): RegExp | null {\n const trimmed = pattern.trim();\n if (!trimmed) {\n return null;\n }\n\n try {\n return new RegExp(trimmed, 'i');\n } catch {\n return null;\n }\n}\n\nfunction buildRedactionRegexes(ctx: { redact: string[]; config: Record<string, unknown> }): RegExp[] {\n const fromConfig = Array.isArray(ctx.config.redact)\n ? ctx.config.redact.filter((entry): entry is string => typeof entry === 'string')\n : [];\n\n return [...DEFAULT_REDACT_PATTERNS, ...ctx.redact, ...fromConfig]\n .map((pattern) => toRegex(pattern))\n .filter((value): value is RegExp => value instanceof RegExp);\n}\n\nfunction shouldRedact(identifier: string, value: string | null, regexes: RegExp[]): boolean {\n if (regexes.some((regex) => regex.test(identifier))) {\n return true;\n }\n\n if (!value) {\n return false;\n }\n\n if (EMAIL_LIKE_REGEX.test(value.trim())) {\n return true;\n }\n\n return regexes.some((regex) => regex.test(value));\n}\n\nexport const storageCollector: CheckpointCollector = {\n name: 'storage',\n defaultEnabled: false,\n\n async collect(ctx) {\n const includeCookieValues = ctx.config.includeCookieValues === true;\n const includeLocalStorageValues = ctx.config.includeLocalStorageValues === true;\n const redactValues = ctx.config.redactValues !== false;\n const regexes = buildRedactionRegexes({ redact: ctx.redact, config: ctx.config });\n\n const cookies = (await ctx.page.context().cookies()) as RawCookie[];\n const localStorageEntries = await ctx.page.evaluate(() =>\n Object.keys(localStorage).map((key) => ({\n key,\n value: localStorage.getItem(key) ?? '',\n })),\n );\n\n const normalizedCookies: StorageCookieState[] = cookies.map((cookie) => {\n const rawValue = includeCookieValues ? cookie.value : null;\n const redacted = redactValues && shouldRedact(cookie.name, rawValue, regexes);\n\n return {\n name: cookie.name,\n domain: cookie.domain,\n path: cookie.path,\n value: rawValue == null ? null : redacted ? REDACTED : rawValue,\n redacted,\n expires: cookie.expires,\n httpOnly: cookie.httpOnly,\n secure: cookie.secure,\n sameSite: cookie.sameSite,\n };\n });\n\n const normalizedLocalStorage: StorageEntryState[] = (localStorageEntries as RawStorageEntry[]).map((entry) => {\n const rawValue = includeLocalStorageValues ? entry.value : null;\n const redacted = redactValues && shouldRedact(entry.key, rawValue, regexes);\n\n return {\n key: entry.key,\n value: rawValue == null ? null : redacted ? REDACTED : rawValue,\n redacted,\n };\n });\n\n const data: StorageCollectorData = {\n cookieCount: normalizedCookies.length,\n localStorageKeyCount: normalizedLocalStorage.length,\n cookies: normalizedCookies,\n localStorage: normalizedLocalStorage,\n };\n\n const outputPath = path.join(ctx.checkpointDir, 'storage-state.json');\n await fs.writeFile(outputPath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n\n return {\n data,\n artifacts: [\n {\n name: 'storage-state',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n cookieCount: data.cookieCount,\n localStorageKeyCount: data.localStorageKeyCount,\n },\n };\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Page } from '@playwright/test';\nimport type {\n CheckpointCollector,\n WebVitalMetric,\n WebVitalRating,\n WebVitalsSnapshot,\n} from '../types';\n\ntype RawWebVitals = {\n cls: number | null;\n fcp: number | null;\n lcp: number | null;\n inp: number | null;\n ttfb: number | null;\n domContentLoaded: number | null;\n loadEvent: number | null;\n url: string;\n};\n\nconst initializedPages = new WeakSet<Page>();\n\nfunction rateMetric(\n value: number | null,\n thresholds: { good: number; needsImprovement: number },\n): WebVitalRating {\n if (value == null || Number.isNaN(value)) {\n return 'unknown';\n }\n if (value <= thresholds.good) {\n return 'good';\n }\n if (value <= thresholds.needsImprovement) {\n return 'needs-improvement';\n }\n return 'poor';\n}\n\nfunction metric(value: number | null, thresholds: { good: number; needsImprovement: number }): WebVitalMetric {\n return {\n value,\n rating: rateMetric(value, thresholds),\n };\n}\n\nasync function captureWebVitals(page: Page): Promise<WebVitalsSnapshot> {\n const raw = await page.evaluate(() => {\n const globalState = globalThis as typeof globalThis & {\n __e2eWebVitals?: {\n cls: number;\n fcp: number | null;\n lcp: number | null;\n inp: number | null;\n };\n };\n\n const state = globalState.__e2eWebVitals ?? {\n cls: 0,\n fcp: null,\n lcp: null,\n inp: null,\n };\n const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming | undefined;\n\n return {\n cls: state.cls,\n fcp: state.fcp,\n lcp: state.lcp,\n inp: state.inp,\n ttfb: navigation ? navigation.responseStart : null,\n domContentLoaded: navigation ? navigation.domContentLoadedEventEnd : null,\n loadEvent: navigation ? navigation.loadEventEnd : null,\n url: location.href,\n } satisfies RawWebVitals;\n });\n\n return {\n url: raw.url,\n capturedAt: new Date().toISOString(),\n cls: metric(raw.cls, { good: 0.1, needsImprovement: 0.25 }),\n fcpMs: metric(raw.fcp, { good: 1800, needsImprovement: 3000 }),\n lcpMs: metric(raw.lcp, { good: 2500, needsImprovement: 4000 }),\n inpMs: metric(raw.inp, { good: 200, needsImprovement: 500 }),\n ttfbMs: metric(raw.ttfb, { good: 800, needsImprovement: 1800 }),\n domContentLoadedMs: raw.domContentLoaded,\n loadEventMs: raw.loadEvent,\n };\n}\n\nexport const webVitalsCollector: CheckpointCollector = {\n name: 'web-vitals',\n defaultEnabled: true,\n\n async setup({ page }) {\n if (initializedPages.has(page)) {\n return;\n }\n\n initializedPages.add(page);\n\n await page.addInitScript(() => {\n const globalState = globalThis as typeof globalThis & {\n __e2eWebVitals?: {\n cls: number;\n fcp: number | null;\n lcp: number | null;\n inp: number | null;\n };\n };\n\n if (!globalState.__e2eWebVitals) {\n globalState.__e2eWebVitals = {\n cls: 0,\n fcp: null,\n lcp: null,\n inp: null,\n };\n }\n\n const state = globalState.__e2eWebVitals;\n\n try {\n const paintObserver = new PerformanceObserver((entryList) => {\n for (const entry of entryList.getEntries()) {\n if (entry.name === 'first-contentful-paint') {\n state.fcp = entry.startTime;\n }\n }\n });\n paintObserver.observe({ type: 'paint', buffered: true });\n } catch {\n // Unsupported in this browser context.\n }\n\n try {\n const lcpObserver = new PerformanceObserver((entryList) => {\n const entries = entryList.getEntries();\n const lastEntry = entries[entries.length - 1];\n if (lastEntry) {\n state.lcp = lastEntry.startTime;\n }\n });\n lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });\n addEventListener('pagehide', () => lcpObserver.disconnect(), { once: true });\n } catch {\n // Unsupported in this browser context.\n }\n\n try {\n const clsObserver = new PerformanceObserver((entryList) => {\n for (const entry of entryList.getEntries() as Array<PerformanceEntry & { hadRecentInput?: boolean; value?: number }>) {\n if (!entry.hadRecentInput) {\n state.cls += entry.value ?? 0;\n }\n }\n });\n clsObserver.observe({ type: 'layout-shift', buffered: true });\n addEventListener('pagehide', () => clsObserver.disconnect(), { once: true });\n } catch {\n // Unsupported in this browser context.\n }\n\n try {\n const inpObserver = new PerformanceObserver((entryList) => {\n for (const entry of entryList.getEntries() as Array<PerformanceEntry & { duration?: number }>) {\n const duration = entry.duration ?? 0;\n if (state.inp == null || duration > state.inp) {\n state.inp = duration;\n }\n }\n });\n inpObserver.observe({ type: 'event', buffered: true, durationThreshold: 40 } as PerformanceObserverInit);\n addEventListener('pagehide', () => inpObserver.disconnect(), { once: true });\n } catch {\n // Unsupported in this browser context.\n }\n });\n },\n\n async collect(ctx) {\n const snapshot = await captureWebVitals(ctx.page);\n const outputPath = path.join(ctx.checkpointDir, 'web-vitals.json');\n\n await fs.writeFile(outputPath, `${JSON.stringify(snapshot, null, 2)}\\n`, 'utf8');\n\n return {\n data: snapshot,\n artifacts: [\n {\n name: 'web-vitals',\n path: outputPath,\n contentType: 'application/json',\n },\n ],\n summary: {\n cls: snapshot.cls,\n fcp: snapshot.fcpMs,\n lcp: snapshot.lcpMs,\n inp: snapshot.inpMs,\n ttfb: snapshot.ttfbMs,\n },\n };\n },\n\n async teardown({ page }) {\n initializedPages.delete(page);\n },\n};\n","import { ariaSnapshotCollector } from './aria-snapshot';\nimport { axeCollector } from './axe';\nimport { consoleCollector } from './console';\nimport { domStatsCollector } from './dom-stats';\nimport { formsCollector } from './forms';\nimport { htmlCollector } from './html';\nimport { metadataCollector } from './metadata';\nimport { networkCollector } from './network';\nimport { networkTimingCollector } from './network-timing';\nimport { screenshotCollector } from './screenshot';\nimport { storageCollector } from './storage';\nimport { webVitalsCollector } from './web-vitals';\n\nexport const builtinCollectors = [\n screenshotCollector,\n htmlCollector,\n axeCollector,\n webVitalsCollector,\n consoleCollector,\n networkCollector,\n metadataCollector,\n ariaSnapshotCollector,\n domStatsCollector,\n formsCollector,\n storageCollector,\n networkTimingCollector,\n];\n","import type { CheckpointCollector } from '../types';\n\nconst builtinCollectors = new Map<string, CheckpointCollector>();\nlet builtinsRegistered = false;\n\nexport function registerBuiltinCollector(collector: CheckpointCollector): void {\n builtinCollectors.set(collector.name, collector);\n}\n\nexport function registerBuiltinCollectors(collectors: CheckpointCollector[]): void {\n if (builtinsRegistered) {\n return;\n }\n\n for (const collector of collectors) {\n registerBuiltinCollector(collector);\n }\n\n builtinsRegistered = true;\n}\n\nexport function getBuiltinCollectors(): Map<string, CheckpointCollector> {\n return new Map(builtinCollectors);\n}\n"],"mappings":"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","names":["fs","path","fs","path","path","fs","fs","path","location","fs","path","fs","path","fs","path","path","fs","fs","path","fs","path","fs","path","path","fs","path","REDACTED","DEFAULT_REDACT_PATTERNS","EMAIL_LIKE_REGEX","toRegex","fs","path","builtinCollectors","fs","path"]}