@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.
- package/dist/baselines/store.d.ts +17 -0
- package/dist/baselines/store.d.ts.map +1 -1
- package/dist/baselines/store.js +30 -1
- package/dist/baselines/store.js.map +1 -1
- package/dist/bin/testivai.js +2 -0
- package/dist/bin/testivai.js.map +1 -1
- package/dist/capture/environment.d.ts +217 -0
- package/dist/capture/environment.d.ts.map +1 -0
- package/dist/capture/environment.js +399 -0
- package/dist/capture/environment.js.map +1 -0
- package/dist/capture/settle.d.ts +7 -0
- package/dist/capture/settle.d.ts.map +1 -1
- package/dist/capture/settle.js +7 -0
- package/dist/capture/settle.js.map +1 -1
- package/dist/capture/stable-capture.d.ts +80 -0
- package/dist/capture/stable-capture.d.ts.map +1 -0
- package/dist/capture/stable-capture.js +106 -0
- package/dist/capture/stable-capture.js.map +1 -0
- package/dist/commands/env.d.ts +37 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +113 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/config/local-config.d.ts +14 -0
- package/dist/config/local-config.d.ts.map +1 -1
- package/dist/config/local-config.js +1 -0
- package/dist/config/local-config.js.map +1 -1
- package/dist/config/validate-config.d.ts.map +1 -1
- package/dist/config/validate-config.js +12 -0
- package/dist/config/validate-config.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/report/anchor.d.ts +18 -0
- package/dist/report/anchor.d.ts.map +1 -0
- package/dist/report/anchor.js +51 -0
- package/dist/report/anchor.js.map +1 -0
- package/dist/report/compare.d.ts +7 -0
- package/dist/report/compare.d.ts.map +1 -1
- package/dist/report/compare.js +22 -2
- package/dist/report/compare.js.map +1 -1
- package/dist/report/environment.d.ts +101 -0
- package/dist/report/environment.d.ts.map +1 -0
- package/dist/report/environment.js +331 -0
- package/dist/report/environment.js.map +1 -0
- package/dist/report/generator.d.ts +7 -2
- package/dist/report/generator.d.ts.map +1 -1
- package/dist/report/generator.js +33 -6
- package/dist/report/generator.js.map +1 -1
- package/dist/report/index.d.ts +5 -2
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +11 -1
- package/dist/report/index.js.map +1 -1
- package/dist/report/results.d.ts +33 -0
- package/dist/report/results.d.ts.map +1 -1
- package/dist/report/template.d.ts +28 -1
- package/dist/report/template.d.ts.map +1 -1
- package/dist/report/template.js +127 -15
- package/dist/report/template.js.map +1 -1
- package/dist/report/validate.d.ts +50 -0
- package/dist/report/validate.d.ts.map +1 -0
- package/dist/report/validate.js +343 -0
- package/dist/report/validate.js.map +1 -0
- package/dist/standalone/run.d.ts +12 -0
- package/dist/standalone/run.d.ts.map +1 -1
- package/dist/standalone/run.js +55 -53
- package/dist/standalone/run.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Stable full-page capture — shared by every adapter that screenshots through
|
|
4
|
+
* CDP `Page.captureScreenshot` with `captureBeyondViewport`.
|
|
5
|
+
*
|
|
6
|
+
* THE PROBLEM
|
|
7
|
+
* -----------
|
|
8
|
+
* Chrome can hand back a frame painted with styles resolved against the wrong
|
|
9
|
+
* viewport while it sets up a beyond-viewport capture: narrow-viewport media
|
|
10
|
+
* rules, a collapsed `min-height: 100vh` hero, or text sized from a
|
|
11
|
+
* `@media (max-width: 480px)` body font. The page measures correctly (DOM,
|
|
12
|
+
* element map and computed styles all match the baseline) but the pixels do
|
|
13
|
+
* not, so an unchanged page flips between two renders from run to run and is
|
|
14
|
+
* reported as changed. Measured on the standalone CLI (an e2e fixture failed
|
|
15
|
+
* on nearly every attempt) and on a Playwright suite in CI (testivai-site's
|
|
16
|
+
* home page: 4.13% "changed" on one run, the same commit passing on re-run).
|
|
17
|
+
*
|
|
18
|
+
* THE GUARD
|
|
19
|
+
* ---------
|
|
20
|
+
* 1. Wait for a fresh frame — two animation frames, so every style and layout
|
|
21
|
+
* change made so far has been painted — before measuring and capturing.
|
|
22
|
+
* A forced layout alone does not prevent a stale frame; a rendered one does.
|
|
23
|
+
* 2. Capture until two captures in a row are identical, at most
|
|
24
|
+
* MAX_STABLE_CAPTURES. The capture after a wrong frame is almost always
|
|
25
|
+
* right. A stable page costs one extra screenshot; a page that never stops
|
|
26
|
+
* changing costs MAX_STABLE_CAPTURES, never an endless loop. The same wrong
|
|
27
|
+
* frame twice in a row would still be kept: rare, as it takes two misses.
|
|
28
|
+
*
|
|
29
|
+
* The helpers are transport-agnostic: the adapter supplies how to evaluate the
|
|
30
|
+
* frame wait in its page and how to take one capture.
|
|
31
|
+
*/
|
|
32
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
+
exports.MAX_STABLE_CAPTURES = exports.FRESH_FRAME_EXPRESSION = exports.FRESH_FRAME_TIMEOUT_MS = void 0;
|
|
34
|
+
exports.settleFreshFrame = settleFreshFrame;
|
|
35
|
+
exports.captureUntilStable = captureUntilStable;
|
|
36
|
+
/** How long the in-page frame wait waits for two frames before giving up. */
|
|
37
|
+
exports.FRESH_FRAME_TIMEOUT_MS = 1000;
|
|
38
|
+
/**
|
|
39
|
+
* In-page expression an adapter awaits before capturing: resolves `true` once
|
|
40
|
+
* the page has rendered two animation frames (a frame produced after every
|
|
41
|
+
* style and layout change made so far has been painted), or `false` after
|
|
42
|
+
* FRESH_FRAME_TIMEOUT_MS for a page that renders no frames at all.
|
|
43
|
+
*/
|
|
44
|
+
exports.FRESH_FRAME_EXPRESSION = `new Promise((resolve) => {
|
|
45
|
+
const timer = setTimeout(() => resolve(false), ${exports.FRESH_FRAME_TIMEOUT_MS});
|
|
46
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
resolve(true);
|
|
49
|
+
}));
|
|
50
|
+
})`;
|
|
51
|
+
/**
|
|
52
|
+
* The most captures of one page while waiting for two in a row to match.
|
|
53
|
+
* Every stale-capture pattern measured settles within four (stale, good,
|
|
54
|
+
* good / good, stale, good, good).
|
|
55
|
+
*/
|
|
56
|
+
exports.MAX_STABLE_CAPTURES = 4;
|
|
57
|
+
/**
|
|
58
|
+
* Wait for a fresh frame, retrying once when none arrived in time (a loaded
|
|
59
|
+
* machine can stall a frame past the in-page timeout). Best-effort, never
|
|
60
|
+
* blocking and never throwing: if neither attempt sees a frame, the capture
|
|
61
|
+
* proceeds and the log says it may be stale.
|
|
62
|
+
*
|
|
63
|
+
* @param waitOnce Evaluates FRESH_FRAME_EXPRESSION in the page and resolves
|
|
64
|
+
* whether it saw two frames. A rejection (e.g. the page navigated away)
|
|
65
|
+
* counts as no frame.
|
|
66
|
+
* @param log Optional debug sink.
|
|
67
|
+
*/
|
|
68
|
+
async function settleFreshFrame(waitOnce, log) {
|
|
69
|
+
const attempt = async () => {
|
|
70
|
+
try {
|
|
71
|
+
return (await waitOnce()) === true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
if (await attempt())
|
|
78
|
+
return;
|
|
79
|
+
log?.('no fresh frame within the wait; waiting once more');
|
|
80
|
+
if (await attempt())
|
|
81
|
+
return;
|
|
82
|
+
log?.('no fresh frame after a retry; capturing anyway, the screenshot may be stale');
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Capture until two captures in a row match, at most `maxCaptures`, and return
|
|
86
|
+
* the matching capture (or the last one when none matched the one before it).
|
|
87
|
+
* The caller waits for a fresh frame before the first capture, usually before
|
|
88
|
+
* measuring the page; this settles again before every recapture.
|
|
89
|
+
*/
|
|
90
|
+
async function captureUntilStable(options) {
|
|
91
|
+
const { capture, settle, log } = options;
|
|
92
|
+
const same = options.same ?? ((a, b) => a === b);
|
|
93
|
+
const maxCaptures = options.maxCaptures ?? exports.MAX_STABLE_CAPTURES;
|
|
94
|
+
let previous = await capture();
|
|
95
|
+
for (let captures = 1; captures < maxCaptures; captures++) {
|
|
96
|
+
await settle();
|
|
97
|
+
const current = await capture();
|
|
98
|
+
if (same(current, previous))
|
|
99
|
+
return current;
|
|
100
|
+
log?.('two captures in a row differed; capturing again');
|
|
101
|
+
previous = current;
|
|
102
|
+
}
|
|
103
|
+
log?.(`no two captures in a row matched in ${maxCaptures}; keeping the last`);
|
|
104
|
+
return previous;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=stable-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stable-capture.js","sourceRoot":"","sources":["../../src/capture/stable-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;;;AAwCH,4CAYC;AAsBD,gDAeC;AAvFD,6EAA6E;AAChE,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAE3C;;;;;GAKG;AACU,QAAA,sBAAsB,GAAG;mDACa,8BAAsB;;;;;GAKtE,CAAC;AAEJ;;;;GAIG;AACU,QAAA,mBAAmB,GAAG,CAAC,CAAC;AAKrC;;;;;;;;;;GAUG;AACI,KAAK,UAAU,gBAAgB,CAAC,QAAgC,EAAE,GAAgB;IACvF,MAAM,OAAO,GAAG,KAAK,IAAsB,EAAE;QAC3C,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IACF,IAAI,MAAM,OAAO,EAAE;QAAE,OAAO;IAC5B,GAAG,EAAE,CAAC,mDAAmD,CAAC,CAAC;IAC3D,IAAI,MAAM,OAAO,EAAE;QAAE,OAAO;IAC5B,GAAG,EAAE,CAAC,6EAA6E,CAAC,CAAC;AACvF,CAAC;AAgBD;;;;;GAKG;AACI,KAAK,UAAU,kBAAkB,CAAI,OAAqC;IAC/E,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAI,EAAE,CAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,2BAAmB,CAAC;IAE/D,IAAI,QAAQ,GAAG,MAAM,OAAO,EAAE,CAAC;IAC/B,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,WAAW,EAAE,QAAQ,EAAE,EAAE,CAAC;QAC1D,MAAM,MAAM,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,MAAM,OAAO,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;YAAE,OAAO,OAAO,CAAC;QAC5C,GAAG,EAAE,CAAC,iDAAiD,CAAC,CAAC;QACzD,QAAQ,GAAG,OAAO,CAAC;IACrB,CAAC;IACD,GAAG,EAAE,CAAC,uCAAuC,WAAW,oBAAoB,CAAC,CAAC;IAC9E,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { type EnvironmentPolicy, type HostEnvironment } from '../capture/environment';
|
|
3
|
+
/**
|
|
4
|
+
* `testivai env` — this machine's part of the capture environment: the OS
|
|
5
|
+
* and distro, CI and its runner image, a container, TESTIVAI_ENV_LABEL,
|
|
6
|
+
* and the environmentPolicy that decides what a change of environment does.
|
|
7
|
+
* The rest of the block (browser, framework, adapter, render settings) is
|
|
8
|
+
* recorded by each capture, since it depends on the browser a test opens.
|
|
9
|
+
*
|
|
10
|
+
* `--fonts` adds a fingerprint of the installed font list (fc-list): two
|
|
11
|
+
* machines whose fingerprints differ draw text differently, the most common
|
|
12
|
+
* reason the same page renders differently "at the same URL". Not recorded
|
|
13
|
+
* per capture: listing fonts costs a process spawn.
|
|
14
|
+
*/
|
|
15
|
+
/** Count and a short hash of a font list (fc-list output), independent of its order and duplicates. */
|
|
16
|
+
export declare function fontFingerprint(fcListOutput: string): {
|
|
17
|
+
count: number;
|
|
18
|
+
sha256: string;
|
|
19
|
+
};
|
|
20
|
+
/** The installed fonts' fingerprint, or 'unavailable' when fc-list cannot run here. */
|
|
21
|
+
export declare function readFontFingerprint(): {
|
|
22
|
+
count: number;
|
|
23
|
+
sha256: string;
|
|
24
|
+
} | 'unavailable';
|
|
25
|
+
export interface EnvironmentReport {
|
|
26
|
+
host: HostEnvironment;
|
|
27
|
+
policy: EnvironmentPolicy;
|
|
28
|
+
/** null: not asked for; 'unavailable': no fc-list. */
|
|
29
|
+
fonts: {
|
|
30
|
+
count: number;
|
|
31
|
+
sha256: string;
|
|
32
|
+
} | 'unavailable' | null;
|
|
33
|
+
}
|
|
34
|
+
/** The human-readable `testivai env` output. */
|
|
35
|
+
export declare function formatEnvironment(report: EnvironmentReport): string;
|
|
36
|
+
export declare const envCommand: Command;
|
|
37
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAA0B,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9G;;;;;;;;;;;GAWG;AAEH,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAGvF;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAOvF;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,sDAAsD;IACtD,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,GAAG,IAAI,CAAC;CACjE;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAoBnE;AAED,eAAO,MAAM,UAAU,SAiBnB,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.envCommand = void 0;
|
|
37
|
+
exports.fontFingerprint = fontFingerprint;
|
|
38
|
+
exports.readFontFingerprint = readFontFingerprint;
|
|
39
|
+
exports.formatEnvironment = formatEnvironment;
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
42
|
+
const crypto = __importStar(require("crypto"));
|
|
43
|
+
const environment_1 = require("../capture/environment");
|
|
44
|
+
const local_config_1 = require("../config/local-config");
|
|
45
|
+
/**
|
|
46
|
+
* `testivai env` — this machine's part of the capture environment: the OS
|
|
47
|
+
* and distro, CI and its runner image, a container, TESTIVAI_ENV_LABEL,
|
|
48
|
+
* and the environmentPolicy that decides what a change of environment does.
|
|
49
|
+
* The rest of the block (browser, framework, adapter, render settings) is
|
|
50
|
+
* recorded by each capture, since it depends on the browser a test opens.
|
|
51
|
+
*
|
|
52
|
+
* `--fonts` adds a fingerprint of the installed font list (fc-list): two
|
|
53
|
+
* machines whose fingerprints differ draw text differently, the most common
|
|
54
|
+
* reason the same page renders differently "at the same URL". Not recorded
|
|
55
|
+
* per capture: listing fonts costs a process spawn.
|
|
56
|
+
*/
|
|
57
|
+
/** Count and a short hash of a font list (fc-list output), independent of its order and duplicates. */
|
|
58
|
+
function fontFingerprint(fcListOutput) {
|
|
59
|
+
const fonts = [...new Set(fcListOutput.split(/\r?\n/).map((l) => l.trim()).filter(Boolean))].sort();
|
|
60
|
+
return { count: fonts.length, sha256: crypto.createHash('sha256').update(fonts.join('\n')).digest('hex').slice(0, 12) };
|
|
61
|
+
}
|
|
62
|
+
/** The installed fonts' fingerprint, or 'unavailable' when fc-list cannot run here. */
|
|
63
|
+
function readFontFingerprint() {
|
|
64
|
+
try {
|
|
65
|
+
const out = (0, child_process_1.execFileSync)('fc-list', [':', 'family', 'style'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 });
|
|
66
|
+
return fontFingerprint(out);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return 'unavailable';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** The human-readable `testivai env` output. */
|
|
73
|
+
function formatEnvironment(report) {
|
|
74
|
+
const { host, policy, fonts } = report;
|
|
75
|
+
const os = `${host.os.platform} ${host.os.release} ${host.os.arch}${host.os.distro ? ` (${host.os.distro})` : ''}`;
|
|
76
|
+
const ci = host.ci ? `${host.ci.provider}${host.ci.runnerImage ? ` (runner image ${host.ci.runnerImage})` : ''}` : 'none';
|
|
77
|
+
const fontLine = fonts === null
|
|
78
|
+
? 'not checked (pass --fonts)'
|
|
79
|
+
: fonts === 'unavailable'
|
|
80
|
+
? 'fc-list is not available on this machine'
|
|
81
|
+
: `${fonts.count} installed, fingerprint ${fonts.sha256}`;
|
|
82
|
+
return [
|
|
83
|
+
'TestivAI capture environment (this machine)',
|
|
84
|
+
` os: ${os}`,
|
|
85
|
+
` ci: ${ci}`,
|
|
86
|
+
` container: ${host.container ? 'yes' : 'no'}`,
|
|
87
|
+
` label: ${host.label ?? 'none (set TESTIVAI_ENV_LABEL to name this environment)'}`,
|
|
88
|
+
` fonts: ${fontLine}`,
|
|
89
|
+
` policy: environmentPolicy "${policy}"`,
|
|
90
|
+
'Browser, framework, adapter and render settings are recorded by each capture (metadata.json `environment`).',
|
|
91
|
+
].join('\n');
|
|
92
|
+
}
|
|
93
|
+
exports.envCommand = new commander_1.Command('env')
|
|
94
|
+
.description("Print this machine's capture environment (OS, distro, CI, container, label) and the environmentPolicy")
|
|
95
|
+
.option('--fonts', 'Also fingerprint the installed fonts (fc-list): differing fingerprints mean text renders differently')
|
|
96
|
+
.option('--json', 'Print machine-readable JSON')
|
|
97
|
+
.action((options) => {
|
|
98
|
+
const report = {
|
|
99
|
+
host: (0, environment_1.collectHostEnvironment)(),
|
|
100
|
+
policy: (0, local_config_1.loadLocalConfig)(process.cwd()).environmentPolicy ?? 'warn',
|
|
101
|
+
fonts: options.fonts ? readFontFingerprint() : null,
|
|
102
|
+
};
|
|
103
|
+
if (options.json) {
|
|
104
|
+
const payload = { environment: report.host, environmentPolicy: report.policy };
|
|
105
|
+
if (report.fonts !== null)
|
|
106
|
+
payload.fonts = report.fonts;
|
|
107
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
process.stdout.write(`${formatEnvironment(report)}\n`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Reads/writes `.testivai/config.json`. Everything runs locally, so this
|
|
5
5
|
* file is optional — absent, every field falls back to its default.
|
|
6
6
|
*/
|
|
7
|
+
import type { EnvironmentPolicy } from '../capture/environment';
|
|
7
8
|
export interface LocalConfig {
|
|
8
9
|
/** Pixel diff threshold (0-1). Default: 0.1 */
|
|
9
10
|
threshold: number;
|
|
@@ -135,6 +136,19 @@ export interface LocalConfig {
|
|
|
135
136
|
* server's --approval-prompt / --no-approval-prompt flag overrides this.
|
|
136
137
|
*/
|
|
137
138
|
mcpApprovalPrompt?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* What a change of capture environment (browser, OS, device scale,
|
|
141
|
+
* capture method…: the recorded `environment`) since the baseline does:
|
|
142
|
+
* - "warn" (default): never changes a status; the report says when a
|
|
143
|
+
* diff is rendering drift rather than calling it render noise.
|
|
144
|
+
* - "separate": adapters key each snapshot by environment,
|
|
145
|
+
* `<name>__<browser>__<platform>`, so each browser and OS gates
|
|
146
|
+
* against its own baselines (never keyed by version). Only baselines
|
|
147
|
+
* of an environment this run captured can be missing.
|
|
148
|
+
* - "strict": a snapshot whose rendering environment changed is
|
|
149
|
+
* changed, whatever its pixels say (exit 1 with --fail-on-diff).
|
|
150
|
+
*/
|
|
151
|
+
environmentPolicy?: EnvironmentPolicy;
|
|
138
152
|
}
|
|
139
153
|
/**
|
|
140
154
|
* Load local config from `.testivai/config.json`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-config.d.ts","sourceRoot":"","sources":["../../src/config/local-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"local-config.d.ts","sourceRoot":"","sources":["../../src/config/local-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACvD;;;;OAIG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;OAcG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAqChE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC/B,WAAW,CAab;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAE9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../src/config/local-config.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"local-config.js","sourceRoot":"","sources":["../../src/config/local-config.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkLH,0CAqCC;AAUD,kDAgBC;AAKD,8CAEC;AAKD,sCAEC;AAKD,4CAEC;AApQD,uCAAyB;AACzB,2CAA6B;AAC7B,uDAAwD;AA+IxD,MAAM,cAAc,GAAgB;IAClC,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,IAAI;IACd,UAAU,EAAE,KAAK;IACjB,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,CAAC;IACjB,aAAa,EAAE,KAAK;IACpB,mBAAmB,EAAE,CAAC;IACtB,SAAS,EAAE,IAAI;IACf,iBAAiB,EAAE,MAAM;CAC1B,CAAC;AAEF,MAAM,eAAe,GAAG,aAAa,CAAC;AACtC,MAAM,UAAU,GAAG,WAAW,CAAC;AAE/B,4EAA4E;AAC5E,6EAA6E;AAC7E,oEAAoE;AACpE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAC,WAAmB;IACjD,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE/B,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAA,qCAAmB,EAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACxD,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,OAAO,CAAC,IAAI,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;gBAC9B,OAAQ,MAAkC,CAAC,GAAG,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QAED,OAAO;YACL,GAAG,cAAc;YACjB,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,wEAAwE;QACxE,wDAAwD;QACxD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC5B,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,8BAA8B,UAAU,uBAAuB,MAAM,qBAAqB,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,WAAmB,EACnB,SAAgC;IAEhC,MAAM,MAAM,GAAgB;QAC1B,GAAG,cAAc;QACjB,GAAG,SAAS;KACb,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACrD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC9C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAErE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,WAAmB;IACnD,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,WAAmB;IAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-config.d.ts","sourceRoot":"","sources":["../../src/config/validate-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"validate-config.d.ts","sourceRoot":"","sources":["../../src/config/validate-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA2CH,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAQD,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAexD;AAoBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CA8CrE"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.levenshtein = levenshtein;
|
|
16
16
|
exports.validateLocalConfig = validateLocalConfig;
|
|
17
|
+
const environment_1 = require("../capture/environment");
|
|
17
18
|
/** Expected JSON type for every known LocalConfig field. */
|
|
18
19
|
const KNOWN_FIELDS = {
|
|
19
20
|
threshold: 'number',
|
|
@@ -37,6 +38,11 @@ const KNOWN_FIELDS = {
|
|
|
37
38
|
maxPages: 'number',
|
|
38
39
|
viewport: 'object',
|
|
39
40
|
mcpApprovalPrompt: 'boolean',
|
|
41
|
+
environmentPolicy: 'string',
|
|
42
|
+
};
|
|
43
|
+
/** String fields that only take one of a fixed set of values; the first is the default. */
|
|
44
|
+
const ENUM_FIELDS = {
|
|
45
|
+
environmentPolicy: environment_1.ENVIRONMENT_POLICIES,
|
|
40
46
|
};
|
|
41
47
|
/**
|
|
42
48
|
* Keys earlier versions understood. They get a targeted retirement notice
|
|
@@ -115,6 +121,12 @@ function validateLocalConfig(parsed) {
|
|
|
115
121
|
: `unknown config key "${key}" — it is being ignored. Known keys: ${Object.keys(KNOWN_FIELDS).join(', ')}.`);
|
|
116
122
|
continue;
|
|
117
123
|
}
|
|
124
|
+
const allowed = ENUM_FIELDS[key];
|
|
125
|
+
if (allowed && !allowed.includes(value)) {
|
|
126
|
+
warnings.push(`config key "${key}" should be one of ${allowed.map((v) => `"${v}"`).join(', ')}, got ${JSON.stringify(value)} — using the default ("${allowed[0]}") instead.`);
|
|
127
|
+
invalidKeys.push(key);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
118
130
|
const actual = jsonType(value);
|
|
119
131
|
if (actual !== expected) {
|
|
120
132
|
warnings.push(`config key "${key}" should be a ${expected}, got ${actual} (${JSON.stringify(value)}) — using the default instead.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../src/config/validate-config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;
|
|
1
|
+
{"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../src/config/validate-config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,11 +18,15 @@ export { parseShardEnv, resolveCaptureOnly, writeShardManifest, SHARD_MANIFEST }
|
|
|
18
18
|
export type { ShardInfo, ShardManifest } from './capture/shard';
|
|
19
19
|
export { settleProbe, buildSettleProbeExpression, SETTLE_STOP_EXPRESSION, SETTLE_STATE_KEY, DEFAULT_QUIET_MS, DEFAULT_SETTLE_TIMEOUT_MS, } from './capture/settle';
|
|
20
20
|
export type { SettleState } from './capture/settle';
|
|
21
|
+
export { applyEnvironmentPolicyToName, browserFromCapabilities, browserFromUserAgent, buildCaptureEnvironment, CAPTURE_METHODS, collectHostEnvironment, detectCi, distroFromOsRelease, ENVIRONMENT_POLICIES, installedPackageVersion, parseEnvironmentVariant, parseRenderProbe, readEnvironment, RENDER_PROBE_EXPRESSION, webDriverEnvironment, } from './capture/environment';
|
|
22
|
+
export type { CaptureEnvironment, CaptureEnvironmentParts, EnvironmentPolicy, HostEnvironment, HostSources, RenderEnvironment, WebDriverEnvironmentInput, } from './capture/environment';
|
|
23
|
+
export { FRESH_FRAME_EXPRESSION, FRESH_FRAME_TIMEOUT_MS, MAX_STABLE_CAPTURES, settleFreshFrame, captureUntilStable, } from './capture/stable-capture';
|
|
24
|
+
export type { CaptureLog, CaptureUntilStableOptions } from './capture/stable-capture';
|
|
21
25
|
export { BaselineStore } from './baselines';
|
|
22
26
|
export type { BaselineMetadata } from './baselines';
|
|
23
27
|
export { loadLocalConfig, createDefaultConfig, localConfigExists, getConfigPath, getDefaultConfig, } from './config';
|
|
24
28
|
export type { LocalConfig } from './config';
|
|
25
|
-
export { generateReport, compareAll, renderHtml } from './report';
|
|
29
|
+
export { generateReport, compareAll, renderHtml, snapshotAnchorId } from './report';
|
|
26
30
|
export type { GenerateReportOptions, CompareOptions, ReportData, ReportSummary, SnapshotResult, SnapshotStatus } from './report';
|
|
27
31
|
export { initCommand } from './commands/init';
|
|
28
32
|
export { runCommand } from './commands/run';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnI,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,cAAc,QAAQ,CAAC;AAIvB,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3G,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EACL,WAAW,EACX,0BAA0B,EAC1B,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnI,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,cAAc,QAAQ,CAAC;AAIvB,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3G,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EACL,WAAW,EACX,0BAA0B,EAC1B,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,QAAQ,EACR,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACpF,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGjI,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD,eAAO,MAAM,OAAO,KAAqC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
18
18
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.
|
|
21
|
+
exports.captureUntilStable = exports.settleFreshFrame = exports.MAX_STABLE_CAPTURES = exports.FRESH_FRAME_TIMEOUT_MS = exports.FRESH_FRAME_EXPRESSION = exports.webDriverEnvironment = exports.RENDER_PROBE_EXPRESSION = exports.readEnvironment = exports.parseRenderProbe = exports.parseEnvironmentVariant = exports.installedPackageVersion = exports.ENVIRONMENT_POLICIES = exports.distroFromOsRelease = exports.detectCi = exports.collectHostEnvironment = exports.CAPTURE_METHODS = exports.buildCaptureEnvironment = exports.browserFromUserAgent = exports.browserFromCapabilities = exports.applyEnvironmentPolicyToName = exports.DEFAULT_SETTLE_TIMEOUT_MS = exports.DEFAULT_QUIET_MS = exports.SETTLE_STATE_KEY = exports.SETTLE_STOP_EXPRESSION = exports.buildSettleProbeExpression = exports.settleProbe = exports.SHARD_MANIFEST = exports.writeShardManifest = exports.resolveCaptureOnly = exports.parseShardEnv = exports.DEFAULT_MAX_ELEMENTS = exports.buildElementMapExpression = exports.collectElementMap = exports.FrameworkDetector = exports.commandExists = exports.setupSignalHandlers = exports.spawnProcess = exports.ProcessManager = exports.isSafeFilename = exports.sanitizeTestName = exports.extractNameFromUrl = exports.generateUniqueFilename = exports.toSafeFilename = exports.createLogger = exports.logger = exports.BrowserDiscoveryError = exports.BrowserDiscovery = exports.BrowserBinding = exports.BrowserCapture = exports.BrowserClient = void 0;
|
|
22
|
+
exports.VERSION = exports.approveCommand = exports.witnessCommand = exports.runCommand = exports.initCommand = exports.snapshotAnchorId = exports.renderHtml = exports.compareAll = exports.generateReport = exports.getDefaultConfig = exports.getConfigPath = exports.localConfigExists = exports.createDefaultConfig = exports.loadLocalConfig = exports.BaselineStore = void 0;
|
|
22
23
|
// Export types
|
|
23
24
|
__exportStar(require("./types"), exports);
|
|
24
25
|
// Export browser modules
|
|
@@ -70,6 +71,31 @@ Object.defineProperty(exports, "SETTLE_STOP_EXPRESSION", { enumerable: true, get
|
|
|
70
71
|
Object.defineProperty(exports, "SETTLE_STATE_KEY", { enumerable: true, get: function () { return settle_1.SETTLE_STATE_KEY; } });
|
|
71
72
|
Object.defineProperty(exports, "DEFAULT_QUIET_MS", { enumerable: true, get: function () { return settle_1.DEFAULT_QUIET_MS; } });
|
|
72
73
|
Object.defineProperty(exports, "DEFAULT_SETTLE_TIMEOUT_MS", { enumerable: true, get: function () { return settle_1.DEFAULT_SETTLE_TIMEOUT_MS; } });
|
|
74
|
+
// Capture provenance — the environment block every adapter records.
|
|
75
|
+
var environment_1 = require("./capture/environment");
|
|
76
|
+
Object.defineProperty(exports, "applyEnvironmentPolicyToName", { enumerable: true, get: function () { return environment_1.applyEnvironmentPolicyToName; } });
|
|
77
|
+
Object.defineProperty(exports, "browserFromCapabilities", { enumerable: true, get: function () { return environment_1.browserFromCapabilities; } });
|
|
78
|
+
Object.defineProperty(exports, "browserFromUserAgent", { enumerable: true, get: function () { return environment_1.browserFromUserAgent; } });
|
|
79
|
+
Object.defineProperty(exports, "buildCaptureEnvironment", { enumerable: true, get: function () { return environment_1.buildCaptureEnvironment; } });
|
|
80
|
+
Object.defineProperty(exports, "CAPTURE_METHODS", { enumerable: true, get: function () { return environment_1.CAPTURE_METHODS; } });
|
|
81
|
+
Object.defineProperty(exports, "collectHostEnvironment", { enumerable: true, get: function () { return environment_1.collectHostEnvironment; } });
|
|
82
|
+
Object.defineProperty(exports, "detectCi", { enumerable: true, get: function () { return environment_1.detectCi; } });
|
|
83
|
+
Object.defineProperty(exports, "distroFromOsRelease", { enumerable: true, get: function () { return environment_1.distroFromOsRelease; } });
|
|
84
|
+
Object.defineProperty(exports, "ENVIRONMENT_POLICIES", { enumerable: true, get: function () { return environment_1.ENVIRONMENT_POLICIES; } });
|
|
85
|
+
Object.defineProperty(exports, "installedPackageVersion", { enumerable: true, get: function () { return environment_1.installedPackageVersion; } });
|
|
86
|
+
Object.defineProperty(exports, "parseEnvironmentVariant", { enumerable: true, get: function () { return environment_1.parseEnvironmentVariant; } });
|
|
87
|
+
Object.defineProperty(exports, "parseRenderProbe", { enumerable: true, get: function () { return environment_1.parseRenderProbe; } });
|
|
88
|
+
Object.defineProperty(exports, "readEnvironment", { enumerable: true, get: function () { return environment_1.readEnvironment; } });
|
|
89
|
+
Object.defineProperty(exports, "RENDER_PROBE_EXPRESSION", { enumerable: true, get: function () { return environment_1.RENDER_PROBE_EXPRESSION; } });
|
|
90
|
+
Object.defineProperty(exports, "webDriverEnvironment", { enumerable: true, get: function () { return environment_1.webDriverEnvironment; } });
|
|
91
|
+
// Stable full-page capture (fresh frame + capture until two in a row match) —
|
|
92
|
+
// shared by every adapter that captures through CDP captureBeyondViewport.
|
|
93
|
+
var stable_capture_1 = require("./capture/stable-capture");
|
|
94
|
+
Object.defineProperty(exports, "FRESH_FRAME_EXPRESSION", { enumerable: true, get: function () { return stable_capture_1.FRESH_FRAME_EXPRESSION; } });
|
|
95
|
+
Object.defineProperty(exports, "FRESH_FRAME_TIMEOUT_MS", { enumerable: true, get: function () { return stable_capture_1.FRESH_FRAME_TIMEOUT_MS; } });
|
|
96
|
+
Object.defineProperty(exports, "MAX_STABLE_CAPTURES", { enumerable: true, get: function () { return stable_capture_1.MAX_STABLE_CAPTURES; } });
|
|
97
|
+
Object.defineProperty(exports, "settleFreshFrame", { enumerable: true, get: function () { return stable_capture_1.settleFreshFrame; } });
|
|
98
|
+
Object.defineProperty(exports, "captureUntilStable", { enumerable: true, get: function () { return stable_capture_1.captureUntilStable; } });
|
|
73
99
|
var baselines_1 = require("./baselines");
|
|
74
100
|
Object.defineProperty(exports, "BaselineStore", { enumerable: true, get: function () { return baselines_1.BaselineStore; } });
|
|
75
101
|
// Export local config
|
|
@@ -84,6 +110,7 @@ var report_1 = require("./report");
|
|
|
84
110
|
Object.defineProperty(exports, "generateReport", { enumerable: true, get: function () { return report_1.generateReport; } });
|
|
85
111
|
Object.defineProperty(exports, "compareAll", { enumerable: true, get: function () { return report_1.compareAll; } });
|
|
86
112
|
Object.defineProperty(exports, "renderHtml", { enumerable: true, get: function () { return report_1.renderHtml; } });
|
|
113
|
+
Object.defineProperty(exports, "snapshotAnchorId", { enumerable: true, get: function () { return report_1.snapshotAnchorId; } });
|
|
87
114
|
// Export commands (for programmatic use)
|
|
88
115
|
var init_1 = require("./commands/init");
|
|
89
116
|
Object.defineProperty(exports, "initCommand", { enumerable: true, get: function () { return init_1.initCommand; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Link targets for snapshots in the HTML report.
|
|
3
|
+
*
|
|
4
|
+
* Its own module (no template code) so the GitHub Action can bundle it for
|
|
5
|
+
* the PR comment's per-snapshot links without the whole report template.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The id of a snapshot's card in the report, for links straight to it
|
|
9
|
+
* (`index.html#snap-home`). Exported so the PR comment builds the same id.
|
|
10
|
+
*
|
|
11
|
+
* A plain name (letters, digits, `_`, `-`) is kept as is. Any other name is
|
|
12
|
+
* reduced to those characters and suffixed with a hash of the full name, so
|
|
13
|
+
* names that differ only in other characters (`home page`, `home/page`)
|
|
14
|
+
* still get different ids. Always matches `snap-[A-Za-z0-9_-]+`, at most 74
|
|
15
|
+
* characters.
|
|
16
|
+
*/
|
|
17
|
+
export declare function snapshotAnchorId(name: string): string;
|
|
18
|
+
//# sourceMappingURL=anchor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor.d.ts","sourceRoot":"","sources":["../../src/report/anchor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Link targets for snapshots in the HTML report.
|
|
4
|
+
*
|
|
5
|
+
* Its own module (no template code) so the GitHub Action can bundle it for
|
|
6
|
+
* the PR comment's per-snapshot links without the whole report template.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.snapshotAnchorId = snapshotAnchorId;
|
|
10
|
+
/** A name that is already a readable, safe id (and short enough to keep). */
|
|
11
|
+
const PLAIN_SNAPSHOT_NAME = /^[A-Za-z0-9_-]{1,60}$/;
|
|
12
|
+
/**
|
|
13
|
+
* The id of a snapshot's card in the report, for links straight to it
|
|
14
|
+
* (`index.html#snap-home`). Exported so the PR comment builds the same id.
|
|
15
|
+
*
|
|
16
|
+
* A plain name (letters, digits, `_`, `-`) is kept as is. Any other name is
|
|
17
|
+
* reduced to those characters and suffixed with a hash of the full name, so
|
|
18
|
+
* names that differ only in other characters (`home page`, `home/page`)
|
|
19
|
+
* still get different ids. Always matches `snap-[A-Za-z0-9_-]+`, at most 74
|
|
20
|
+
* characters.
|
|
21
|
+
*/
|
|
22
|
+
function snapshotAnchorId(name) {
|
|
23
|
+
if (PLAIN_SNAPSHOT_NAME.test(name))
|
|
24
|
+
return `snap-${name}`;
|
|
25
|
+
const readable = trimDashes(name.replace(/[^A-Za-z0-9_-]+/g, '-')).slice(0, 60);
|
|
26
|
+
return `snap-${readable ? `${readable}-` : ''}${fnv1a(name)}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Drop leading and trailing dashes. A loop, not /^-+|-+$/: that regex is
|
|
30
|
+
* quadratic on a run of dashes between two other characters, and a snapshot
|
|
31
|
+
* name can come from a results.json someone else wrote.
|
|
32
|
+
*/
|
|
33
|
+
function trimDashes(value) {
|
|
34
|
+
let start = 0;
|
|
35
|
+
let end = value.length;
|
|
36
|
+
while (start < end && value[start] === '-')
|
|
37
|
+
start++;
|
|
38
|
+
while (end > start && value[end - 1] === '-')
|
|
39
|
+
end--;
|
|
40
|
+
return value.slice(start, end);
|
|
41
|
+
}
|
|
42
|
+
/** 32-bit FNV-1a of a string's UTF-16 code units, as 8 hex digits. */
|
|
43
|
+
function fnv1a(value) {
|
|
44
|
+
let hash = 0x811c9dc5;
|
|
45
|
+
for (let i = 0; i < value.length; i++) {
|
|
46
|
+
hash ^= value.charCodeAt(i);
|
|
47
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
48
|
+
}
|
|
49
|
+
return hash.toString(16).padStart(8, '0');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=anchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../src/report/anchor.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAeH,4CAIC;AAjBD,6EAA6E;AAC7E,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAEpD;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,IAAI,EAAE,CAAC;IAC1D,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,OAAO,KAAK,GAAG,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG;QAAE,KAAK,EAAE,CAAC;IACpD,OAAO,GAAG,GAAG,KAAK,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG;QAAE,GAAG,EAAE,CAAC;IACpD,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,sEAAsE;AACtE,SAAS,KAAK,CAAC,KAAa;IAC1B,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC"}
|
package/dist/report/compare.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { SnapshotResult } from './results';
|
|
7
7
|
import { type MaskSpec } from '../diff/mask';
|
|
8
8
|
import type { RegionOptions } from '../diff/types';
|
|
9
|
+
import { type EnvironmentPolicy } from '../capture/environment';
|
|
9
10
|
export interface CompareOptions {
|
|
10
11
|
threshold?: number;
|
|
11
12
|
projectRoot: string;
|
|
@@ -29,6 +30,12 @@ export interface CompareOptions {
|
|
|
29
30
|
* that would otherwise poison the noise hint.
|
|
30
31
|
*/
|
|
31
32
|
volatileAttributes?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* config `environmentPolicy`. 'strict' makes a snapshot whose rendering
|
|
35
|
+
* environment changed since the baseline changed, whatever its pixels
|
|
36
|
+
* say; 'warn' (default) and 'separate' never change a status here.
|
|
37
|
+
*/
|
|
38
|
+
environmentPolicy?: EnvironmentPolicy;
|
|
32
39
|
}
|
|
33
40
|
export interface PassCriteria {
|
|
34
41
|
/** Pass when diff percentage (0-100) is at or below this. Default 0. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAqB,cAAc,EAAkB,MAAM,WAAW,CAAC;AAEnF,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAqB,cAAc,EAAkB,MAAM,WAAW,CAAC;AAEnF,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,wBAAwB,CAAC;AAUjF,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;IAClB,yDAAyD;IACzD,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAkCD,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,EAAE,CAsIpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAsEtF"}
|