@testivai/witness 2.3.1 → 2.5.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 (68) hide show
  1. package/dist/baselines/store.d.ts +17 -0
  2. package/dist/baselines/store.d.ts.map +1 -1
  3. package/dist/baselines/store.js +30 -1
  4. package/dist/baselines/store.js.map +1 -1
  5. package/dist/bin/testivai.js +2 -0
  6. package/dist/bin/testivai.js.map +1 -1
  7. package/dist/capture/environment.d.ts +217 -0
  8. package/dist/capture/environment.d.ts.map +1 -0
  9. package/dist/capture/environment.js +399 -0
  10. package/dist/capture/environment.js.map +1 -0
  11. package/dist/capture/settle.d.ts +7 -0
  12. package/dist/capture/settle.d.ts.map +1 -1
  13. package/dist/capture/settle.js +7 -0
  14. package/dist/capture/settle.js.map +1 -1
  15. package/dist/capture/stable-capture.d.ts +80 -0
  16. package/dist/capture/stable-capture.d.ts.map +1 -0
  17. package/dist/capture/stable-capture.js +106 -0
  18. package/dist/capture/stable-capture.js.map +1 -0
  19. package/dist/commands/env.d.ts +37 -0
  20. package/dist/commands/env.d.ts.map +1 -0
  21. package/dist/commands/env.js +113 -0
  22. package/dist/commands/env.js.map +1 -0
  23. package/dist/config/local-config.d.ts +14 -0
  24. package/dist/config/local-config.d.ts.map +1 -1
  25. package/dist/config/local-config.js +1 -0
  26. package/dist/config/local-config.js.map +1 -1
  27. package/dist/config/validate-config.d.ts.map +1 -1
  28. package/dist/config/validate-config.js +12 -0
  29. package/dist/config/validate-config.js.map +1 -1
  30. package/dist/index.d.ts +5 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +28 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/report/anchor.d.ts +18 -0
  35. package/dist/report/anchor.d.ts.map +1 -0
  36. package/dist/report/anchor.js +51 -0
  37. package/dist/report/anchor.js.map +1 -0
  38. package/dist/report/compare.d.ts +7 -0
  39. package/dist/report/compare.d.ts.map +1 -1
  40. package/dist/report/compare.js +22 -2
  41. package/dist/report/compare.js.map +1 -1
  42. package/dist/report/environment.d.ts +101 -0
  43. package/dist/report/environment.d.ts.map +1 -0
  44. package/dist/report/environment.js +331 -0
  45. package/dist/report/environment.js.map +1 -0
  46. package/dist/report/generator.d.ts +7 -2
  47. package/dist/report/generator.d.ts.map +1 -1
  48. package/dist/report/generator.js +33 -6
  49. package/dist/report/generator.js.map +1 -1
  50. package/dist/report/index.d.ts +5 -2
  51. package/dist/report/index.d.ts.map +1 -1
  52. package/dist/report/index.js +11 -1
  53. package/dist/report/index.js.map +1 -1
  54. package/dist/report/results.d.ts +33 -0
  55. package/dist/report/results.d.ts.map +1 -1
  56. package/dist/report/template.d.ts +28 -1
  57. package/dist/report/template.d.ts.map +1 -1
  58. package/dist/report/template.js +127 -15
  59. package/dist/report/template.js.map +1 -1
  60. package/dist/report/validate.d.ts +50 -0
  61. package/dist/report/validate.d.ts.map +1 -0
  62. package/dist/report/validate.js +343 -0
  63. package/dist/report/validate.js.map +1 -0
  64. package/dist/standalone/run.d.ts +12 -0
  65. package/dist/standalone/run.d.ts.map +1 -1
  66. package/dist/standalone/run.js +55 -53
  67. package/dist/standalone/run.js.map +1 -1
  68. package/package.json +1 -1
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+ /**
3
+ * Capture provenance — where a capture came from.
4
+ *
5
+ * When the same URL renders differently, the question a reviewer needs
6
+ * answered first is whether the PAGE changed or the MACHINE did: a new
7
+ * browser build, another OS or distro (another set of fonts), another device
8
+ * scale, another way of taking the screenshot. Every adapter records the
9
+ * same `environment` block in the capture's metadata.json; approving a
10
+ * capture freezes it into the baseline's metadata.json, and the compare
11
+ * reads the two side by side (report/environment.ts).
12
+ *
13
+ * The block is plain JSON, so non-JS adapters write the same shape
14
+ * (docs/extension-api.md). Every part an adapter cannot observe is left out,
15
+ * never guessed: an absent field reads as "not recorded", not as a change.
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.RENDER_PROBE_EXPRESSION = exports.ENVIRONMENT_POLICIES = exports.CAPTURE_METHODS = void 0;
52
+ exports.distroFromOsRelease = distroFromOsRelease;
53
+ exports.detectCi = detectCi;
54
+ exports.collectHostEnvironment = collectHostEnvironment;
55
+ exports.browserFromUserAgent = browserFromUserAgent;
56
+ exports.browserFromCapabilities = browserFromCapabilities;
57
+ exports.installedPackageVersion = installedPackageVersion;
58
+ exports.parseRenderProbe = parseRenderProbe;
59
+ exports.buildCaptureEnvironment = buildCaptureEnvironment;
60
+ exports.webDriverEnvironment = webDriverEnvironment;
61
+ exports.readEnvironment = readEnvironment;
62
+ exports.applyEnvironmentPolicyToName = applyEnvironmentPolicyToName;
63
+ exports.parseEnvironmentVariant = parseEnvironmentVariant;
64
+ const fs = __importStar(require("fs"));
65
+ const os = __importStar(require("os"));
66
+ /**
67
+ * How the screenshot was taken, as `<extent>:<mechanism>`. The extent is what
68
+ * the image covers (the full page or the viewport); the mechanism is what
69
+ * took it. A change of method changes the image, and often its size.
70
+ */
71
+ exports.CAPTURE_METHODS = {
72
+ /** CDP Page.captureScreenshot with captureBeyondViewport. */
73
+ CDP_FULL_PAGE: 'full-page:cdp',
74
+ /** Playwright page.screenshot({ fullPage: true }). */
75
+ PLAYWRIGHT_FULL_PAGE: 'full-page:playwright',
76
+ /** Viewport screenshots scrolled and stitched together. */
77
+ STITCHED_FULL_PAGE: 'full-page:stitched',
78
+ /** Firefox's own full-page screenshot (Selenium save_full_page_screenshot). */
79
+ FIREFOX_FULL_PAGE: 'full-page:firefox',
80
+ /** WebDriver takeScreenshot: the viewport only. */
81
+ WEBDRIVER_VIEWPORT: 'viewport:webdriver',
82
+ };
83
+ exports.ENVIRONMENT_POLICIES = ['warn', 'separate', 'strict'];
84
+ // ── Host ────────────────────────────────────────────────────────────────────
85
+ /**
86
+ * The distro from /etc/os-release, as `<ID> <VERSION_ID>` ("ubuntu 24.04",
87
+ * "debian 12"; "arch" for a rolling release). That pair decides the fonts and
88
+ * the FreeType build a Linux machine draws text with; the kernel does not.
89
+ */
90
+ function distroFromOsRelease(text) {
91
+ const fields = {};
92
+ for (const line of text.split(/\r?\n/)) {
93
+ const m = /^([A-Z_]+)=(.*)$/.exec(line.trim());
94
+ if (m)
95
+ fields[m[1]] = m[2].replace(/^["']|["']$/g, '');
96
+ }
97
+ if (!fields.ID)
98
+ return undefined;
99
+ return fields.VERSION_ID ? `${fields.ID} ${fields.VERSION_ID}` : fields.ID;
100
+ }
101
+ /** The CI provider, and the runner image where the provider names one. */
102
+ function detectCi(env) {
103
+ if (env.GITHUB_ACTIONS === 'true') {
104
+ const runnerImage = env.ImageOS && env.ImageVersion ? `${env.ImageOS}/${env.ImageVersion}` : undefined;
105
+ return runnerImage ? { provider: 'github-actions', runnerImage } : { provider: 'github-actions' };
106
+ }
107
+ if (env.GITLAB_CI)
108
+ return { provider: 'gitlab' };
109
+ if (env.CIRCLECI)
110
+ return { provider: 'circleci' };
111
+ if (env.BUILDKITE)
112
+ return { provider: 'buildkite' };
113
+ if (env.JENKINS_URL)
114
+ return { provider: 'jenkins' };
115
+ if (env.TF_BUILD)
116
+ return { provider: 'azure-pipelines' };
117
+ if (env.CI && env.CI !== 'false' && env.CI !== '0')
118
+ return { provider: 'ci' };
119
+ return undefined;
120
+ }
121
+ const safely = (fn, fallback) => {
122
+ try {
123
+ return fn();
124
+ }
125
+ catch {
126
+ return fallback;
127
+ }
128
+ };
129
+ /** The machine-level part of the block. Never throws. */
130
+ function collectHostEnvironment(sources = {}) {
131
+ const env = sources.env ?? process.env;
132
+ const platform = sources.platform ?? process.platform;
133
+ const readFile = sources.readFile ?? ((p) => safely(() => fs.readFileSync(p, 'utf-8'), null));
134
+ const exists = sources.exists ?? ((p) => fs.existsSync(p));
135
+ const host = {
136
+ os: {
137
+ platform,
138
+ release: sources.release ?? safely(() => os.release(), ''),
139
+ arch: sources.arch ?? process.arch,
140
+ },
141
+ };
142
+ if (platform === 'linux') {
143
+ const text = safely(() => readFile('/etc/os-release'), null);
144
+ const distro = text ? distroFromOsRelease(text) : undefined;
145
+ if (distro)
146
+ host.os.distro = distro;
147
+ }
148
+ const ci = detectCi(env);
149
+ if (ci)
150
+ host.ci = ci;
151
+ if (safely(() => exists('/.dockerenv') || exists('/run/.containerenv'), false))
152
+ host.container = true;
153
+ const label = (env.TESTIVAI_ENV_LABEL ?? '').trim();
154
+ if (label)
155
+ host.label = label;
156
+ return host;
157
+ }
158
+ // ── Browser ─────────────────────────────────────────────────────────────────
159
+ /**
160
+ * The engine and its version from a user agent: the fallback for an adapter
161
+ * whose driver does not say (a Playwright persistent context has no
162
+ * browser() to ask). Edge is reported as chromium with channel msedge, the
163
+ * way Playwright names it.
164
+ */
165
+ function browserFromUserAgent(ua) {
166
+ if (!ua)
167
+ return null;
168
+ const edge = /\bEdg\/([\d.]+)/.exec(ua);
169
+ const chrome = /\b(HeadlessChrome|Chrome|Chromium)\/([\d.]+)/.exec(ua);
170
+ if (chrome) {
171
+ const browser = { name: 'chromium', version: chrome[2] };
172
+ if (chrome[1] === 'HeadlessChrome')
173
+ browser.headless = true;
174
+ if (edge)
175
+ browser.channel = 'msedge';
176
+ return browser;
177
+ }
178
+ const firefox = /\bFirefox\/([\d.]+)/.exec(ua);
179
+ if (firefox)
180
+ return { name: 'firefox', version: firefox[1] };
181
+ // Two linear matches, not /Version\/([\d.]+).*Safari\//: that pattern
182
+ // backtracks quadratically on a long run of dots.
183
+ const safari = /\bVersion\/([\d.]+)/.exec(ua);
184
+ if (safari && /\bSafari\//.test(ua.slice(safari.index + safari[0].length)))
185
+ return { name: 'webkit', version: safari[1] };
186
+ return null;
187
+ }
188
+ /** WebDriver browserName values, normalized to the engine family and its branded channel. */
189
+ const WEBDRIVER_BROWSERS = {
190
+ chrome: { name: 'chromium', channel: 'chrome', driver: 'chromedriver' },
191
+ 'chrome-headless-shell': { name: 'chromium', channel: 'chrome-headless-shell', driver: 'chromedriver' },
192
+ chromium: { name: 'chromium', driver: 'chromedriver' },
193
+ microsoftedge: { name: 'chromium', channel: 'msedge', driver: 'msedgedriver' },
194
+ msedge: { name: 'chromium', channel: 'msedge', driver: 'msedgedriver' },
195
+ firefox: { name: 'firefox', driver: 'geckodriver' },
196
+ safari: { name: 'webkit', channel: 'safari' },
197
+ };
198
+ /** The first token of a driver version string ("141.0.7390.37 (hash-refs/…)" → "141.0.7390.37"). */
199
+ const firstToken = (v) => (typeof v === 'string' && v.trim() ? v.trim().split(/\s+/)[0] : undefined);
200
+ /**
201
+ * The browser (and the WebDriver binary) from W3C capabilities, as
202
+ * WebdriverIO's `browser.capabilities` or selenium-webdriver's
203
+ * `getCapabilities()` returns them (a plain object, or an object with
204
+ * `get()`). Headless is read from the browser's own launch arguments, and
205
+ * only said when they are there to say it. Null without a browser name.
206
+ */
207
+ function browserFromCapabilities(caps) {
208
+ if (!caps || typeof caps !== 'object')
209
+ return null;
210
+ const c = caps;
211
+ const get = (key) => (typeof c.get === 'function' ? c.get(key) : c[key]);
212
+ const rawName = get('browserName');
213
+ if (typeof rawName !== 'string' || rawName.length === 0)
214
+ return null;
215
+ const known = WEBDRIVER_BROWSERS[rawName.toLowerCase()];
216
+ const version = get('browserVersion') ?? get('version');
217
+ const browser = {
218
+ name: known?.name ?? rawName.toLowerCase(),
219
+ version: typeof version === 'string' && version.length > 0 ? version : null,
220
+ };
221
+ if (known?.channel)
222
+ browser.channel = known.channel;
223
+ const options = (get('goog:chromeOptions') ?? get('ms:edgeOptions') ?? get('moz:firefoxOptions'));
224
+ if (options && Array.isArray(options.args)) {
225
+ browser.headless = options.args.some((a) => typeof a === 'string' && /^-{1,2}headless(=|$)/.test(a));
226
+ }
227
+ let driverVersion;
228
+ if (known?.driver === 'chromedriver')
229
+ driverVersion = firstToken(get('chrome')?.chromedriverVersion);
230
+ if (known?.driver === 'msedgedriver')
231
+ driverVersion = firstToken(get('msedge')?.msedgedriverVersion);
232
+ if (known?.driver === 'geckodriver')
233
+ driverVersion = firstToken(get('moz:geckodriverVersion'));
234
+ return driverVersion && known?.driver ? { browser, driver: { name: known.driver, version: driverVersion } } : { browser };
235
+ }
236
+ /**
237
+ * The version of a package as the project at `root` resolves it (the user's
238
+ * own webdriverio or selenium-webdriver, not one bundled here), or null.
239
+ */
240
+ function installedPackageVersion(name, root = process.cwd()) {
241
+ try {
242
+ const pkgPath = require.resolve(`${name}/package.json`, { paths: [root] });
243
+ const version = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')).version;
244
+ return typeof version === 'string' ? version : null;
245
+ }
246
+ catch {
247
+ return null;
248
+ }
249
+ }
250
+ // ── Render probe ────────────────────────────────────────────────────────────
251
+ /**
252
+ * One self-contained in-page expression (no imports, no closures) that
253
+ * measures what the page is actually rendered with. Measured, not taken from
254
+ * configuration: a config can say 1280×720 at scale 1 while the browser
255
+ * renders something else. Each field is read on its own, so one missing API
256
+ * never loses the rest.
257
+ */
258
+ exports.RENDER_PROBE_EXPRESSION = `(function () {
259
+ var out = {};
260
+ try { out.viewport = { width: window.innerWidth, height: window.innerHeight }; } catch (e) {}
261
+ try { out.deviceScaleFactor = window.devicePixelRatio; } catch (e) {}
262
+ try { out.colorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } catch (e) {}
263
+ try { out.reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'reduce' : 'no-preference'; } catch (e) {}
264
+ try { out.locale = navigator.language; } catch (e) {}
265
+ try { out.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (e) {}
266
+ try { out.userAgent = navigator.userAgent; } catch (e) {}
267
+ return out;
268
+ })()`;
269
+ const isNumber = (v) => typeof v === 'number' && Number.isFinite(v);
270
+ const isString = (v) => typeof v === 'string' && v.length > 0;
271
+ /** Validate the probe's result. Mistyped fields are dropped, never trusted. */
272
+ function parseRenderProbe(raw) {
273
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
274
+ return null;
275
+ const r = raw;
276
+ const render = {};
277
+ const vp = r.viewport;
278
+ if (vp && isNumber(vp.width) && isNumber(vp.height))
279
+ render.viewport = { width: vp.width, height: vp.height };
280
+ if (isNumber(r.deviceScaleFactor))
281
+ render.deviceScaleFactor = r.deviceScaleFactor;
282
+ if (r.colorScheme === 'light' || r.colorScheme === 'dark')
283
+ render.colorScheme = r.colorScheme;
284
+ if (r.reducedMotion === 'reduce' || r.reducedMotion === 'no-preference')
285
+ render.reducedMotion = r.reducedMotion;
286
+ if (isString(r.locale))
287
+ render.locale = r.locale;
288
+ if (isString(r.timezone))
289
+ render.timezone = r.timezone;
290
+ return isString(r.userAgent) ? { render, userAgent: r.userAgent } : { render };
291
+ }
292
+ // ── Assembly ────────────────────────────────────────────────────────────────
293
+ /** Drop undefined members, so the block round-trips through JSON unchanged. */
294
+ function compact(value) {
295
+ const out = {};
296
+ for (const [k, v] of Object.entries(value))
297
+ if (v !== undefined)
298
+ out[k] = v;
299
+ return out;
300
+ }
301
+ /** Assemble the block from what one adapter observed. */
302
+ function buildCaptureEnvironment(parts) {
303
+ const { host } = parts;
304
+ // Built in the documented order (docs/extension-api.md), so metadata.json reads the same everywhere.
305
+ const env = {
306
+ os: compact({ ...host.os }),
307
+ browser: compact({ ...parts.browser }),
308
+ };
309
+ if (parts.framework)
310
+ env.framework = compact({ ...parts.framework });
311
+ env.adapter = { ...parts.adapter };
312
+ if (parts.driver)
313
+ env.driver = { ...parts.driver };
314
+ if (parts.render) {
315
+ const render = compact({ ...parts.render });
316
+ if (Object.keys(render).length > 0)
317
+ env.render = render;
318
+ }
319
+ if (host.ci)
320
+ env.ci = compact({ ...host.ci });
321
+ if (host.container)
322
+ env.container = true;
323
+ if (host.label)
324
+ env.label = host.label;
325
+ if (parts.project)
326
+ env.project = parts.project;
327
+ return env;
328
+ }
329
+ /**
330
+ * The block for a WebDriver adapter: the browser and driver from the
331
+ * capabilities (the user agent when they say nothing), the render settings
332
+ * from the probe. Null when neither names the browser: never guessed.
333
+ */
334
+ function webDriverEnvironment(input) {
335
+ const probed = parseRenderProbe(input.probe);
336
+ const fromCaps = browserFromCapabilities(input.capabilities);
337
+ const browser = fromCaps?.browser ?? (probed?.userAgent ? browserFromUserAgent(probed.userAgent) : null);
338
+ if (!browser)
339
+ return null;
340
+ return buildCaptureEnvironment({
341
+ host: input.host ?? collectHostEnvironment(),
342
+ browser,
343
+ framework: { ...input.framework },
344
+ adapter: input.adapter,
345
+ driver: fromCaps?.driver,
346
+ render: probed?.render,
347
+ });
348
+ }
349
+ /**
350
+ * The block as recorded in a metadata.json, or null when there is none:
351
+ * captures from before provenance, or from an adapter that does not record
352
+ * it. Only the three parts every recorder writes are required.
353
+ */
354
+ function readEnvironment(raw) {
355
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
356
+ return null;
357
+ const e = raw;
358
+ const obj = (v) => Boolean(v) && typeof v === 'object' && !Array.isArray(v);
359
+ if (!obj(e.os) || typeof e.os.platform !== 'string')
360
+ return null;
361
+ if (!obj(e.browser) || typeof e.browser.name !== 'string')
362
+ return null;
363
+ if (!obj(e.adapter) || typeof e.adapter.captureMethod !== 'string')
364
+ return null;
365
+ return e;
366
+ }
367
+ // ── separate policy ─────────────────────────────────────────────────────────
368
+ const safeSegment = (s) => s.replace(/[^a-z0-9_-]+/gi, '_').toLowerCase();
369
+ /** Node's process.platform values: a suffix ending in one of them is an environment variant. */
370
+ const PLATFORMS = ['aix', 'android', 'darwin', 'freebsd', 'haiku', 'linux', 'openbsd', 'sunos', 'win32', 'cygwin', 'netbsd'];
371
+ /**
372
+ * environmentPolicy "separate" keys each snapshot by environment:
373
+ * `<name>__<browser>__<platform>`, the same in-the-name mechanism as the
374
+ * Playwright multi-project variant, so the on-disk layout, results.json, the
375
+ * report, approvals and the approve action all work unchanged. A browser the
376
+ * name already ends with (a project named after it) is not repeated. Never
377
+ * keyed by version: a browser upgrade should be seen, not hidden behind a
378
+ * fresh baseline. Other policies return the name unchanged.
379
+ */
380
+ function applyEnvironmentPolicyToName(name, env, policy) {
381
+ if (policy !== 'separate')
382
+ return name;
383
+ const browser = safeSegment(env.browser.name);
384
+ const platform = safeSegment(env.os.platform);
385
+ const segments = name.split('__');
386
+ const withBrowser = segments.length > 1 && segments[segments.length - 1] === browser ? name : `${name}__${browser}`;
387
+ return `${withBrowser}__${platform}`;
388
+ }
389
+ /** The variant a separate-policy name carries, or null for a name without one. */
390
+ function parseEnvironmentVariant(name) {
391
+ const segments = name.split('__');
392
+ if (segments.length < 3)
393
+ return null;
394
+ const platform = segments[segments.length - 1];
395
+ if (!PLATFORMS.includes(platform))
396
+ return null;
397
+ return { base: segments.slice(0, -2).join('__'), browser: segments[segments.length - 2], platform };
398
+ }
399
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/capture/environment.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,13 @@
22
22
  * content that had not *loaded* yet — which is a load question, not a pixel
23
23
  * question.
24
24
  *
25
+ * One pixel question remains, and it is Chrome's, not the page's: a
26
+ * beyond-viewport capture can return a frame painted for the wrong viewport
27
+ * while the measured page is unchanged. That is guarded at capture time in
28
+ * capture/stable-capture.ts (fresh frame, then capture until two in a row
29
+ * match), which costs one extra screenshot on a stable page. This probe still
30
+ * decides when to start capturing.
31
+ *
25
32
  * WHAT THIS DOES
26
33
  * --------------
27
34
  * A cheap synchronous probe the adapter polls from the host language, exactly
@@ -1 +1 @@
1
- {"version":3,"file":"settle.d.ts","sourceRoot":"","sources":["../../src/capture/settle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,YAAY,EAAE,OAAO,CAAC;IACtB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B,EACD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,IAAI,KAAK;QAAE,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAA;CAAE,EAC3H,OAAO,EAAE,MAAM,GACd,WAAW,CAoDb;AAED,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,qFAAqF;AACrF,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,wDAAwD;AACxD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,MAAyB,GAAG,MAAM,CAErF;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0SAMxB,CAAC"}
1
+ {"version":3,"file":"settle.d.ts","sourceRoot":"","sources":["../../src/capture/settle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,YAAY,EAAE,OAAO,CAAC;IACtB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B,EACD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,IAAI,KAAK;QAAE,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAA;CAAE,EAC3H,OAAO,EAAE,MAAM,GACd,WAAW,CAoDb;AAED,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,qFAAqF;AACrF,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,wDAAwD;AACxD,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,MAAyB,GAAG,MAAM,CAErF;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0SAMxB,CAAC"}
@@ -23,6 +23,13 @@
23
23
  * content that had not *loaded* yet — which is a load question, not a pixel
24
24
  * question.
25
25
  *
26
+ * One pixel question remains, and it is Chrome's, not the page's: a
27
+ * beyond-viewport capture can return a frame painted for the wrong viewport
28
+ * while the measured page is unchanged. That is guarded at capture time in
29
+ * capture/stable-capture.ts (fresh frame, then capture until two in a row
30
+ * match), which costs one extra screenshot on a stable page. This probe still
31
+ * decides when to start capturing.
32
+ *
26
33
  * WHAT THIS DOES
27
34
  * --------------
28
35
  * A cheap synchronous probe the adapter polls from the host language, exactly
@@ -1 +1 @@
1
- {"version":3,"file":"settle.js","sourceRoot":"","sources":["../../src/capture/settle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settle.js","sourceRoot":"","sources":["../../src/capture/settle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Stable full-page capture — shared by every adapter that screenshots through
3
+ * CDP `Page.captureScreenshot` with `captureBeyondViewport`.
4
+ *
5
+ * THE PROBLEM
6
+ * -----------
7
+ * Chrome can hand back a frame painted with styles resolved against the wrong
8
+ * viewport while it sets up a beyond-viewport capture: narrow-viewport media
9
+ * rules, a collapsed `min-height: 100vh` hero, or text sized from a
10
+ * `@media (max-width: 480px)` body font. The page measures correctly (DOM,
11
+ * element map and computed styles all match the baseline) but the pixels do
12
+ * not, so an unchanged page flips between two renders from run to run and is
13
+ * reported as changed. Measured on the standalone CLI (an e2e fixture failed
14
+ * on nearly every attempt) and on a Playwright suite in CI (testivai-site's
15
+ * home page: 4.13% "changed" on one run, the same commit passing on re-run).
16
+ *
17
+ * THE GUARD
18
+ * ---------
19
+ * 1. Wait for a fresh frame — two animation frames, so every style and layout
20
+ * change made so far has been painted — before measuring and capturing.
21
+ * A forced layout alone does not prevent a stale frame; a rendered one does.
22
+ * 2. Capture until two captures in a row are identical, at most
23
+ * MAX_STABLE_CAPTURES. The capture after a wrong frame is almost always
24
+ * right. A stable page costs one extra screenshot; a page that never stops
25
+ * changing costs MAX_STABLE_CAPTURES, never an endless loop. The same wrong
26
+ * frame twice in a row would still be kept: rare, as it takes two misses.
27
+ *
28
+ * The helpers are transport-agnostic: the adapter supplies how to evaluate the
29
+ * frame wait in its page and how to take one capture.
30
+ */
31
+ /** How long the in-page frame wait waits for two frames before giving up. */
32
+ export declare const FRESH_FRAME_TIMEOUT_MS = 1000;
33
+ /**
34
+ * In-page expression an adapter awaits before capturing: resolves `true` once
35
+ * the page has rendered two animation frames (a frame produced after every
36
+ * style and layout change made so far has been painted), or `false` after
37
+ * FRESH_FRAME_TIMEOUT_MS for a page that renders no frames at all.
38
+ */
39
+ export declare const FRESH_FRAME_EXPRESSION = "new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), 1000);\n requestAnimationFrame(() => requestAnimationFrame(() => {\n clearTimeout(timer);\n resolve(true);\n }));\n})";
40
+ /**
41
+ * The most captures of one page while waiting for two in a row to match.
42
+ * Every stale-capture pattern measured settles within four (stale, good,
43
+ * good / good, stale, good, good).
44
+ */
45
+ export declare const MAX_STABLE_CAPTURES = 4;
46
+ /** Where the helpers report what they did; adapters route it to their debug output. */
47
+ export type CaptureLog = (message: string) => void;
48
+ /**
49
+ * Wait for a fresh frame, retrying once when none arrived in time (a loaded
50
+ * machine can stall a frame past the in-page timeout). Best-effort, never
51
+ * blocking and never throwing: if neither attempt sees a frame, the capture
52
+ * proceeds and the log says it may be stale.
53
+ *
54
+ * @param waitOnce Evaluates FRESH_FRAME_EXPRESSION in the page and resolves
55
+ * whether it saw two frames. A rejection (e.g. the page navigated away)
56
+ * counts as no frame.
57
+ * @param log Optional debug sink.
58
+ */
59
+ export declare function settleFreshFrame(waitOnce: () => Promise<boolean>, log?: CaptureLog): Promise<void>;
60
+ /** Options for {@link captureUntilStable}. */
61
+ export interface CaptureUntilStableOptions<T> {
62
+ /** Takes one capture of the page (e.g. base64 PNG data from CDP). */
63
+ capture: () => Promise<T>;
64
+ /** Runs before every recapture; typically `settleFreshFrame`. Not run before the first capture. */
65
+ settle: () => Promise<void>;
66
+ /** Whether two captures are the same pixels. Default: strict equality (right for base64 strings). */
67
+ same?: (a: T, b: T) => boolean;
68
+ /** Most captures to take. Default: MAX_STABLE_CAPTURES. */
69
+ maxCaptures?: number;
70
+ /** Optional debug sink. */
71
+ log?: CaptureLog;
72
+ }
73
+ /**
74
+ * Capture until two captures in a row match, at most `maxCaptures`, and return
75
+ * the matching capture (or the last one when none matched the one before it).
76
+ * The caller waits for a fresh frame before the first capture, usually before
77
+ * measuring the page; this settles again before every recapture.
78
+ */
79
+ export declare function captureUntilStable<T>(options: CaptureUntilStableOptions<T>): Promise<T>;
80
+ //# sourceMappingURL=stable-capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-capture.d.ts","sourceRoot":"","sources":["../../src/capture/stable-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,+MAMhC,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,uFAAuF;AACvF,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAYxG;AAED,8CAA8C;AAC9C,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,qEAAqE;IACrE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,mGAAmG;IACnG,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,qGAAqG;IACrG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;IAC/B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAe7F"}