@flighthq/tool-capture 0.3.0 → 0.3.1-next.1041.35b950c

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 (82) hide show
  1. package/README.md +1 -1
  2. package/dist/baselineStore.d.ts +12 -1
  3. package/dist/baselineStore.d.ts.map +1 -1
  4. package/dist/baselineStore.js +83 -6
  5. package/dist/baselineStore.js.map +1 -1
  6. package/dist/bin.js +80 -6
  7. package/dist/bin.js.map +1 -1
  8. package/dist/captureBaselineCoverageManifest.d.ts +80 -0
  9. package/dist/captureBaselineCoverageManifest.d.ts.map +1 -0
  10. package/dist/captureBaselineCoverageManifest.js +178 -0
  11. package/dist/captureBaselineCoverageManifest.js.map +1 -0
  12. package/dist/captureBaselineSanity.d.ts +9 -0
  13. package/dist/captureBaselineSanity.d.ts.map +1 -0
  14. package/dist/captureBaselineSanity.js +32 -0
  15. package/dist/captureBaselineSanity.js.map +1 -0
  16. package/dist/captureBenchmark.d.ts.map +1 -1
  17. package/dist/captureBenchmark.js +5 -1
  18. package/dist/captureBenchmark.js.map +1 -1
  19. package/dist/captureDomReadback.d.ts +4 -0
  20. package/dist/captureDomReadback.d.ts.map +1 -0
  21. package/dist/captureDomReadback.js +51 -0
  22. package/dist/captureDomReadback.js.map +1 -0
  23. package/dist/captureEntry.d.ts +12 -3
  24. package/dist/captureEntry.d.ts.map +1 -1
  25. package/dist/captureEntry.js +87 -36
  26. package/dist/captureEntry.js.map +1 -1
  27. package/dist/captureEntryFilter.d.ts +5 -0
  28. package/dist/captureEntryFilter.d.ts.map +1 -0
  29. package/dist/captureEntryFilter.js +23 -0
  30. package/dist/captureEntryFilter.js.map +1 -0
  31. package/dist/captureFlightPreset.js +10 -4
  32. package/dist/captureFlightPreset.js.map +1 -1
  33. package/dist/captureProtocol.d.ts +3 -0
  34. package/dist/captureProtocol.d.ts.map +1 -1
  35. package/dist/captureProtocol.js.map +1 -1
  36. package/dist/captureResourceFailure.d.ts +4 -0
  37. package/dist/captureResourceFailure.d.ts.map +1 -0
  38. package/dist/captureResourceFailure.js +31 -0
  39. package/dist/captureResourceFailure.js.map +1 -0
  40. package/dist/captureScreenshotHash.d.ts +30 -0
  41. package/dist/captureScreenshotHash.d.ts.map +1 -0
  42. package/dist/captureScreenshotHash.js +108 -0
  43. package/dist/captureScreenshotHash.js.map +1 -0
  44. package/dist/captureServer.d.ts +8 -0
  45. package/dist/captureServer.d.ts.map +1 -1
  46. package/dist/captureServer.js +126 -22
  47. package/dist/captureServer.js.map +1 -1
  48. package/dist/captureSuite.d.ts +11 -0
  49. package/dist/captureSuite.d.ts.map +1 -1
  50. package/dist/captureSuite.js +6 -4
  51. package/dist/captureSuite.js.map +1 -1
  52. package/dist/captureValidation.d.ts +20 -3
  53. package/dist/captureValidation.d.ts.map +1 -1
  54. package/dist/captureValidation.js +222 -70
  55. package/dist/captureValidation.js.map +1 -1
  56. package/dist/captureWorkflow.d.ts.map +1 -1
  57. package/dist/captureWorkflow.js +3 -0
  58. package/dist/captureWorkflow.js.map +1 -1
  59. package/dist/functionalScene3Ds.d.ts.map +1 -1
  60. package/dist/functionalScene3Ds.js +5 -3
  61. package/dist/functionalScene3Ds.js.map +1 -1
  62. package/dist/functionalVerify.d.ts.map +1 -1
  63. package/dist/functionalVerify.js +57 -16
  64. package/dist/functionalVerify.js.map +1 -1
  65. package/package.json +5 -5
  66. package/src/baselineStore.test.ts +210 -7
  67. package/src/bin.test.ts +32 -0
  68. package/src/captureBaselineCoverageManifest.test.ts +368 -0
  69. package/src/captureBaselineSanity.test.ts +38 -0
  70. package/src/captureBenchmark.e2e.test.ts +29 -1
  71. package/src/captureDomReadback.test.ts +35 -0
  72. package/src/captureEntry.e2e.test.ts +108 -0
  73. package/src/captureEntryFilter.test.ts +45 -0
  74. package/src/captureEyes.e2e.test.ts +43 -0
  75. package/src/captureFlightPreset.test.ts +10 -0
  76. package/src/capturePage.test.ts +23 -3
  77. package/src/captureResourceFailure.test.ts +60 -0
  78. package/src/captureScreenshotHash.test.ts +142 -0
  79. package/src/captureServer.test.ts +103 -3
  80. package/src/captureValidation.test.ts +217 -36
  81. package/src/functionalScene3Ds.test.ts +7 -0
  82. package/src/functionalVerify.test.ts +33 -3
