@keboola/validate-ui 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,81 @@
1
1
  import { Page, Browser } from 'playwright';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Backend/render state of a region. A region that rendered its data is `ok`;
6
+ * `empty`/`error`/`loading` are non-data states — an old→new transition into one
7
+ * of them is a degrade, not a value regression (a backend was unavailable, or an
8
+ * intentional empty state is showing).
9
+ */
10
+ declare const REGION_STATES: readonly ["ok", "empty", "error", "loading"];
11
+ type RegionState = (typeof REGION_STATES)[number];
12
+ /** One diffable region of a page — a landmark, labelled section, or component. */
13
+ declare const Region: z.ZodObject<{
14
+ key: z.ZodString;
15
+ label: z.ZodString;
16
+ state: z.ZodEnum<{
17
+ ok: "ok";
18
+ empty: "empty";
19
+ error: "error";
20
+ loading: "loading";
21
+ }>;
22
+ values: z.ZodArray<z.ZodString>;
23
+ }, z.core.$strip>;
24
+ type Region = z.infer<typeof Region>;
25
+ /**
26
+ * A page reduced to its diffable regions — the currency both input paths (a live
27
+ * boot or a recorded JSON file) produce and the differ consumes. Pure JSON, so
28
+ * it is safe to serialize to disk and re-load; {@link loadSnapshot} validates it.
29
+ */
30
+ declare const CompareSnapshot: z.ZodObject<{
31
+ route: z.ZodString;
32
+ regions: z.ZodArray<z.ZodObject<{
33
+ key: z.ZodString;
34
+ label: z.ZodString;
35
+ state: z.ZodEnum<{
36
+ ok: "ok";
37
+ empty: "empty";
38
+ error: "error";
39
+ loading: "loading";
40
+ }>;
41
+ values: z.ZodArray<z.ZodString>;
42
+ }, z.core.$strip>>;
43
+ }, z.core.$strip>;
44
+ type CompareSnapshot = z.infer<typeof CompareSnapshot>;
45
+ /** One old-vs-new delta, always attributed to a region. */
46
+ type CompareFinding = Finding & {
47
+ regionKey: string;
48
+ kind: 'region-removed' | 'region-degraded' | 'value-missing' | 'region-added';
49
+ /** Stable signature of the delta — identical across routes for shared chrome. */
50
+ valueSignature: string;
51
+ /** Present when a config rule suppressed this delta; it never fails the verdict. */
52
+ suppressed?: {
53
+ reason: string;
54
+ };
55
+ };
56
+ /**
57
+ * One expected-absent rule. `region` (exact or `*`-glob against {@link Region.key})
58
+ * alone suppresses a whole `region-removed`; add `value` to suppress a specific
59
+ * missing value token (optionally scoped to a region). `reason` is required and
60
+ * surfaced in the report so suppression is auditable, never silent.
61
+ */
62
+ declare const ExpectedAbsentRule: z.ZodObject<{
63
+ region: z.ZodOptional<z.ZodString>;
64
+ value: z.ZodOptional<z.ZodString>;
65
+ reason: z.ZodString;
66
+ }, z.core.$strip>;
67
+ type ExpectedAbsentRule = z.infer<typeof ExpectedAbsentRule>;
68
+ /** Semantic-compare configuration — the allowlist plus extra state markers. */
69
+ declare const CompareConfig: z.ZodObject<{
70
+ expectedAbsent: z.ZodOptional<z.ZodArray<z.ZodObject<{
71
+ region: z.ZodOptional<z.ZodString>;
72
+ value: z.ZodOptional<z.ZodString>;
73
+ reason: z.ZodString;
74
+ }, z.core.$strip>>>;
75
+ emptyStateMarkers: z.ZodOptional<z.ZodArray<z.ZodString>>;
76
+ errorStateMarkers: z.ZodOptional<z.ZodArray<z.ZodString>>;
77
+ }, z.core.$strip>;
78
+ type CompareConfig = z.infer<typeof CompareConfig>;
2
79
 
