domflax 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +214 -0
- package/dist/chunk-4HHISSMR.js +2227 -0
- package/dist/chunk-4HHISSMR.js.map +1 -0
- package/dist/chunk-6WVVF6AD.js +55 -0
- package/dist/chunk-6WVVF6AD.js.map +1 -0
- package/dist/chunk-77SLHRN6.js +2047 -0
- package/dist/chunk-77SLHRN6.js.map +1 -0
- package/dist/chunk-ZJ2S36GY.js +175 -0
- package/dist/chunk-ZJ2S36GY.js.map +1 -0
- package/dist/cli.cjs +5207 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1310 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +4383 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +539 -0
- package/dist/index.d.ts +539 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/pattern-CX6iBzTD.d.ts +237 -0
- package/dist/pattern-P4FIKAUB.d.cts +237 -0
- package/dist/pattern-kit.cjs +630 -0
- package/dist/pattern-kit.cjs.map +1 -0
- package/dist/pattern-kit.d.cts +80 -0
- package/dist/pattern-kit.d.ts +80 -0
- package/dist/pattern-kit.js +55 -0
- package/dist/pattern-kit.js.map +1 -0
- package/dist/types-BQ7l6dVe.d.cts +749 -0
- package/dist/types-BQ7l6dVe.d.ts +749 -0
- package/dist/verify.cjs +2747 -0
- package/dist/verify.cjs.map +1 -0
- package/dist/verify.d.cts +245 -0
- package/dist/verify.d.ts +245 -0
- package/dist/verify.js +2700 -0
- package/dist/verify.js.map +1 -0
- package/dist/webpack-loader.cjs +4149 -0
- package/dist/webpack-loader.cjs.map +1 -0
- package/dist/webpack-loader.d.cts +21 -0
- package/dist/webpack-loader.d.ts +21 -0
- package/dist/webpack-loader.js +30 -0
- package/dist/webpack-loader.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { H as Diagnostic } from './types-BQ7l6dVe.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @domflax/verify — public type contract (TYPED STUB)
|
|
5
|
+
*
|
|
6
|
+
* Equivalence verifier: renders the `before` and `after` source of a single-file
|
|
7
|
+
* transform in a real browser and proves they are visually + structurally
|
|
8
|
+
* equivalent across a set of viewports. The heavy rendering/diffing engine
|
|
9
|
+
* (playwright + pixelmatch + pngjs) lands in a later stage; this module defines
|
|
10
|
+
* the FULL result/option surface and a NotImplemented entry point so downstream
|
|
11
|
+
* packages can typecheck against the contract today.
|
|
12
|
+
*
|
|
13
|
+
* Future runtime deps (NOT in package.json by design — see SKILL build rules):
|
|
14
|
+
* - playwright (headless render of before/after)
|
|
15
|
+
* - pixelmatch (per-pixel image delta)
|
|
16
|
+
* - pngjs (PNG decode for pixelmatch)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** A rendered surface to compare. */
|
|
20
|
+
interface RenderTarget {
|
|
21
|
+
/** Stable label, e.g. 'before' | 'after'. */
|
|
22
|
+
readonly label: string;
|
|
23
|
+
/** Source code (JSX/TSX/HTML) to mount and render. */
|
|
24
|
+
readonly code: string;
|
|
25
|
+
/** Virtual module id / path, used for diagnostics + module resolution. */
|
|
26
|
+
readonly id: string;
|
|
27
|
+
}
|
|
28
|
+
/** Logical viewport the page is rendered at. */
|
|
29
|
+
interface Viewport {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
readonly deviceScaleFactor?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Browser engine to drive (playwright channel). */
|
|
36
|
+
type BrowserEngine = 'chromium' | 'firefox' | 'webkit';
|
|
37
|
+
interface VerifyOptions {
|
|
38
|
+
readonly viewports?: readonly Viewport[];
|
|
39
|
+
readonly engine?: BrowserEngine;
|
|
40
|
+
/** Per-channel 0–255 tolerance before a pixel counts as different. */
|
|
41
|
+
readonly pixelThreshold?: number;
|
|
42
|
+
/** Max fraction (0–1) of differing pixels still considered equivalent. */
|
|
43
|
+
readonly maxPixelRatio?: number;
|
|
44
|
+
/** Max bounding-box drift in CSS px before flagging a layout shift. */
|
|
45
|
+
readonly maxBoxDeltaPx?: number;
|
|
46
|
+
/** Computed-style properties to compare; omit to use the verifier default set. */
|
|
47
|
+
readonly styleProperties?: readonly string[];
|
|
48
|
+
/** Wall-clock budget per target render, in ms. */
|
|
49
|
+
readonly timeoutMs?: number;
|
|
50
|
+
/** When true, retain rendered PNGs/diffs in the result for debugging. */
|
|
51
|
+
readonly captureArtifacts?: boolean;
|
|
52
|
+
}
|
|
53
|
+
interface BoundingBox {
|
|
54
|
+
readonly x: number;
|
|
55
|
+
readonly y: number;
|
|
56
|
+
readonly width: number;
|
|
57
|
+
readonly height: number;
|
|
58
|
+
}
|
|
59
|
+
/** Per-pixel comparison for one viewport. */
|
|
60
|
+
interface PixelDiff {
|
|
61
|
+
readonly width: number;
|
|
62
|
+
readonly height: number;
|
|
63
|
+
readonly totalPixels: number;
|
|
64
|
+
readonly changedPixels: number;
|
|
65
|
+
readonly changedRatio: number;
|
|
66
|
+
/** Encoded PNG of the diff overlay; present only when captureArtifacts. */
|
|
67
|
+
readonly diffPng?: Uint8Array;
|
|
68
|
+
}
|
|
69
|
+
/** Layout drift for a single matched element between before/after. */
|
|
70
|
+
interface BBoxDiff {
|
|
71
|
+
/** Best-effort selector / index path identifying the element. */
|
|
72
|
+
readonly path: string;
|
|
73
|
+
readonly before: BoundingBox | null;
|
|
74
|
+
readonly after: BoundingBox | null;
|
|
75
|
+
readonly deltaX: number;
|
|
76
|
+
readonly deltaY: number;
|
|
77
|
+
readonly deltaWidth: number;
|
|
78
|
+
readonly deltaHeight: number;
|
|
79
|
+
/** Max absolute component of the delta, in CSS px. */
|
|
80
|
+
readonly maxDelta: number;
|
|
81
|
+
}
|
|
82
|
+
/** Computed-style mismatch for one property on one element. */
|
|
83
|
+
interface StyleDiff {
|
|
84
|
+
readonly path: string;
|
|
85
|
+
readonly property: string;
|
|
86
|
+
readonly before: string | null;
|
|
87
|
+
readonly after: string | null;
|
|
88
|
+
}
|
|
89
|
+
type Equivalence = 'equivalent' | 'divergent' | 'inconclusive';
|
|
90
|
+
interface ViewportResult {
|
|
91
|
+
readonly viewport: Viewport;
|
|
92
|
+
readonly equivalence: Equivalence;
|
|
93
|
+
readonly pixel: PixelDiff;
|
|
94
|
+
readonly boxes: readonly BBoxDiff[];
|
|
95
|
+
readonly styles: readonly StyleDiff[];
|
|
96
|
+
/** Present only when captureArtifacts. */
|
|
97
|
+
readonly beforePng?: Uint8Array;
|
|
98
|
+
readonly afterPng?: Uint8Array;
|
|
99
|
+
}
|
|
100
|
+
interface VerifyResult {
|
|
101
|
+
readonly equivalence: Equivalence;
|
|
102
|
+
readonly engine: BrowserEngine;
|
|
103
|
+
readonly viewports: readonly ViewportResult[];
|
|
104
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
105
|
+
readonly durationMs: number;
|
|
106
|
+
}
|
|
107
|
+
declare const DEFAULT_VIEWPORTS: readonly Viewport[];
|
|
108
|
+
declare const DEFAULT_VERIFY_OPTIONS: {
|
|
109
|
+
readonly engine: "chromium";
|
|
110
|
+
readonly pixelThreshold: 2;
|
|
111
|
+
readonly maxPixelRatio: 0;
|
|
112
|
+
readonly maxBoxDeltaPx: 0.5;
|
|
113
|
+
readonly timeoutMs: 30000;
|
|
114
|
+
readonly captureArtifacts: false;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @domflax/verify — deterministic headless render + artifact capture.
|
|
119
|
+
*
|
|
120
|
+
* Accepts an HTML-string fragment (or a full document) and produces, for a
|
|
121
|
+
* single viewport:
|
|
122
|
+
* - a viewport-clipped PNG screenshot (equal dimensions for before/after, so
|
|
123
|
+
* pixelmatch never sees a size mismatch), and
|
|
124
|
+
* - the list of VISUAL LEAVES with their bounding boxes + computed styles.
|
|
125
|
+
*
|
|
126
|
+
* Determinism is pinned hard: animations/transitions/caret disabled, reduced
|
|
127
|
+
* motion forced, fonts awaited, and layout settled across two animation frames
|
|
128
|
+
* before anything is measured.
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/** A measured visual leaf — see {@link extractLeaves}. */
|
|
132
|
+
interface LeafSnapshot {
|
|
133
|
+
/** Lower-cased tag name. */
|
|
134
|
+
readonly tag: string;
|
|
135
|
+
/** ARIA role if set, else the tag — the structure-independent identity. */
|
|
136
|
+
readonly role: string;
|
|
137
|
+
/** Trimmed direct text content (own text nodes only). */
|
|
138
|
+
readonly text: string;
|
|
139
|
+
/** Layout geometry in CSS pixels, viewport-relative. */
|
|
140
|
+
readonly box: {
|
|
141
|
+
readonly x: number;
|
|
142
|
+
readonly y: number;
|
|
143
|
+
readonly width: number;
|
|
144
|
+
readonly height: number;
|
|
145
|
+
};
|
|
146
|
+
/** Requested computed-style properties, raw (normalization happens in diff). */
|
|
147
|
+
readonly styles: Record<string, string>;
|
|
148
|
+
}
|
|
149
|
+
interface RenderArtifacts {
|
|
150
|
+
readonly png: Uint8Array;
|
|
151
|
+
readonly leaves: readonly LeafSnapshot[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @domflax/verify — pure diff engine (no browser, fully unit-testable)
|
|
156
|
+
*
|
|
157
|
+
* Three independent comparison passes operate on the artifacts captured from a
|
|
158
|
+
* rendered page (see {@link ./render}):
|
|
159
|
+
*
|
|
160
|
+
* 1. {@link pixelDiff} — per-pixel delta of the two screenshots (pixelmatch + pngjs).
|
|
161
|
+
* 2. {@link diffBoxes} — per-visual-leaf bounding-box drift.
|
|
162
|
+
* 3. {@link diffStyles} — per-visual-leaf computed-style mismatch, NORMALIZED.
|
|
163
|
+
*
|
|
164
|
+
* Passes 2 and 3 are STRUCTURE-INDEPENDENT: leaves are matched by (role, text)
|
|
165
|
+
* and visual position order, never by DOM index — node counts legitimately
|
|
166
|
+
* differ once a transform flattens wrappers, so DOM-order matching would be
|
|
167
|
+
* meaningless.
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
declare const DEFAULT_STYLE_PROPERTIES: readonly string[];
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @domflax/verify — headless browser lifecycle.
|
|
174
|
+
*
|
|
175
|
+
* One shared {@link Browser} is launched and reused across every viewport and
|
|
176
|
+
* every fixture in a run (see {@link ./index}'s `createVerifier`), which is the
|
|
177
|
+
* batching primitive the maintainer-side oracle needs when validating many
|
|
178
|
+
* fixtures at once.
|
|
179
|
+
*
|
|
180
|
+
* Critically, a launch failure (no downloaded browser binary on a bare CI box)
|
|
181
|
+
* is reported as a value, never thrown past the public API — the verifier then
|
|
182
|
+
* returns an `inconclusive` verdict instead of hard-failing.
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Probe whether the engine can actually launch on this machine. Used by tests
|
|
187
|
+
* to `skipIf` cleanly when no browser is present, keeping browserless CI green.
|
|
188
|
+
*/
|
|
189
|
+
declare function isBrowserAvailable(engine?: BrowserEngine): Promise<boolean>;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @domflax/verify — the maintainer-side Tier-2 equivalence oracle.
|
|
193
|
+
*
|
|
194
|
+
* Renders the `before` and `after` source of a single-file transform in a real
|
|
195
|
+
* headless browser and proves they are visually + structurally equivalent
|
|
196
|
+
* across a matrix of viewports. For each viewport it runs three independent
|
|
197
|
+
* passes (pixel, bounding-box, computed-style) and folds them into one verdict.
|
|
198
|
+
*
|
|
199
|
+
* The comparison is STRUCTURE-INDEPENDENT by design: node counts legitimately
|
|
200
|
+
* change once a transform flattens wrappers, so leaves are matched by visual
|
|
201
|
+
* role/text/position, never by DOM index (see {@link ./diff}).
|
|
202
|
+
*
|
|
203
|
+
* If no browser binary is available the verifier returns an `inconclusive`
|
|
204
|
+
* verdict (never throws), so browserless CI stays green.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/** Fully-resolved options used by the render+diff engine. */
|
|
208
|
+
interface ResolvedVerifyOptions {
|
|
209
|
+
readonly viewports: readonly Viewport[];
|
|
210
|
+
readonly engine: BrowserEngine;
|
|
211
|
+
readonly pixelThreshold: number;
|
|
212
|
+
readonly maxPixelRatio: number;
|
|
213
|
+
readonly maxBoxDeltaPx: number;
|
|
214
|
+
readonly styleProperties: readonly string[];
|
|
215
|
+
readonly timeoutMs: number;
|
|
216
|
+
readonly captureArtifacts: boolean;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Merge caller options over the verifier defaults. Pure and total — safe to use
|
|
220
|
+
* for config validation / dry-run planning.
|
|
221
|
+
*/
|
|
222
|
+
declare function resolveVerifyOptions(opts?: VerifyOptions): ResolvedVerifyOptions;
|
|
223
|
+
interface Verifier {
|
|
224
|
+
/** Verify one before/after pair. Per-call options override the verifier defaults. */
|
|
225
|
+
verify(before: RenderTarget, after: RenderTarget, opts?: VerifyOptions): Promise<VerifyResult>;
|
|
226
|
+
/** Close the shared browser. Safe to call multiple times. */
|
|
227
|
+
close(): Promise<void>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create a verifier that holds ONE browser open across many {@link Verifier.verify}
|
|
231
|
+
* calls — the efficient path for validating a corpus of fixtures. The browser is
|
|
232
|
+
* launched lazily on first use; if launch fails (no binary), every `verify` call
|
|
233
|
+
* returns an `inconclusive` verdict rather than throwing.
|
|
234
|
+
*/
|
|
235
|
+
declare function createVerifier(): Verifier;
|
|
236
|
+
/**
|
|
237
|
+
* One-shot equivalence check: render `before` and `after` and prove visual +
|
|
238
|
+
* structural equivalence across every viewport. Launches a single browser for
|
|
239
|
+
* the call and closes it afterwards.
|
|
240
|
+
*
|
|
241
|
+
* Returns an `inconclusive` verdict (never throws) when no browser is available.
|
|
242
|
+
*/
|
|
243
|
+
declare function verifyEquivalence(before: RenderTarget, after: RenderTarget, opts?: VerifyOptions): Promise<VerifyResult>;
|
|
244
|
+
|
|
245
|
+
export { type BBoxDiff, type BoundingBox, type BrowserEngine, DEFAULT_STYLE_PROPERTIES, DEFAULT_VERIFY_OPTIONS, DEFAULT_VIEWPORTS, type Equivalence, type LeafSnapshot, type PixelDiff, type RenderArtifacts, type RenderTarget, type ResolvedVerifyOptions, type StyleDiff, type Verifier, type VerifyOptions, type VerifyResult, type Viewport, type ViewportResult, createVerifier, isBrowserAvailable, resolveVerifyOptions, verifyEquivalence };
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { H as Diagnostic } from './types-BQ7l6dVe.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @domflax/verify — public type contract (TYPED STUB)
|
|
5
|
+
*
|
|
6
|
+
* Equivalence verifier: renders the `before` and `after` source of a single-file
|
|
7
|
+
* transform in a real browser and proves they are visually + structurally
|
|
8
|
+
* equivalent across a set of viewports. The heavy rendering/diffing engine
|
|
9
|
+
* (playwright + pixelmatch + pngjs) lands in a later stage; this module defines
|
|
10
|
+
* the FULL result/option surface and a NotImplemented entry point so downstream
|
|
11
|
+
* packages can typecheck against the contract today.
|
|
12
|
+
*
|
|
13
|
+
* Future runtime deps (NOT in package.json by design — see SKILL build rules):
|
|
14
|
+
* - playwright (headless render of before/after)
|
|
15
|
+
* - pixelmatch (per-pixel image delta)
|
|
16
|
+
* - pngjs (PNG decode for pixelmatch)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** A rendered surface to compare. */
|
|
20
|
+
interface RenderTarget {
|
|
21
|
+
/** Stable label, e.g. 'before' | 'after'. */
|
|
22
|
+
readonly label: string;
|
|
23
|
+
/** Source code (JSX/TSX/HTML) to mount and render. */
|
|
24
|
+
readonly code: string;
|
|
25
|
+
/** Virtual module id / path, used for diagnostics + module resolution. */
|
|
26
|
+
readonly id: string;
|
|
27
|
+
}
|
|
28
|
+
/** Logical viewport the page is rendered at. */
|
|
29
|
+
interface Viewport {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
readonly deviceScaleFactor?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Browser engine to drive (playwright channel). */
|
|
36
|
+
type BrowserEngine = 'chromium' | 'firefox' | 'webkit';
|
|
37
|
+
interface VerifyOptions {
|
|
38
|
+
readonly viewports?: readonly Viewport[];
|
|
39
|
+
readonly engine?: BrowserEngine;
|
|
40
|
+
/** Per-channel 0–255 tolerance before a pixel counts as different. */
|
|
41
|
+
readonly pixelThreshold?: number;
|
|
42
|
+
/** Max fraction (0–1) of differing pixels still considered equivalent. */
|
|
43
|
+
readonly maxPixelRatio?: number;
|
|
44
|
+
/** Max bounding-box drift in CSS px before flagging a layout shift. */
|
|
45
|
+
readonly maxBoxDeltaPx?: number;
|
|
46
|
+
/** Computed-style properties to compare; omit to use the verifier default set. */
|
|
47
|
+
readonly styleProperties?: readonly string[];
|
|
48
|
+
/** Wall-clock budget per target render, in ms. */
|
|
49
|
+
readonly timeoutMs?: number;
|
|
50
|
+
/** When true, retain rendered PNGs/diffs in the result for debugging. */
|
|
51
|
+
readonly captureArtifacts?: boolean;
|
|
52
|
+
}
|
|
53
|
+
interface BoundingBox {
|
|
54
|
+
readonly x: number;
|
|
55
|
+
readonly y: number;
|
|
56
|
+
readonly width: number;
|
|
57
|
+
readonly height: number;
|
|
58
|
+
}
|
|
59
|
+
/** Per-pixel comparison for one viewport. */
|
|
60
|
+
interface PixelDiff {
|
|
61
|
+
readonly width: number;
|
|
62
|
+
readonly height: number;
|
|
63
|
+
readonly totalPixels: number;
|
|
64
|
+
readonly changedPixels: number;
|
|
65
|
+
readonly changedRatio: number;
|
|
66
|
+
/** Encoded PNG of the diff overlay; present only when captureArtifacts. */
|
|
67
|
+
readonly diffPng?: Uint8Array;
|
|
68
|
+
}
|
|
69
|
+
/** Layout drift for a single matched element between before/after. */
|
|
70
|
+
interface BBoxDiff {
|
|
71
|
+
/** Best-effort selector / index path identifying the element. */
|
|
72
|
+
readonly path: string;
|
|
73
|
+
readonly before: BoundingBox | null;
|
|
74
|
+
readonly after: BoundingBox | null;
|
|
75
|
+
readonly deltaX: number;
|
|
76
|
+
readonly deltaY: number;
|
|
77
|
+
readonly deltaWidth: number;
|
|
78
|
+
readonly deltaHeight: number;
|
|
79
|
+
/** Max absolute component of the delta, in CSS px. */
|
|
80
|
+
readonly maxDelta: number;
|
|
81
|
+
}
|
|
82
|
+
/** Computed-style mismatch for one property on one element. */
|
|
83
|
+
interface StyleDiff {
|
|
84
|
+
readonly path: string;
|
|
85
|
+
readonly property: string;
|
|
86
|
+
readonly before: string | null;
|
|
87
|
+
readonly after: string | null;
|
|
88
|
+
}
|
|
89
|
+
type Equivalence = 'equivalent' | 'divergent' | 'inconclusive';
|
|
90
|
+
interface ViewportResult {
|
|
91
|
+
readonly viewport: Viewport;
|
|
92
|
+
readonly equivalence: Equivalence;
|
|
93
|
+
readonly pixel: PixelDiff;
|
|
94
|
+
readonly boxes: readonly BBoxDiff[];
|
|
95
|
+
readonly styles: readonly StyleDiff[];
|
|
96
|
+
/** Present only when captureArtifacts. */
|
|
97
|
+
readonly beforePng?: Uint8Array;
|
|
98
|
+
readonly afterPng?: Uint8Array;
|
|
99
|
+
}
|
|
100
|
+
interface VerifyResult {
|
|
101
|
+
readonly equivalence: Equivalence;
|
|
102
|
+
readonly engine: BrowserEngine;
|
|
103
|
+
readonly viewports: readonly ViewportResult[];
|
|
104
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
105
|
+
readonly durationMs: number;
|
|
106
|
+
}
|
|
107
|
+
declare const DEFAULT_VIEWPORTS: readonly Viewport[];
|
|
108
|
+
declare const DEFAULT_VERIFY_OPTIONS: {
|
|
109
|
+
readonly engine: "chromium";
|
|
110
|
+
readonly pixelThreshold: 2;
|
|
111
|
+
readonly maxPixelRatio: 0;
|
|
112
|
+
readonly maxBoxDeltaPx: 0.5;
|
|
113
|
+
readonly timeoutMs: 30000;
|
|
114
|
+
readonly captureArtifacts: false;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @domflax/verify — deterministic headless render + artifact capture.
|
|
119
|
+
*
|
|
120
|
+
* Accepts an HTML-string fragment (or a full document) and produces, for a
|
|
121
|
+
* single viewport:
|
|
122
|
+
* - a viewport-clipped PNG screenshot (equal dimensions for before/after, so
|
|
123
|
+
* pixelmatch never sees a size mismatch), and
|
|
124
|
+
* - the list of VISUAL LEAVES with their bounding boxes + computed styles.
|
|
125
|
+
*
|
|
126
|
+
* Determinism is pinned hard: animations/transitions/caret disabled, reduced
|
|
127
|
+
* motion forced, fonts awaited, and layout settled across two animation frames
|
|
128
|
+
* before anything is measured.
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/** A measured visual leaf — see {@link extractLeaves}. */
|
|
132
|
+
interface LeafSnapshot {
|
|
133
|
+
/** Lower-cased tag name. */
|
|
134
|
+
readonly tag: string;
|
|
135
|
+
/** ARIA role if set, else the tag — the structure-independent identity. */
|
|
136
|
+
readonly role: string;
|
|
137
|
+
/** Trimmed direct text content (own text nodes only). */
|
|
138
|
+
readonly text: string;
|
|
139
|
+
/** Layout geometry in CSS pixels, viewport-relative. */
|
|
140
|
+
readonly box: {
|
|
141
|
+
readonly x: number;
|
|
142
|
+
readonly y: number;
|
|
143
|
+
readonly width: number;
|
|
144
|
+
readonly height: number;
|
|
145
|
+
};
|
|
146
|
+
/** Requested computed-style properties, raw (normalization happens in diff). */
|
|
147
|
+
readonly styles: Record<string, string>;
|
|
148
|
+
}
|
|
149
|
+
interface RenderArtifacts {
|
|
150
|
+
readonly png: Uint8Array;
|
|
151
|
+
readonly leaves: readonly LeafSnapshot[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @domflax/verify — pure diff engine (no browser, fully unit-testable)
|
|
156
|
+
*
|
|
157
|
+
* Three independent comparison passes operate on the artifacts captured from a
|
|
158
|
+
* rendered page (see {@link ./render}):
|
|
159
|
+
*
|
|
160
|
+
* 1. {@link pixelDiff} — per-pixel delta of the two screenshots (pixelmatch + pngjs).
|
|
161
|
+
* 2. {@link diffBoxes} — per-visual-leaf bounding-box drift.
|
|
162
|
+
* 3. {@link diffStyles} — per-visual-leaf computed-style mismatch, NORMALIZED.
|
|
163
|
+
*
|
|
164
|
+
* Passes 2 and 3 are STRUCTURE-INDEPENDENT: leaves are matched by (role, text)
|
|
165
|
+
* and visual position order, never by DOM index — node counts legitimately
|
|
166
|
+
* differ once a transform flattens wrappers, so DOM-order matching would be
|
|
167
|
+
* meaningless.
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
declare const DEFAULT_STYLE_PROPERTIES: readonly string[];
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @domflax/verify — headless browser lifecycle.
|
|
174
|
+
*
|
|
175
|
+
* One shared {@link Browser} is launched and reused across every viewport and
|
|
176
|
+
* every fixture in a run (see {@link ./index}'s `createVerifier`), which is the
|
|
177
|
+
* batching primitive the maintainer-side oracle needs when validating many
|
|
178
|
+
* fixtures at once.
|
|
179
|
+
*
|
|
180
|
+
* Critically, a launch failure (no downloaded browser binary on a bare CI box)
|
|
181
|
+
* is reported as a value, never thrown past the public API — the verifier then
|
|
182
|
+
* returns an `inconclusive` verdict instead of hard-failing.
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Probe whether the engine can actually launch on this machine. Used by tests
|
|
187
|
+
* to `skipIf` cleanly when no browser is present, keeping browserless CI green.
|
|
188
|
+
*/
|
|
189
|
+
declare function isBrowserAvailable(engine?: BrowserEngine): Promise<boolean>;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @domflax/verify — the maintainer-side Tier-2 equivalence oracle.
|
|
193
|
+
*
|
|
194
|
+
* Renders the `before` and `after` source of a single-file transform in a real
|
|
195
|
+
* headless browser and proves they are visually + structurally equivalent
|
|
196
|
+
* across a matrix of viewports. For each viewport it runs three independent
|
|
197
|
+
* passes (pixel, bounding-box, computed-style) and folds them into one verdict.
|
|
198
|
+
*
|
|
199
|
+
* The comparison is STRUCTURE-INDEPENDENT by design: node counts legitimately
|
|
200
|
+
* change once a transform flattens wrappers, so leaves are matched by visual
|
|
201
|
+
* role/text/position, never by DOM index (see {@link ./diff}).
|
|
202
|
+
*
|
|
203
|
+
* If no browser binary is available the verifier returns an `inconclusive`
|
|
204
|
+
* verdict (never throws), so browserless CI stays green.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
/** Fully-resolved options used by the render+diff engine. */
|
|
208
|
+
interface ResolvedVerifyOptions {
|
|
209
|
+
readonly viewports: readonly Viewport[];
|
|
210
|
+
readonly engine: BrowserEngine;
|
|
211
|
+
readonly pixelThreshold: number;
|
|
212
|
+
readonly maxPixelRatio: number;
|
|
213
|
+
readonly maxBoxDeltaPx: number;
|
|
214
|
+
readonly styleProperties: readonly string[];
|
|
215
|
+
readonly timeoutMs: number;
|
|
216
|
+
readonly captureArtifacts: boolean;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Merge caller options over the verifier defaults. Pure and total — safe to use
|
|
220
|
+
* for config validation / dry-run planning.
|
|
221
|
+
*/
|
|
222
|
+
declare function resolveVerifyOptions(opts?: VerifyOptions): ResolvedVerifyOptions;
|
|
223
|
+
interface Verifier {
|
|
224
|
+
/** Verify one before/after pair. Per-call options override the verifier defaults. */
|
|
225
|
+
verify(before: RenderTarget, after: RenderTarget, opts?: VerifyOptions): Promise<VerifyResult>;
|
|
226
|
+
/** Close the shared browser. Safe to call multiple times. */
|
|
227
|
+
close(): Promise<void>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create a verifier that holds ONE browser open across many {@link Verifier.verify}
|
|
231
|
+
* calls — the efficient path for validating a corpus of fixtures. The browser is
|
|
232
|
+
* launched lazily on first use; if launch fails (no binary), every `verify` call
|
|
233
|
+
* returns an `inconclusive` verdict rather than throwing.
|
|
234
|
+
*/
|
|
235
|
+
declare function createVerifier(): Verifier;
|
|
236
|
+
/**
|
|
237
|
+
* One-shot equivalence check: render `before` and `after` and prove visual +
|
|
238
|
+
* structural equivalence across every viewport. Launches a single browser for
|
|
239
|
+
* the call and closes it afterwards.
|
|
240
|
+
*
|
|
241
|
+
* Returns an `inconclusive` verdict (never throws) when no browser is available.
|
|
242
|
+
*/
|
|
243
|
+
declare function verifyEquivalence(before: RenderTarget, after: RenderTarget, opts?: VerifyOptions): Promise<VerifyResult>;
|
|
244
|
+
|
|
245
|
+
export { type BBoxDiff, type BoundingBox, type BrowserEngine, DEFAULT_STYLE_PROPERTIES, DEFAULT_VERIFY_OPTIONS, DEFAULT_VIEWPORTS, type Equivalence, type LeafSnapshot, type PixelDiff, type RenderArtifacts, type RenderTarget, type ResolvedVerifyOptions, type StyleDiff, type Verifier, type VerifyOptions, type VerifyResult, type Viewport, type ViewportResult, createVerifier, isBrowserAvailable, resolveVerifyOptions, verifyEquivalence };
|