@@ -0,0 +1,30 @@
1
+ /** The slice of Playwright's `Page` this needs — narrow so a test can supply a double. */
2
+ export interface CaptureScreenshotHashPage {
3
+ evaluate<Result, Argument>(fn: (argument: Argument) => Promise<Result>, argument: Argument): Promise<Result>;
4
+ }
5
+ /**
6
+ * SHA-256 over the screenshot's decoded pixels, prefixed by its dimensions.
7
+ *
8
+ * Dimensions are in the digest because RGBA bytes alone do not pin them: a 100x50 frame and a 50x100
9
+ * frame with the same pixel sequence would otherwise collide, and a resize is exactly the kind of change
10
+ * a capture baseline exists to notice.
11
+ *
12
+ * Throws if the page cannot decode the screenshot. That is deliberate and not a sentinel: falling back
13
+ * to hashing the encoded bytes would silently produce a value that means something DIFFERENT from every
14
+ * other value in the same column, which is worse than a failed capture because nothing downstream could
15
+ * tell the two apart.
16
+ */
17
+ export declare function hashCaptureScreenshotPixels(page: CaptureScreenshotHashPage, screenshot: Uint8Array, blankCoverage: number | null): Promise<string>;
18
+ /**
19
+ * The same hash, or `null` when the page cannot produce one.
20
+ *
21
+ * For the ERROR path only. There the page may already be crashed or navigated away — which is often the
22
+ * very reason the capture failed — and throwing would destroy the error report on its way out, turning a
23
+ * recorded failure into an unrecorded one. `hash` is already nullable on that path, so a missing hash is
24
+ * a shape the consumer handles; an exception is not.
25
+ *
26
+ * Deliberately NOT used on the success path: there, an undecodable screenshot means the capture did not
27
+ * produce what it claims, and silently writing `null` would let a broken capture look like a partial one.
28
+ */
29
+ export declare function hashCaptureScreenshotPixelsOrNull(page: CaptureScreenshotHashPage, screenshot: Uint8Array, blankCoverage: number | null): Promise<string | null>;
30
+ //# sourceMappingURL=captureScreenshotHash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureScreenshotHash.d.ts","sourceRoot":"","sources":["../src/captureScreenshotHash.ts"],"names":[],"mappings":"AA8BA,0FAA0F;AAC1F,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9G;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,yBAAyB,EAC/B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,OAAO,CAAC,MAAM,CAAC,CA2DjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iCAAiC,CACrD,IAAI,EAAE,yBAAyB,EAC/B,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExB"}
@@ -0,0 +1,108 @@
1
+ // Hashes what a capture RENDERED, not how it was encoded.
2
+ //
3
+ // The screenshot arrives as PNG bytes — Playwright's `page.screenshot()`, or a base64 canvas dataURL.
4
+ // Hashing those bytes answers "did the encoded artifact change", which is not the question a capture
5
+ // baseline is asked: a PNG encoder that changed its filter heuristics, its compression level, or its
6
+ // ancillary chunks moves the hash while every pixel is identical, and a real render change is
7
+ // indistinguishable from that. Decoding to RGBA first makes the hash answer "did the render change".
8
+ //
9
+ // THE DECODE HAPPENS IN THE PAGE, because nothing in this repo can decode a PNG in Node —
10
+ // `@flighthq/image-codec` is a registry whose real decoders are browser-supplied, and no PNG decoder is
11
+ // installed. The browser already does this natively and is already open at the hash site (the page is
12
+ // not closed until the `finally` well after), so this reuses a mechanism the capture path already
13
+ // depends on rather than adding a dependency.
14
+ //
15
+ // WHAT IS HASHED IS NOT LITERALLY THE FILE'S SAMPLES: drawImage into a 2d canvas may apply alpha
16
+ // premultiplication and colour-space conversion. The digest stays deterministic and still tracks the
17
+ // render, which is what it is for — but do not read it as byte-identity with the PNG's decoded pixels.
18
+ //
19
+ // The threshold is a PARAMETER rather than an import so this module stays free of captureEntry.
20
+ //
21
+ // ★ PASS null WHEN THE SCENE'S OWN VERIFIER HAS ALREADY APPROVED THE FRAME, AND MEAN IT. A scene declares
22
+ // its own `minCoverage`, and functionalVerify honours that declaration; a scene that renders a full-canvas
23
+ // solid colour on purpose sets it to 0 and validates itself with a pixel oracle instead. Applying a global
24
+ // coverage threshold here after such a frame has PASSED overrules the only party that knows what the scene
25
+ // is for, and refuses a correct render. Two blank checks in one capture must not answer to different
26
+ // thresholds — so when the verifier has ruled, this one does not run at all.
27
+ //
28
+ // The DIGEST is computed in the page too, so only a 64-character hex string crosses the bridge. Shipping
29
+ // the pixels back would be ~1.9M bytes per capture for an 800x600 frame, per column, per run.
30
+ /**
31
+ * SHA-256 over the screenshot's decoded pixels, prefixed by its dimensions.
32
+ *
33
+ * Dimensions are in the digest because RGBA bytes alone do not pin them: a 100x50 frame and a 50x100
34
+ * frame with the same pixel sequence would otherwise collide, and a resize is exactly the kind of change
35
+ * a capture baseline exists to notice.
36
+ *
37
+ * Throws if the page cannot decode the screenshot. That is deliberate and not a sentinel: falling back
38
+ * to hashing the encoded bytes would silently produce a value that means something DIFFERENT from every
39
+ * other value in the same column, which is worse than a failed capture because nothing downstream could
40
+ * tell the two apart.
41
+ */
42
+ export async function hashCaptureScreenshotPixels(page, screenshot, blankCoverage) {
43
+ const base64 = Buffer.from(screenshot).toString('base64');
44
+ const hash = await page.evaluate(async (input) => {
45
+ const response = await fetch(`data:image/png;base64,${input.base64}`);
46
+ const bitmap = await createImageBitmap(await response.blob());
47
+ const canvas = document.createElement('canvas');
48
+ canvas.width = bitmap.width;
49
+ canvas.height = bitmap.height;
50
+ const context = canvas.getContext('2d');
51
+ if (context === null)
52
+ throw new Error('hashCaptureScreenshotPixels: no 2d context to decode into');
53
+ context.drawImage(bitmap, 0, 0);
54
+ const pixels = context.getImageData(0, 0, bitmap.width, bitmap.height).data;
55
+ // BLANK CHECK, using the capture path's own coverage definition and threshold rather than a second
56
+ // one: the fraction of pixels differing from the top-left (background) sample by more than 8 in any
57
+ // channel. A decode can succeed with correct dimensions and byte count and still yield nothing —
58
+ // a re-read of a WebGPU swapchain does exactly that — and a digest of a blank frame is a perfectly
59
+ // well-formed hash of no information. Shape validation cannot catch it; only content can.
60
+ const backgroundR = pixels[0];
61
+ const backgroundG = pixels[1];
62
+ const backgroundB = pixels[2];
63
+ let differing = 0;
64
+ const total = bitmap.width * bitmap.height;
65
+ for (let index = 0; index < total; index++) {
66
+ const offset = index * 4;
67
+ if (Math.abs(pixels[offset] - backgroundR) > 8 ||
68
+ Math.abs(pixels[offset + 1] - backgroundG) > 8 ||
69
+ Math.abs(pixels[offset + 2] - backgroundB) > 8) {
70
+ differing += 1;
71
+ }
72
+ }
73
+ if (input.blankCoverage !== null && differing / total <= input.blankCoverage)
74
+ return 'blank';
75
+ // `<width>x<height>:` then the raw RGBA, hashed as one buffer.
76
+ const header = new TextEncoder().encode(`${bitmap.width}x${bitmap.height}:`);
77
+ const payload = new Uint8Array(header.length + pixels.length);
78
+ payload.set(header, 0);
79
+ payload.set(pixels, header.length);
80
+ const digest = await crypto.subtle.digest('SHA-256', payload);
81
+ return Array.from(new Uint8Array(digest))
82
+ .map((byte) => byte.toString(16).padStart(2, '0'))
83
+ .join('');
84
+ }, { base64, blankCoverage });
85
+ if (hash === 'blank') {
86
+ throw new Error('hashCaptureScreenshotPixels: the decoded screenshot is blank (coverage at or below the empty-frame ' +
87
+ 'threshold), so its digest would be a well-formed hash of no render');
88
+ }
89
+ if (typeof hash !== 'string' || !/^[0-9a-f]{64}$/.test(hash)) {
90
+ throw new Error(`hashCaptureScreenshotPixels: page returned '${String(hash)}' rather than a sha256 hex digest`);
91
+ }
92
+ return hash;
93
+ }
94
+ /**
95
+ * The same hash, or `null` when the page cannot produce one.
96
+ *
97
+ * For the ERROR path only. There the page may already be crashed or navigated away — which is often the
98
+ * very reason the capture failed — and throwing would destroy the error report on its way out, turning a
99
+ * recorded failure into an unrecorded one. `hash` is already nullable on that path, so a missing hash is
100
+ * a shape the consumer handles; an exception is not.
101
+ *
102
+ * Deliberately NOT used on the success path: there, an undecodable screenshot means the capture did not
103
+ * produce what it claims, and silently writing `null` would let a broken capture look like a partial one.
104
+ */
105
+ export async function hashCaptureScreenshotPixelsOrNull(page, screenshot, blankCoverage) {
106
+ return hashCaptureScreenshotPixels(page, screenshot, blankCoverage).catch(() => null);
107
+ }
108
+ //# sourceMappingURL=captureScreenshotHash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureScreenshotHash.js","sourceRoot":"","sources":["../src/captureScreenshotHash.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,14 @@ export interface Server {
3
3
  url: string;