3
80
  /** A named viewport the harness renders and captures at. */
4
81
  type Viewport = {
@@ -84,11 +161,15 @@ type AxisContext = {
84
161
  baseline?: Uint8Array;
85
162
  /** Re-render the same route under a different brand id and capture it. */
86
163
  captureUnderBrand?: (brand: string) => Promise<CaptureArtifact>;
164
+ /** The "old" UI reduced to regions — enables the compare axis when present. */
165
+ comparison?: CompareSnapshot;
166
+ /** Allowlist + state markers for the compare axis. */
167
+ compareConfig?: CompareConfig;
87
168
  };
88
169
  /**
89
- * A verdict axis. Each of the four axes (runtime-health, accessibility,
90
- * visual-brand, brief-conformance) implements this contract in its own file so
91
- * they can be built independently. `run` must resolve to a {@link Verdict} and
170
+ * A verdict axis. Each of the axes (runtime-health, accessibility,
171
+ * visual-brand, brief-conformance, compare) implements this contract in its own
172
+ * file so they can be built independently. `run` must resolve to a {@link Verdict} and
92
173
  * should not throw for expected-missing input — the aggregator converts a throw
93
174
  * into a failing verdict, but a clear finding is better.
94
175
  */
@@ -157,6 +238,10 @@ type ValidateOptions = {
157
238
  /** Reuse a browser instead of launching one. */
158
239
  browser?: Browser;
159
240
  timeoutMs?: number;
241
+ /** The "old" UI reduced to regions — enables the compare axis when present. */
242
+ comparison?: CompareSnapshot;
243
+ /** Allowlist + state markers for the compare axis. */
244
+ compareConfig?: CompareConfig;
160
245
  };
161
246
  /**
162
247
  * The closed loop: render `url`, capture ground truth, and run every axis over
@@ -170,6 +255,18 @@ declare const accessibilityAxis: Axis;
170
255
 
171
256
  declare const briefConformanceAxis: Axis;
172
257
 
258
+ /**
259
+ * A5 · Semantic old-vs-new compare verdict — UT-4572.
260
+ *
261
+ * Activates only when `context.comparison` (an "old" {@link CompareSnapshot}) is
262
+ * supplied; otherwise it degrades to a passing skip, so ordinary single-page runs
263
+ * are unaffected. Extracts the "new" snapshot from the live `context.page`, then
264
+ * runs the pure {@link diffSnapshots}: deltas are localized per region, declared
265
+ * expected-absent deltas are suppressed (not dropped), and a region that degraded
266
+ * to an empty/error state is reported informationally rather than as value loss.
267
+ */
268
+ declare const compareAxis: Axis;
269
+
173
270
  /**
174
271
  * A2 · Runtime-health verdict — UT-4493.
175
272
  *
@@ -191,7 +288,101 @@ declare const runtimeHealthAxis: Axis;
191
288
  */
192
289
  declare const visualBrandAxis: Axis;
193
290
 
194
- /** The four axes, in report order. */
291
+ /**
292
+ * The registered axes, in report order. `compare` runs last and only activates
293
+ * when a comparison snapshot is supplied, so ordinary single-page runs are
294
+ * unaffected.
295
+ */
195
296
  declare const ALL_AXES: Axis[];
196
297
 
197
- export { ALL_AXES, type AggregateVerdict, type Axis, type AxisContext, type CaptureArtifact, type CaptureOptions, type ConsoleEntry, DEFAULT_VIEWPORTS, DESKTOP_VIEWPORT, type Finding, MOBILE_VIEWPORT, type NetworkEntry, SEVERITIES, type Severity, type StaticServer, type ValidateOptions, type Verdict, type Viewport, accessibilityAxis, aggregatePass, briefConformanceAxis, capture, capturePage, prepareForScreenshot, runAxes, runtimeHealthAxis, serveStatic, validate, visualBrandAxis };
298
+ /**
299
+ * Semantic old-vs-new diff of two snapshots. Walks regions by key and localizes
300
+ * every delta to a region: a removed region is `serious` unless allowlisted; a
301
+ * region that degraded to an empty/error state is reported informationally and
302
+ * NOT diffed as value loss; surviving regions get a per-region value-multiset
303
+ * diff with allowlist suppression; new regions are non-regression notes. Pure —
304
+ * no browser, no I/O.
305
+ */
306
+ declare const diffSnapshots: (oldSnap: CompareSnapshot, newSnap: CompareSnapshot, config?: CompareConfig) => CompareFinding[];
307
+ /** A compare run passes when no active (non-suppressed) delta is serious/critical. */
308
+ declare const comparePass: (findings: CompareFinding[]) => boolean;
309
+
310
+ /** One route's compare findings. */
311
+ type RouteFindings = {
312
+ route: string;
313
+ findings: CompareFinding[];
314
+ };
315
+ type DedupResult = {
316
+ /** Findings seen on ≥2 routes, collapsed to one entry tagged with the route count. */
317
+ sharedChrome: CompareFinding[];
318
+ /** Per-route findings with the shared-chrome copies removed. */
319
+ perRoute: RouteFindings[];
320
+ };
321
+ /**
322
+ * Collapse deltas that recur across routes into a single `shared-chrome` finding.
323
+ * A value flagged on a shared header/daily-brief element would otherwise be
324
+ * multiplied across every route (the prototype's `8.4/7.7/-8%/67%` on all 10
325
+ * pages); here it is reported once, tagged with the routes it spans, and dropped
326
+ * from each route's own list. Pure — no browser, no I/O.
327
+ */
328
+ declare const dedupeSharedChrome: (perRoute: RouteFindings[]) => DedupResult;
329
+
330
+ /**
331
+ * Reduce the live page to its diffable regions, in the browser. An explicit
332
+ * `[data-region]` is an authoritative boundary (its subtree is one region);
333
+ * elsewhere boundaries are the outermost-empty ("leaf") landmarks/sections, so
334
+ * regions never overlap or double-count values. Each region's key is resolved by
335
+ * precedence
336
+ * (`data-region` → `data-testid` → role → `aria-label` → nearest heading), its
337
+ * state from `data-state`/text markers, and its values as normalized numeric
338
+ * tokens. Symmetric across old and new so the two sides diff cleanly.
339
+ */
340
+ declare const extractRegions: (page: Page, config?: CompareConfig) => Promise<Region[]>;
341
+
342
+ /** How the "old" side is sourced — booted live or loaded from recorded snapshots, never both. */
343
+ type OldSource = {
344
+ oldBaseUrl: string;
345
+ oldSnapshotDir?: never;
346
+ } | {
347
+ oldSnapshotDir: string;
348
+ oldBaseUrl?: never;
349
+ };
350
+ type CompareRoutesOptions = OldSource & {
351
+ /** Base URL of the new build, joined with each route. */
352
+ newBaseUrl: string;
353
+ routes: string[];
354
+ config?: CompareConfig;
355
+ browser?: Browser;
356
+ viewport?: Viewport;
357
+ timeoutMs?: number;
358
+ };
359
+ type RouteCompareResult = {
360
+ route: string;
361
+ findings: CompareFinding[];
362
+ pass: boolean;
363
+ };
364
+ type CompareRoutesResult = {
365
+ routes: RouteCompareResult[];
366
+ /** Deltas seen on ≥2 routes, reported once (e.g. shared chrome / daily-brief). */
367
+ sharedChrome: CompareFinding[];
368
+ pass: boolean;
369
+ };
370
+ /** Recorded old snapshot filename for a route: `/a/b` → `a_b.json`, `/` → `index.json`. */
371
+ declare const routeSnapshotFile: (route: string) => string;
372
+ /**
373
+ * Multi-route semantic compare. Boots each route on the new side (and the old
374
+ * side too, unless recorded snapshots are supplied), diffs per route, then
375
+ * collapses deltas that recur across routes into a single shared-chrome entry so
376
+ * one shared element is not reported as N regressions. Exactly one of
377
+ * `oldBaseUrl` / `oldSnapshotDir` must be given.
378
+ */
379
+ declare const compareRoutes: (options: CompareRoutesOptions) => Promise<CompareRoutesResult>;
380
+
381
+ /** Reduce a loaded live page to a {@link CompareSnapshot} for the given route. */
382
+ declare const captureSnapshot: (page: Page, route: string, config?: CompareConfig) => Promise<CompareSnapshot>;
383
+ /** Persist a snapshot as pretty JSON so an "old" side can be recorded once and re-diffed. */
384
+ declare const saveSnapshot: (snapshot: CompareSnapshot, path: string) => Promise<void>;
385
+ /** Read and validate a recorded snapshot from disk. */
386
+ declare const loadSnapshot: (path: string) => Promise<CompareSnapshot>;
387
+
388
+ export { ALL_AXES, type AggregateVerdict, type Axis, type AxisContext, type CaptureArtifact, type CaptureOptions, CompareConfig, type CompareFinding, type CompareRoutesOptions, type CompareRoutesResult, CompareSnapshot, type ConsoleEntry, DEFAULT_VIEWPORTS, DESKTOP_VIEWPORT, type DedupResult, ExpectedAbsentRule, type Finding, MOBILE_VIEWPORT, type NetworkEntry, REGION_STATES, Region, type RegionState, type RouteCompareResult, type RouteFindings, SEVERITIES, type Severity, type StaticServer, type ValidateOptions, type Verdict, type Viewport, accessibilityAxis, aggregatePass, briefConformanceAxis, capture, capturePage, captureSnapshot, compareAxis, comparePass, compareRoutes, dedupeSharedChrome, diffSnapshots, extractRegions, loadSnapshot, prepareForScreenshot, routeSnapshotFile, runAxes, runtimeHealthAxis, saveSnapshot, serveStatic, validate, visualBrandAxis };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,81 @@
1
1
  import { Page, Browser } from 'playwright';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Backend/render state of a region. A region that rendered its data is `ok`;
6
+ * `empty`/`error`/`loading` are non-data states — an old→new transition into one
7
+ * of them is a degrade, not a value regression (a backend was unavailable, or an
8
+ * intentional empty state is showing).
9
+ */
10
+ declare const REGION_STATES: readonly ["ok", "empty", "error", "loading"];
11
+ type RegionState = (typeof REGION_STATES)[number];
12
+ /** One diffable region of a page — a landmark, labelled section, or component. */
13
+ declare const Region: z.ZodObject<{
14
+ key: z.ZodString;
15
+ label: z.ZodString;
16
+ state: z.ZodEnum<{
17
+ ok: "ok";
18
+ empty: "empty";
19
+ error: "error";
20
+ loading: "loading";
21
+ }>;
22
+ values: z.ZodArray<z.ZodString>;
23
+ }, z.core.$strip>;
24
+ type Region = z.infer<typeof Region>;
25
+ /**
26
+ * A page reduced to its diffable regions — the currency both input paths (a live
27
+ * boot or a recorded JSON file) produce and the differ consumes. Pure JSON, so
28
+ * it is safe to serialize to disk and re-load; {@link loadSnapshot} validates it.
29
+ */
30
+ declare const CompareSnapshot: z.ZodObject<{
31
+ route: z.ZodString;
32
+ regions: z.ZodArray<z.ZodObject<{
33
+ key: z.ZodString;
34
+ label: z.ZodString;
35
+ state: z.ZodEnum<{
36
+ ok: "ok";
37
+ empty: "empty";
38
+ error: "error";
39
+ loading: "loading";
40
+ }>;
41
+ values: z.ZodArray<z.ZodString>;
42
+ }, z.core.$strip>>;
43
+ }, z.core.$strip>;
44
+ type CompareSnapshot = z.infer<typeof CompareSnapshot>;
45
+ /** One old-vs-new delta, always attributed to a region. */
46
+ type CompareFinding = Finding & {
47
+ regionKey: string;
48
+ kind: 'region-removed' | 'region-degraded' | 'value-missing' | 'region-added';
49
+ /** Stable signature of the delta — identical across routes for shared chrome. */
50
+ valueSignature: string;
51
+ /** Present when a config rule suppressed this delta; it never fails the verdict. */
52
+ suppressed?: {
53
+ reason: string;
54
+ };
55
+ };
56
+ /**
57
+ * One expected-absent rule. `region` (exact or `*`-glob against {@link Region.key})
58
+ * alone suppresses a whole `region-removed`; add `value` to suppress a specific
59
+ * missing value token (optionally scoped to a region). `reason` is required and
60
+ * surfaced in the report so suppression is auditable, never silent.
61
+ */
62
+ declare const ExpectedAbsentRule: z.ZodObject<{
63
+ region: z.ZodOptional<z.ZodString>;
64
+ value: z.ZodOptional<z.ZodString>;
65
+ reason: z.ZodString;
66
+ }, z.core.$strip>;
67
+ type ExpectedAbsentRule = z.infer<typeof ExpectedAbsentRule>;
68
+ /** Semantic-compare configuration — the allowlist plus extra state markers. */
69
+ declare const CompareConfig: z.ZodObject<{
70
+ expectedAbsent: z.ZodOptional<z.ZodArray<z.ZodObject<{
71
+ region: z.ZodOptional<z.ZodString>;
72
+ value: z.ZodOptional<z.ZodString>;
73
+ reason: z.ZodString;
74
+ }, z.core.$strip>>>;
75
+ emptyStateMarkers: z.ZodOptional<z.ZodArray<z.ZodString>>;
76
+ errorStateMarkers: z.ZodOptional<z.ZodArray<z.ZodString>>;
77
+ }, z.core.$strip>;
78
+ type CompareConfig = z.infer<typeof CompareConfig>;
2
79
 
3
80
  /** A named viewport the harness renders and captures at. */
4
81
  type Viewport = {
@@ -84,11 +161,15 @@ type AxisContext = {
84
161
  baseline?: Uint8Array;
85
162
  /** Re-render the same route under a different brand id and capture it. */
86
163
  captureUnderBrand?: (brand: string) => Promise<CaptureArtifact>;
164
+ /** The "old" UI reduced to regions — enables the compare axis when present. */
165
+ comparison?: CompareSnapshot;
166
+ /** Allowlist + state markers for the compare axis. */
167
+ compareConfig?: CompareConfig;
87
168
  };
88
169
  /**
89
- * A verdict axis. Each of the four axes (runtime-health, accessibility,
90
- * visual-brand, brief-conformance) implements this contract in its own file so
91
- * they can be built independently. `run` must resolve to a {@link Verdict} and
170
+ * A verdict axis. Each of the axes (runtime-health, accessibility,
171
+ * visual-brand, brief-conformance, compare) implements this contract in its own
172
+ * file so they can be built independently. `run` must resolve to a {@link Verdict} and
92
173
  * should not throw for expected-missing input — the aggregator converts a throw
93
174
  * into a failing verdict, but a clear finding is better.
94
175
  */
@@ -157,6 +238,10 @@ type ValidateOptions = {
157
238
  /** Reuse a browser instead of launching one. */
158
239
  browser?: Browser;
159
240
  timeoutMs?: number;
241
+ /** The "old" UI reduced to regions — enables the compare axis when present. */
242
+ comparison?: CompareSnapshot;
243
+ /** Allowlist + state markers for the compare axis. */
244
+ compareConfig?: CompareConfig;
160
245
  };
161
246
  /**
162
247
  * The closed loop: render `url`, capture ground truth, and run every axis over
@@ -170,6 +255,18 @@ declare const accessibilityAxis: Axis;
170
255
 
171
256
  declare const briefConformanceAxis: Axis;
172
257
 
258
+ /**
259
+ * A5 · Semantic old-vs-new compare verdict — UT-4572.
260
+ *
261
+ * Activates only when `context.comparison` (an "old" {@link CompareSnapshot}) is
262
+ * supplied; otherwise it degrades to a passing skip, so ordinary single-page runs
263
+ * are unaffected. Extracts the "new" snapshot from the live `context.page`, then
264
+ * runs the pure {@link diffSnapshots}: deltas are localized per region, declared
265
+ * expected-absent deltas are suppressed (not dropped), and a region that degraded
266
+ * to an empty/error state is reported informationally rather than as value loss.
267
+ */
268
+ declare const compareAxis: Axis;
269
+
173
270
  /**
174
271
  * A2 · Runtime-health verdict — UT-4493.
175
272
  *
@@ -191,7 +288,101 @@ declare const runtimeHealthAxis: Axis;
191
288
  */
192
289
  declare const visualBrandAxis: Axis;
193
290
 
194
- /** The four axes, in report order. */
291
+ /**
292
+ * The registered axes, in report order. `compare` runs last and only activates
293
+ * when a comparison snapshot is supplied, so ordinary single-page runs are
294
+ * unaffected.
295
+ */
195
296
  declare const ALL_AXES: Axis[];
196
297
 
197
- export { ALL_AXES, type AggregateVerdict, type Axis, type AxisContext, type CaptureArtifact, type CaptureOptions, type ConsoleEntry, DEFAULT_VIEWPORTS, DESKTOP_VIEWPORT, type Finding, MOBILE_VIEWPORT, type NetworkEntry, SEVERITIES, type Severity, type StaticServer, type ValidateOptions, type Verdict, type Viewport, accessibilityAxis, aggregatePass, briefConformanceAxis, capture, capturePage, prepareForScreenshot, runAxes, runtimeHealthAxis, serveStatic, validate, visualBrandAxis };
298
+ /**
299
+ * Semantic old-vs-new diff of two snapshots. Walks regions by key and localizes
300
+ * every delta to a region: a removed region is `serious` unless allowlisted; a
301
+ * region that degraded to an empty/error state is reported informationally and
302
+ * NOT diffed as value loss; surviving regions get a per-region value-multiset
303
+ * diff with allowlist suppression; new regions are non-regression notes. Pure —
304
+ * no browser, no I/O.
305
+ */
306
+ declare const diffSnapshots: (oldSnap: CompareSnapshot, newSnap: CompareSnapshot, config?: CompareConfig) => CompareFinding[];
307
+ /** A compare run passes when no active (non-suppressed) delta is serious/critical. */
308
+ declare const comparePass: (findings: CompareFinding[]) => boolean;
309
+
310
+ /** One route's compare findings. */
311
+ type RouteFindings = {
312
+ route: string;
313
+ findings: CompareFinding[];
314
+ };
315
+ type DedupResult = {
316
+ /** Findings seen on ≥2 routes, collapsed to one entry tagged with the route count. */
317
+ sharedChrome: CompareFinding[];
318
+ /** Per-route findings with the shared-chrome copies removed. */
319
+ perRoute: RouteFindings[];
320
+ };
321
+ /**
322
+ * Collapse deltas that recur across routes into a single `shared-chrome` finding.
323
+ * A value flagged on a shared header/daily-brief element would otherwise be
324
+ * multiplied across every route (the prototype's `8.4/7.7/-8%/67%` on all 10
325
+ * pages); here it is reported once, tagged with the routes it spans, and dropped
326
+ * from each route's own list. Pure — no browser, no I/O.
327
+ */
328
+ declare const dedupeSharedChrome: (perRoute: RouteFindings[]) => DedupResult;
329
+
330
+ /**
331
+ * Reduce the live page to its diffable regions, in the browser. An explicit
332
+ * `[data-region]` is an authoritative boundary (its subtree is one region);
333
+ * elsewhere boundaries are the outermost-empty ("leaf") landmarks/sections, so
334
+ * regions never overlap or double-count values. Each region's key is resolved by
335
+ * precedence
336
+ * (`data-region` → `data-testid` → role → `aria-label` → nearest heading), its
337
+ * state from `data-state`/text markers, and its values as normalized numeric
338
+ * tokens. Symmetric across old and new so the two sides diff cleanly.
339
+ */
340
+ declare const extractRegions: (page: Page, config?: CompareConfig) => Promise<Region[]>;
341
+
342
+ /** How the "old" side is sourced — booted live or loaded from recorded snapshots, never both. */
343
+ type OldSource = {
344
+ oldBaseUrl: string;
345
+ oldSnapshotDir?: never;
346
+ } | {
347
+ oldSnapshotDir: string;
348
+ oldBaseUrl?: never;
349
+ };
350
+ type CompareRoutesOptions = OldSource & {
351
+ /** Base URL of the new build, joined with each route. */
352
+ newBaseUrl: string;
353
+ routes: string[];
354
+ config?: CompareConfig;
355
+ browser?: Browser;
356
+ viewport?: Viewport;
357
+ timeoutMs?: number;
358
+ };
359
+ type RouteCompareResult = {
360
+ route: string;
361
+ findings: CompareFinding[];
362
+ pass: boolean;
363
+ };
364
+ type CompareRoutesResult = {
365
+ routes: RouteCompareResult[];
366
+ /** Deltas seen on ≥2 routes, reported once (e.g. shared chrome / daily-brief). */
367
+ sharedChrome: CompareFinding[];
368
+ pass: boolean;
369
+ };
370
+ /** Recorded old snapshot filename for a route: `/a/b` → `a_b.json`, `/` → `index.json`. */
371
+ declare const routeSnapshotFile: (route: string) => string;
372
+ /**
373
+ * Multi-route semantic compare. Boots each route on the new side (and the old
374
+ * side too, unless recorded snapshots are supplied), diffs per route, then
375
+ * collapses deltas that recur across routes into a single shared-chrome entry so
376
+ * one shared element is not reported as N regressions. Exactly one of
377
+ * `oldBaseUrl` / `oldSnapshotDir` must be given.
378
+ */
379
+ declare const compareRoutes: (options: CompareRoutesOptions) => Promise<CompareRoutesResult>;
380
+
381
+ /** Reduce a loaded live page to a {@link CompareSnapshot} for the given route. */
382
+ declare const captureSnapshot: (page: Page, route: string, config?: CompareConfig) => Promise<CompareSnapshot>;
383
+ /** Persist a snapshot as pretty JSON so an "old" side can be recorded once and re-diffed. */
384
+ declare const saveSnapshot: (snapshot: CompareSnapshot, path: string) => Promise<void>;
385
+ /** Read and validate a recorded snapshot from disk. */
386
+ declare const loadSnapshot: (path: string) => Promise<CompareSnapshot>;
387
+
388
+ export { ALL_AXES, type AggregateVerdict, type Axis, type AxisContext, type CaptureArtifact, type CaptureOptions, CompareConfig, type CompareFinding, type CompareRoutesOptions, type CompareRoutesResult, CompareSnapshot, type ConsoleEntry, DEFAULT_VIEWPORTS, DESKTOP_VIEWPORT, type DedupResult, ExpectedAbsentRule, type Finding, MOBILE_VIEWPORT, type NetworkEntry, REGION_STATES, Region, type RegionState, type RouteCompareResult, type RouteFindings, SEVERITIES, type Severity, type StaticServer, type ValidateOptions, type Verdict, type Viewport, accessibilityAxis, aggregatePass, briefConformanceAxis, capture, capturePage, captureSnapshot, compareAxis, comparePass, compareRoutes, dedupeSharedChrome, diffSnapshots, extractRegions, loadSnapshot, prepareForScreenshot, routeSnapshotFile, runAxes, runtimeHealthAxis, saveSnapshot, serveStatic, validate, visualBrandAxis };