4
4
  kill(): void;
5
5
  }
6
+ /**
7
+ * Explains when a served build predates the newest source it was built from.
8
+ *
9
+ * Returns null when the build is at least as new as the source, so a fresh build stays silent.
10
+ * Timestamps are millisecond epochs; a missing one (null) yields no verdict, since a comparison that
11
+ * could not be made must not read as reassurance.
12
+ */
13
+ export declare function explainCaptureDistStaleness(builtAt: number | null, sourceChangedAt: number | null): string | null;
6
14
  /** Serves an already-built directory on an ephemeral localhost port for a capture suite. */
7
15
  export declare function resolveCaptureDirectoryServer(directory: string): Promise<Server>;
8
16
  export declare function resolveServer(opts: {
@@ -1 +1 @@
1
- {"version":3,"file":"captureServer.d.ts","sourceRoot":"","sources":["../src/captureServer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,IAAI,IAAI,CAAC;CACd;AAED,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA8DxG;AAKD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB7G"}
1
+ {"version":3,"file":"captureServer.d.ts","sourceRoot":"","sources":["../src/captureServer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAGhD,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,IAAI,IAAI,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAMjH;AAED,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA8DxG;AA6ED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgD7G"}
@@ -2,9 +2,23 @@
2
2
  // Node.js static server over a pre-built dist (the default, faster), or an already-running external
3
3
  // URL. Each resolves to a { url, kill } handle the capture loop drives pages against.
4
4
  import { spawn, spawnSync } from 'node:child_process';
5
- import { existsSync, readFileSync } from 'node:fs';
5
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
6
6
  import { createServer } from 'node:http';
7
7
  import { basename, extname, join, relative } from 'node:path';
8
+ import { discoverFunctionalScene3Ds } from './functionalScene3Ds.js';
9
+ /**
10
+ * Explains when a served build predates the newest source it was built from.
11
+ *
12
+ * Returns null when the build is at least as new as the source, so a fresh build stays silent.
13
+ * Timestamps are millisecond epochs; a missing one (null) yields no verdict, since a comparison that
14
+ * could not be made must not read as reassurance.
15
+ */
16
+ export function explainCaptureDistStaleness(builtAt, sourceChangedAt) {
17
+ if (builtAt === null || sourceChangedAt === null || builtAt >= sourceChangedAt)
18
+ return null;
19
+ return ('The static build is older than the current source. This capture measures the PREVIOUS code, so a ' +
20
+ 'change under test will look like it had no effect.');
21
+ }
8
22
  /** Serves an already-built directory on an ephemeral localhost port for a capture suite. */
9
23
  export function resolveCaptureDirectoryServer(directory) {
10
24
  return serveDirectory(directory);
@@ -59,27 +73,6 @@ export function resolveServer(opts) {
59
73
  proc.on('error', reject);
60
74
  });
61
75
  }
62
- // Serve a pre-built tool dist from a lightweight Node.js HTTP server, bypassing the Vite dev
63
- // server and its on-demand transform overhead. Auto-builds when dist is absent; pass forceBuild to
64
- // always rebuild (e.g. for baseline captures that must be authoritative).
65
- export function resolveStaticServer(opts) {
66
- const { tool, root, forceBuild = false } = opts;
67
- const toolDir = tool === 'examples' ? join(root, 'examples', 'runners', 'web') : join(root, 'tools', tool);
68
- const distDir = join(toolDir, 'dist');
69
- if (!existsSync(distDir) || forceBuild) {
70
- console.log(`Building tools/${tool}…`);
71
- const workspace = tool === 'examples' ? '@flighthq/examples' : `tools/${tool}`;
72
- const args = ['run', 'build', `--workspace=${workspace}`];
73
- const result = runNpm(args, root);
74
- if (result.status !== 0) {
75
- return Promise.reject(new Error(`Build failed. Run "npm run build:${tool}" to debug.`));
76
- }
77
- }
78
- if (!existsSync(distDir)) {
79
- return Promise.reject(new Error(`No build found at ${distDir} after build. Run "npm run build:${tool}" to debug.`));
80
- }
81
- return serveDirectory(distDir);
82
- }
83
76
  function runNpm(args, cwd) {
84
77
  const npmExecPath = process.env['npm_execpath'];
85
78
  // `npx tsx ...` also sets npm_execpath, but to npx-cli.js. Passing `run build` back to that CLI asks
@@ -145,4 +138,115 @@ const DEV_SCRIPT = {
145
138
  functional: 'dev:functional',
146
139
  reference: 'dev:reference',
147
140
  };
141
+ // Serve a pre-built tool dist from a lightweight Node.js HTTP server, bypassing the Vite dev
142
+ // server and its on-demand transform overhead. Auto-builds when dist is absent; pass forceBuild to
143
+ // always rebuild (e.g. for baseline captures that must be authoritative).
144
+ export function resolveStaticServer(opts) {
145
+ const { tool, root, forceBuild = false } = opts;
146
+ const toolDir = tool === 'examples' ? join(root, 'examples', 'runners', 'web') : join(root, 'tools', tool);
147
+ const distDir = join(toolDir, 'dist');
148
+ if (!existsSync(distDir) || forceBuild) {
149
+ console.log(`Building tools/${tool}…`);
150
+ const workspace = tool === 'examples' ? '@flighthq/examples' : `tools/${tool}`;
151
+ const args = ['run', 'build', `--workspace=${workspace}`];
152
+ const result = runNpm(args, root);
153
+ if (result.status !== 0) {
154
+ return Promise.reject(new Error(`Build failed. Run "npm run build:${tool}" to debug.`));
155
+ }
156
+ }
157
+ if (!existsSync(distDir)) {
158
+ return Promise.reject(new Error(`No build found at ${distDir} after build. Run "npm run build:${tool}" to debug.`));
159
+ }
160
+ if (tool === 'functional') {
161
+ const { discovered, missing } = getMissingFunctionalCaptureRoutes(root, distDir);
162
+ if (missing.length > 0) {
163
+ return Promise.reject(new Error(`Functional dist is missing ${missing.length} of ${discovered.length} discovered routes, so it cannot serve the current suite. Run "npm run build:functional" and retry. Missing: ${missing.join(', ')}`));
164
+ }
165
+ }
166
+ // A capture served from a stale dist measures the code as it was BEFORE the edit under test, and
167
+ // answers with the pre-change result — which reads as "the change had no effect" rather than as a
168
+ // failure to observe it. That is the most persuasive wrong answer available, so say it out loud.
169
+ // ★ DELIBERATELY WIDE: this fires on ANY capture-source edit, including a tool-capture change that
170
+ // cannot affect the bundle, and costs an unnecessary rebuild when it does. That is the accepted price.
171
+ // Narrowing it to "sources that actually reach the bundle" is how the defect it exists to prevent comes
172
+ // back — a stale dist silently served 22 missing routes and cost the fleet most of a day, and every
173
+ // narrowing is a new chance to mis-classify one source as irrelevant. Pay the rebuild.
174
+ const staleness = explainCaptureDistStaleness(newestModifiedTime(distDir), newestCaptureSourceModifiedTime(tool, root));
175
+ if (staleness !== null) {
176
+ return Promise.reject(new Error(`${staleness} Run "npm run build:${tool}" and retry.`));
177
+ }
178
+ return serveDirectory(distDir);
179
+ }
180
+ function getMissingFunctionalCaptureRoutes(root, distDir) {
181
+ const scenes = discoverFunctionalScene3Ds(join(root, 'functional', 'scenes'));
182
+ const discovered = scenes.flatMap((scene) => scene.renderers.map((renderer) => `tests/${scene.name}/${renderer}/`));
183
+ return {
184
+ discovered,
185
+ missing: discovered.filter((route) => !existsSync(join(distDir, route, 'index.html'))),
186
+ };
187
+ }
188
+ function newestCaptureSourceModifiedTime(tool, root) {
189
+ const sources = tool === 'functional'
190
+ ? [
191
+ join(root, 'packages'),
192
+ join(root, 'functional', 'scenes'),
193
+ join(root, 'tools', 'functional'),
194
+ join(root, 'tools', 'harness'),
195
+ ]
196
+ : tool === 'examples'
197
+ ? [join(root, 'packages'), join(root, 'examples', 'packages'), join(root, 'examples', 'runners', 'web')]
198
+ : [];
199
+ let newest = null;
200
+ for (const source of sources) {
201
+ const time = newestModifiedTime(source);
202
+ if (time !== null && (newest === null || time > newest))
203
+ newest = time;
204
+ }
205
+ return newest;
206
+ }
207
+ /** Newest modification time under a directory tree, or null when it cannot be read. */
208
+ function newestModifiedTime(directory) {
209
+ try {
210
+ const stats = statSync(directory);
211
+ if (!stats.isDirectory())
212
+ return stats.mtimeMs;
213
+ }
214
+ catch {
215
+ return null;
216
+ }
217
+ let newest = null;
218
+ const walk = (current, depth) => {
219
+ if (depth > 6)
220
+ return;
221
+ let entries;
222
+ try {
223
+ entries = readdirSync(current, { withFileTypes: true });
224
+ }
225
+ catch {
226
+ return;
227
+ }
228
+ for (const entry of entries) {
229
+ if (entry.name === 'node_modules' ||
230
+ entry.name === 'dist' ||
231
+ entry.name === 'dev-dist' ||
232
+ entry.name.startsWith('.'))
233
+ continue;
234
+ const path = join(current, entry.name);
235
+ if (entry.isDirectory()) {
236
+ walk(path, depth + 1);
237
+ continue;
238
+ }
239
+ try {
240
+ const time = statSync(path).mtimeMs;
241
+ if (newest === null || time > newest)
242
+ newest = time;
243
+ }
244
+ catch {
245
+ // A file that vanished mid-walk simply does not contribute a timestamp.
246
+ }
247
+ }
248
+ };
249
+ walk(directory, 0);
250
+ return newest;
251
+ }
148
252
  //# sourceMappingURL=captureServer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"captureServer.js","sourceRoot":"","sources":["../src/captureServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"captureServer.js","sourceRoot":"","sources":["../src/captureServer.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { CaptureBaselineProvenance } from '@flighthq/types/contract';
1
2
  import type { CaptureBrowserSession } from './captureBrowser.js';
2
3
  import type { Entry } from './captureEntries.js';
3
4
  import type { CaptureTargetReport } from './captureEntry.js';
@@ -13,6 +14,8 @@ export interface CaptureSuiteOptions {
13
14
  outBase?: string;
14
15
  rendererFilter?: Readonly<string[]>;
15
16
  filter?: string;
17
+ /** Exact entry name. Unlike `filter`, selects nothing beyond the name given — use it when writing. */
18
+ filterExact?: string;
16
19
  captureFrames?: number;
17
20
  extraWait?: number;
18
21
  updateBaseline?: boolean;
@@ -29,6 +32,13 @@ export interface CaptureSuiteOptions {
29
32
  reportPath?: string | false;
30
33
  }
31
34
  export type CaptureFingerprintMap = Record<string, Record<string, string>>;
35
+ /**
36
+ * Provenance for fingerprints published by the same captures, keyed identically to CaptureFingerprintMap.
37
+ * Kept as a PARALLEL map rather than folded into the value so a consumer that stamps provenance and one
38
+ * that only needs the fingerprint string stay independent — and so a fingerprint can never arrive with a
39
+ * provenance that describes a different capture.
40
+ */
41
+ export type CaptureFingerprintProvenanceMap = Record<string, Record<string, CaptureBaselineProvenance>>;
32
42
  export interface CaptureSuiteResult {
33
43
  aborted: boolean;
34
44
  captured: number;
@@ -37,6 +47,7 @@ export interface CaptureSuiteResult {
37
47
  shouldFail: boolean;
38
48
  /** Assertion-passed fingerprints collected as a by-product of capture. */
39
49
  fingerprints: CaptureFingerprintMap;
50
+ fingerprintProvenance: CaptureFingerprintProvenanceMap;
40
51
  durationMs: number;
41
52
  targets: CaptureTargetReport[];
42
53
  reportPath: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"captureSuite.d.ts","sourceRoot":"","sources":["../src/captureSuite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAI7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,sGAAsG;IACtG,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yGAAyG;IACzG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,EAAE,qBAAqB,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA+FzG"}
1
+ {"version":3,"file":"captureSuite.d.ts","sourceRoot":"","sources":["../src/captureSuite.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAI1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAK7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,sGAAsG;IACtG,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yGAAyG;IACzG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sGAAsG;IACtG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,MAAM,+BAA+B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;AAExG,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,EAAE,qBAAqB,CAAC;IACpC,qBAAqB,EAAE,+BAA+B,CAAC;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqGzG"}
@@ -5,6 +5,7 @@ import { resolve } from 'node:path';
5
5
  import pc from 'picocolors';
6
6
  import { launchBrowser } from './captureBrowser.js';
7
7
  import { captureParallel, isVerifiedCaptureTool } from './captureEntry.js';
8
+ import { selectCaptureEntriesByName } from './captureEntryFilter.js';
8
9
  import { formatSummaryCount, formatSummaryLine } from './captureFormat.js';
9
10
  import { installAbortHandler } from './captureInterrupt.js';
10
11
  import { writeCaptureReport } from './captureReport.js';
@@ -13,9 +14,7 @@ export async function runCaptureSuite(options) {
13
14
  const root = resolve(options.root ?? process.cwd());
14
15
  const outBase = resolve(root, options.outBase ?? '.artifacts');
15
16
  const rendererFilter = [...(options.rendererFilter ?? [])];
16
- const entries = options.filter
17
- ? options.entries.filter((entry) => entry.name.includes(options.filter))
18
- : [...options.entries];
17
+ const entries = selectCaptureEntriesByName(options.entries, options.filter, options.filterExact);
19
18
  if (entries.length === 0)
20
19
  throw new Error(`No capture entries found subject=${options.subject}`);
21
20
  const captureFrames = options.captureFrames ?? 0;
@@ -37,8 +36,10 @@ export async function runCaptureSuite(options) {
37
36
  let failed = 0;
38
37
  let targets = [];
39
38
  const fingerprints = {};
40
- const onVerifiedFingerprint = (entry, renderer, fingerprint) => {
39
+ const fingerprintProvenance = {};
40
+ const onVerifiedFingerprint = (entry, renderer, fingerprint, provenance) => {
41
41
  (fingerprints[entry] ??= {})[renderer] = fingerprint;
42
+ (fingerprintProvenance[entry] ??= {})[renderer] = provenance;
42
43
  };
43
44
  try {
44
45
  const result = await captureParallel({
@@ -93,6 +94,7 @@ export async function runCaptureSuite(options) {
93
94
  failed,
94
95
  shouldFail,
95
96
  fingerprints,
97
+ fingerprintProvenance,
96
98
  durationMs: Math.round((performance.now() - startedAt) * 100) / 100,
97
99
  targets,
98
100
  reportPath,
@@ -1 +1 @@
1
- {"version":3,"file":"captureSuite.js","sourceRoot":"","sources":["../src/captureSuite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"captureSuite.js","sourceRoot":"","sources":["../src/captureSuite.ts"],"names":[],"mappings":"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"}
@@ -2,17 +2,21 @@ import type { CaptureBrowserSession } from './captureBrowser.js';
2
2
  import type { Entry } from './captureEntries.js';
3
3
  import type { CaptureParityGroup } from './captureManifest.js';
4
4
  import type { Server } from './captureServer.js';
5
- import type { CaptureFingerprintMap } from './captureSuite.js';
5
+ import type { CaptureFingerprintMap, CaptureFingerprintProvenanceMap } from './captureSuite.js';
6
6
  export interface CaptureValidationOptions {
7
7
  subject: string;
8
8
  entries: Readonly<Entry[]>;
9
9
  server: Server;
10
10
  root?: string;
11
11
  filter?: string;
12
+ /** Exact entry name. Unlike `filter`, selects nothing beyond the name given — use it when writing. */
13
+ filterExact?: string;
12
14
  rendererFilter?: Readonly<string[]>;
13
15
  captureFrames?: number;
14
16
  report?: boolean;
15
17
  updateFingerprints?: boolean;
18
+ /** Accept the observed coverage as the new capture baseline coverage manifest instead of gating on it. */
19
+ updateCoverage?: boolean;
16
20
  gateRegression?: boolean;
17
21
  gateParity?: boolean;
18
22
  stabilityEpsilon?: number;
@@ -38,6 +42,7 @@ export interface CaptureValidationOptions {
38
42
  parityGroups?: Readonly<Record<string, Readonly<CaptureParityGroup>>>;
39
43
  /** Assertion-passed fingerprints from a preceding capture pass. Avoids reloading those pages. */
40
44
  fingerprints?: Readonly<CaptureFingerprintMap>;
45
+ fingerprintProvenance?: Readonly<CaptureFingerprintProvenanceMap>;
41
46
  /** Reuse an already initialized browser/context. The caller owns its lifetime. */
42
47
  browserSession?: CaptureBrowserSession;
43
48
  /** Aggregate machine report path. Defaults to `.artifacts/<subject>/validation-report.json`. */
@@ -85,13 +90,25 @@ export interface CaptureValidationCheck {
85
90
  recordedSourceHash?: string | null;
86
91
  currentSourceHash?: string | null;
87
92
  }
88
- export declare function explainCaptureParityUncovered(eligibleCount: number, hasGroups: boolean): string;
93
+ export declare function explainCaptureParityUncovered(eligibleCount: number, hasGroups: boolean, unavailableReferences?: readonly string[]): string;
89
94
  export declare function explainCaptureVerificationStall(verification: Readonly<{
90
95
  fingerprint?: string | null;
91
96
  state?: string;
92
97
  }> | null, waitedMs: number): string;
98
+ /**
99
+ * Ranks measured parity distances, widest disagreement first.
100
+ *
101
+ * Returns null when nothing was compared, so a run that measured nothing prints no ranking rather
102
+ * than an empty one that would read as agreement.
103
+ */
104
+ export declare function formatCaptureParityRanking(checks: readonly Readonly<{
105
+ distance?: number;
106
+ entry: string;
107
+ kind: string;
108
+ renderers?: readonly string[];
109
+ }>[], limit?: number): string | null;
93
110
  export declare function isCaptureParityCoverageFailure(run: Readonly<CaptureParityCoverage>): boolean;
94
111
  export declare function isCaptureRegressionCoverageFailure(run: Readonly<CaptureRegressionCoverage>): boolean;
95
- export declare function isUniformCaptureFingerprint(fingerprint: string): boolean;
112
+ export { isUniformCaptureFingerprint } from './captureBaselineSanity.js';
96
113
  export declare function runCaptureValidation(input: Readonly<CaptureValidationOptions>): Promise<CaptureValidationResult>;
97
114
  //# sourceMappingURL=captureValidation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"captureValidation.d.ts","sourceRoot":"","sources":["../src/captureValidation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"captureValidation.d.ts","sourceRoot":"","sources":["../src/captureValidation.ts"],"names":[],"mappings":"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"}