@testivai/witness 1.0.2 → 1.0.3

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.
@@ -5,8 +5,11 @@
5
5
  *
6
6
  * Directory structure:
7
7
  * .testivai/
8
- * ├── baselines/{name}/screenshot.png, metadata.json, .previous/
9
- * └── temp/{name}/screenshot.png (gitignored)
8
+ * ├── baselines/{name}/screenshot.png, metadata.json, dom.html?, .previous/
9
+ * └── temp/{name}/screenshot.png, dom.html? (gitignored)
10
+ *
11
+ * `dom.html` is optional — written when the adapter captures DOM alongside
12
+ * the screenshot. Used by the DOM-diff noise hint in the local report.
10
13
  */
11
14
  export interface BaselineMetadata {
12
15
  name: string;
@@ -38,8 +41,16 @@ export declare class BaselineStore {
38
41
  /**
39
42
  * Write a screenshot and metadata to the baseline directory.
40
43
  * Creates the directory if it doesn't exist.
44
+ *
45
+ * @param dom - Optional DOM HTML captured at the same time as the
46
+ * screenshot. Stored as `dom.html` for the noise-hint compare.
47
+ */
48
+ write(name: string, screenshot: Buffer, metadata?: Partial<BaselineMetadata>, dom?: string): void;
49
+ /**
50
+ * Read the baseline DOM HTML if one was captured.
51
+ * Returns null when no DOM file exists for this snapshot.
41
52
  */
42
- write(name: string, screenshot: Buffer, metadata?: Partial<BaselineMetadata>): void;
53
+ readDom(name: string): string | null;
43
54
  /**
44
55
  * Approve a temp screenshot as the new baseline.
45
56
  * Backs up the previous baseline to `.previous/` if one exists.
@@ -55,12 +66,20 @@ export declare class BaselineStore {
55
66
  list(): string[];
56
67
  /**
57
68
  * Write a temp screenshot (captured during a test run).
69
+ *
70
+ * @param dom - Optional DOM HTML captured at the same time as the
71
+ * screenshot. Stored as `dom.html` next to the screenshot.
58
72
  */
59
- writeTemp(name: string, screenshot: Buffer): void;
73
+ writeTemp(name: string, screenshot: Buffer, dom?: string): void;
60
74
  /**
61
75
  * Read a temp screenshot.
62
76
  */
63
77
  readTemp(name: string): Buffer | null;
78
+ /**
79
+ * Read the temp DOM HTML if one was captured.
80
+ * Returns null when no temp DOM file exists for this snapshot.
81
+ */
82
+ readTempDom(name: string): string | null;
64
83
  /**
65
84
  * List all temp snapshot names.
66
85
  */
@@ -72,7 +91,9 @@ export declare class BaselineStore {
72
91
  getBaselineDir(name: string): string;
73
92
  getBaselineScreenshotPath(name: string): string;
74
93
  getBaselineMetadataPath(name: string): string;
94
+ getBaselineDomPath(name: string): string;
75
95
  getTempScreenshotPath(name: string): string;
96
+ getTempDomPath(name: string): string;
76
97
  getBaselinesDir(): string;
77
98
  getTempDir(): string;
78
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/baselines/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IAIZ,OAAO,CAAC,QAAQ,CAAC,WAAW;IAHxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAEJ,WAAW,EAAE,MAAM;IAKhD;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAK7B;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQjC;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IASnD;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAkBnF;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAsC3B;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA6BxB;;OAEG;IACH,IAAI,IAAI,MAAM,EAAE;IAUhB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAMjD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQrC;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAUpB;;OAEG;IACH,SAAS,IAAI,IAAI;IAQjB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/C,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI7C,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI3C,eAAe,IAAI,MAAM;IAIzB,UAAU,IAAI,MAAM;CAGrB"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/baselines/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IAIZ,OAAO,CAAC,QAAQ,CAAC,WAAW;IAHxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAEJ,WAAW,EAAE,MAAM;IAKhD;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAK7B;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQjC;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IASnD;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAuBjG;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMpC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkD3B;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAsCxB;;OAEG;IACH,IAAI,IAAI,MAAM,EAAE;IAUhB;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAS/D;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQrC;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMxC;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAUpB;;OAEG;IACH,SAAS,IAAI,IAAI;IAQjB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/C,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI7C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIxC,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI3C,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIpC,eAAe,IAAI,MAAM;IAIzB,UAAU,IAAI,MAAM;CAGrB"}
@@ -6,8 +6,11 @@
6
6
  *
7
7
  * Directory structure:
8
8
  * .testivai/
9
- * ├── baselines/{name}/screenshot.png, metadata.json, .previous/
10
- * └── temp/{name}/screenshot.png (gitignored)
9
+ * ├── baselines/{name}/screenshot.png, metadata.json, dom.html?, .previous/
10
+ * └── temp/{name}/screenshot.png, dom.html? (gitignored)
11
+ *
12
+ * `dom.html` is optional — written when the adapter captures DOM alongside
13
+ * the screenshot. Used by the DOM-diff noise hint in the local report.
11
14
  */
12
15
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
16
  if (k2 === undefined) k2 = k;
@@ -85,12 +88,19 @@ class BaselineStore {
85
88
  /**
86
89
  * Write a screenshot and metadata to the baseline directory.
87
90
  * Creates the directory if it doesn't exist.
91
+ *
92
+ * @param dom - Optional DOM HTML captured at the same time as the
93
+ * screenshot. Stored as `dom.html` for the noise-hint compare.
88
94
  */
89
- write(name, screenshot, metadata) {
95
+ write(name, screenshot, metadata, dom) {
90
96
  const baselineDir = this.getBaselineDir(name);
91
97
  fs.mkdirSync(baselineDir, { recursive: true });
92
98
  // Write screenshot
93
99
  fs.writeFileSync(this.getBaselineScreenshotPath(name), screenshot);
100
+ // Write DOM if provided
101
+ if (dom !== undefined) {
102
+ fs.writeFileSync(this.getBaselineDomPath(name), dom);
103
+ }
94
104
  // Write metadata
95
105
  const now = new Date().toISOString();
96
106
  const meta = {
@@ -101,6 +111,16 @@ class BaselineStore {
101
111
  };
102
112
  fs.writeFileSync(this.getBaselineMetadataPath(name), JSON.stringify(meta, null, 2));
103
113
  }
114
+ /**
115
+ * Read the baseline DOM HTML if one was captured.
116
+ * Returns null when no DOM file exists for this snapshot.
117
+ */
118
+ readDom(name) {
119
+ const domPath = this.getBaselineDomPath(name);
120
+ if (!fs.existsSync(domPath))
121
+ return null;
122
+ return fs.readFileSync(domPath, 'utf-8');
123
+ }
104
124
  /**
105
125
  * Approve a temp screenshot as the new baseline.
106
126
  * Backs up the previous baseline to `.previous/` if one exists.
@@ -114,6 +134,8 @@ class BaselineStore {
114
134
  const previousDir = path.join(baselineDir, '.previous');
115
135
  const currentScreenshot = this.getBaselineScreenshotPath(name);
116
136
  const currentMetadata = this.getBaselineMetadataPath(name);
137
+ const currentDom = this.getBaselineDomPath(name);
138
+ const tempDom = this.getTempDomPath(name);
117
139
  // Backup current baseline if it exists
118
140
  if (fs.existsSync(currentScreenshot)) {
119
141
  fs.mkdirSync(previousDir, { recursive: true });
@@ -121,10 +143,21 @@ class BaselineStore {
121
143
  if (fs.existsSync(currentMetadata)) {
122
144
  fs.copyFileSync(currentMetadata, path.join(previousDir, 'metadata.json'));
123
145
  }
146
+ if (fs.existsSync(currentDom)) {
147
+ fs.copyFileSync(currentDom, path.join(previousDir, 'dom.html'));
148
+ }
124
149
  }
125
150
  // Copy temp to baseline
126
151
  fs.mkdirSync(baselineDir, { recursive: true });
127
152
  fs.copyFileSync(tempScreenshot, currentScreenshot);
153
+ if (fs.existsSync(tempDom)) {
154
+ fs.copyFileSync(tempDom, currentDom);
155
+ }
156
+ else if (fs.existsSync(currentDom)) {
157
+ // Temp had no DOM but baseline did — drop the stale DOM rather
158
+ // than keep an inconsistent pair.
159
+ fs.rmSync(currentDom);
160
+ }
128
161
  // Update metadata
129
162
  const now = new Date().toISOString();
130
163
  const existingMeta = this.readMetadata(name);
@@ -147,8 +180,10 @@ class BaselineStore {
147
180
  }
148
181
  const previousScreenshot = path.join(previousDir, 'screenshot.png');
149
182
  const previousMetadata = path.join(previousDir, 'metadata.json');
183
+ const previousDom = path.join(previousDir, 'dom.html');
150
184
  const currentScreenshot = this.getBaselineScreenshotPath(name);
151
185
  const currentMetadata = this.getBaselineMetadataPath(name);
186
+ const currentDom = this.getBaselineDomPath(name);
152
187
  // Restore previous screenshot
153
188
  if (fs.existsSync(previousScreenshot)) {
154
189
  fs.copyFileSync(previousScreenshot, currentScreenshot);
@@ -157,6 +192,13 @@ class BaselineStore {
157
192
  if (fs.existsSync(previousMetadata)) {
158
193
  fs.copyFileSync(previousMetadata, currentMetadata);
159
194
  }
195
+ // Restore previous DOM (or remove the current one if no previous existed)
196
+ if (fs.existsSync(previousDom)) {
197
+ fs.copyFileSync(previousDom, currentDom);
198
+ }
199
+ else if (fs.existsSync(currentDom)) {
200
+ fs.rmSync(currentDom);
201
+ }
160
202
  // Remove .previous directory
161
203
  fs.rmSync(previousDir, { recursive: true, force: true });
162
204
  }
@@ -174,11 +216,17 @@ class BaselineStore {
174
216
  }
175
217
  /**
176
218
  * Write a temp screenshot (captured during a test run).
219
+ *
220
+ * @param dom - Optional DOM HTML captured at the same time as the
221
+ * screenshot. Stored as `dom.html` next to the screenshot.
177
222
  */
178
- writeTemp(name, screenshot) {
223
+ writeTemp(name, screenshot, dom) {
179
224
  const tempDir = path.join(this.tempDir, name);
180
225
  fs.mkdirSync(tempDir, { recursive: true });
181
226
  fs.writeFileSync(this.getTempScreenshotPath(name), screenshot);
227
+ if (dom !== undefined) {
228
+ fs.writeFileSync(this.getTempDomPath(name), dom);
229
+ }
182
230
  }
183
231
  /**
184
232
  * Read a temp screenshot.
@@ -190,6 +238,16 @@ class BaselineStore {
190
238
  }
191
239
  return fs.readFileSync(tempPath);
192
240
  }
241
+ /**
242
+ * Read the temp DOM HTML if one was captured.
243
+ * Returns null when no temp DOM file exists for this snapshot.
244
+ */
245
+ readTempDom(name) {
246
+ const domPath = this.getTempDomPath(name);
247
+ if (!fs.existsSync(domPath))
248
+ return null;
249
+ return fs.readFileSync(domPath, 'utf-8');
250
+ }
193
251
  /**
194
252
  * List all temp snapshot names.
195
253
  */
@@ -220,9 +278,15 @@ class BaselineStore {
220
278
  getBaselineMetadataPath(name) {
221
279
  return path.join(this.baselinesDir, name, 'metadata.json');
222
280
  }
281
+ getBaselineDomPath(name) {
282
+ return path.join(this.baselinesDir, name, 'dom.html');
283
+ }
223
284
  getTempScreenshotPath(name) {
224
285
  return path.join(this.tempDir, name, 'screenshot.png');
225
286
  }
287
+ getTempDomPath(name) {
288
+ return path.join(this.tempDir, name, 'dom.html');
289
+ }
226
290
  getBaselinesDir() {
227
291
  return this.baselinesDir;
228
292
  }
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/baselines/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/baselines/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * TestivAI DOM Diff — lightweight noise-hint comparison
3
+ *
4
+ * Compares two HTML strings (typically `document.documentElement.outerHTML`
5
+ * captured at snapshot time) and returns a small structural-change summary.
6
+ *
7
+ * This is intentionally NOT a full DOM tree differ — those bring 30 KB+ of
8
+ * dependencies and complex semantics we don't need. The job here is to
9
+ * answer one question per snapshot:
10
+ *
11
+ * "When pixels differ, is the underlying DOM also different?"
12
+ *
13
+ * If pixels differ but DOM is unchanged, the difference is almost certainly
14
+ * render noise (font rendering, anti-aliasing, sub-pixel layout). The HTML
15
+ * report uses this as a noise hint.
16
+ *
17
+ * Approach (zero-dep, ~120 LOC of tokenizer):
18
+ * 1. Stream-tokenize each HTML into a flat list of open events
19
+ * (`{ tag, attrs: Record<string, string> }`).
20
+ * 2. Compare via multiset operations:
21
+ * - tags only in candidate → added
22
+ * - tags only in baseline → removed
23
+ * - same tag pairs that differ in attributes → attributeChanges
24
+ *
25
+ * Tradeoffs:
26
+ * - We treat element ORDER as soft. Two pages with the same elements in
27
+ * a different order register as zero diff in tag counts but may show up
28
+ * as attribute changes if reordering changes attributes (uncommon).
29
+ * This is acceptable because the SAME page captured twice should
30
+ * normally produce identical token lists.
31
+ * - Text content is ignored. Visual regression on text wording is what
32
+ * pixels are for — we don't want to flag every dynamic timestamp.
33
+ * - Comments and processing instructions are ignored.
34
+ *
35
+ * Self-closing void elements per HTML spec are handled.
36
+ */
37
+ /** Result of a DOM diff comparison. */
38
+ export interface DomDiffResult {
39
+ /** True if the two HTML strings are structurally different. */
40
+ domChanged: boolean;
41
+ /** Per-bucket counts; null when domChanged is false. */
42
+ summary: DomDiffSummary | null;
43
+ }
44
+ export interface DomDiffSummary {
45
+ /** Tag occurrences present in candidate but not baseline. */
46
+ added: number;
47
+ /** Tag occurrences present in baseline but not candidate. */
48
+ removed: number;
49
+ /** Tag pairs present in both but with different attributes. */
50
+ attributeChanges: number;
51
+ }
52
+ interface OpenEvent {
53
+ tag: string;
54
+ /** Attributes serialized as `key=value` pairs, sorted, joined by '\0'. */
55
+ attrSig: string;
56
+ }
57
+ /**
58
+ * Compare two HTML strings.
59
+ *
60
+ * Returns `{ domChanged: false, summary: null }` for fast paths:
61
+ * - Both inputs identical bytes
62
+ * - Both inputs missing/empty (e.g., DOM capture wasn't enabled)
63
+ *
64
+ * Otherwise tokenizes both and produces a summary.
65
+ */
66
+ export declare function domDiff(baselineHtml: string | null | undefined, candidateHtml: string | null | undefined): DomDiffResult;
67
+ /**
68
+ * Stream-tokenize HTML into open events.
69
+ *
70
+ * Skips: doctype, comments, processing instructions, CDATA, text nodes,
71
+ * script/style content (handled as opaque). Close tags are dropped.
72
+ *
73
+ * Robust against malformed HTML — we never throw; on weird input we
74
+ * just stop emitting events. Worst case = false "no DOM signal".
75
+ */
76
+ declare function tokenize(html: string): OpenEvent[];
77
+ /**
78
+ * Internal export only used in tests; exposes the tokenizer for white-box
79
+ * verification. Not part of the package public API.
80
+ */
81
+ export declare const __internals__: {
82
+ tokenize: typeof tokenize;
83
+ };
84
+ export {};
85
+ //# sourceMappingURL=dom-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-diff.d.ts","sourceRoot":"","sources":["../../src/diff/dom-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAOH,uCAAuC;AACvC,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,UAAU,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,CAyDxH;AAuBD;;;;;;;;GAQG;AACH,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAwE3C;AAsFD;;;GAGG;AACH,eAAO,MAAM,aAAa;;CAAe,CAAC"}
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ /**
3
+ * TestivAI DOM Diff — lightweight noise-hint comparison
4
+ *
5
+ * Compares two HTML strings (typically `document.documentElement.outerHTML`
6
+ * captured at snapshot time) and returns a small structural-change summary.
7
+ *
8
+ * This is intentionally NOT a full DOM tree differ — those bring 30 KB+ of
9
+ * dependencies and complex semantics we don't need. The job here is to
10
+ * answer one question per snapshot:
11
+ *
12
+ * "When pixels differ, is the underlying DOM also different?"
13
+ *
14
+ * If pixels differ but DOM is unchanged, the difference is almost certainly
15
+ * render noise (font rendering, anti-aliasing, sub-pixel layout). The HTML
16
+ * report uses this as a noise hint.
17
+ *
18
+ * Approach (zero-dep, ~120 LOC of tokenizer):
19
+ * 1. Stream-tokenize each HTML into a flat list of open events
20
+ * (`{ tag, attrs: Record<string, string> }`).
21
+ * 2. Compare via multiset operations:
22
+ * - tags only in candidate → added
23
+ * - tags only in baseline → removed
24
+ * - same tag pairs that differ in attributes → attributeChanges
25
+ *
26
+ * Tradeoffs:
27
+ * - We treat element ORDER as soft. Two pages with the same elements in
28
+ * a different order register as zero diff in tag counts but may show up
29
+ * as attribute changes if reordering changes attributes (uncommon).
30
+ * This is acceptable because the SAME page captured twice should
31
+ * normally produce identical token lists.
32
+ * - Text content is ignored. Visual regression on text wording is what
33
+ * pixels are for — we don't want to flag every dynamic timestamp.
34
+ * - Comments and processing instructions are ignored.
35
+ *
36
+ * Self-closing void elements per HTML spec are handled.
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.__internals__ = void 0;
40
+ exports.domDiff = domDiff;
41
+ const VOID_ELEMENTS = new Set([
42
+ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
43
+ 'link', 'meta', 'param', 'source', 'track', 'wbr',
44
+ ]);
45
+ /**
46
+ * Compare two HTML strings.
47
+ *
48
+ * Returns `{ domChanged: false, summary: null }` for fast paths:
49
+ * - Both inputs identical bytes
50
+ * - Both inputs missing/empty (e.g., DOM capture wasn't enabled)
51
+ *
52
+ * Otherwise tokenizes both and produces a summary.
53
+ */
54
+ function domDiff(baselineHtml, candidateHtml) {
55
+ // Fast path: missing data on either side → no signal
56
+ if (!baselineHtml || !candidateHtml) {
57
+ return { domChanged: false, summary: null };
58
+ }
59
+ // Fast path: byte-identical
60
+ if (baselineHtml === candidateHtml) {
61
+ return { domChanged: false, summary: null };
62
+ }
63
+ const baselineEvents = tokenize(baselineHtml);
64
+ const candidateEvents = tokenize(candidateHtml);
65
+ // Bucket by tag name; within each bucket, count attrSig multisets
66
+ const baselineBuckets = bucketize(baselineEvents);
67
+ const candidateBuckets = bucketize(candidateEvents);
68
+ let added = 0;
69
+ let removed = 0;
70
+ let attributeChanges = 0;
71
+ const allTags = new Set([...baselineBuckets.keys(), ...candidateBuckets.keys()]);
72
+ for (const tag of allTags) {
73
+ const baselineForTag = baselineBuckets.get(tag) ?? new Map();
74
+ const candidateForTag = candidateBuckets.get(tag) ?? new Map();
75
+ const baselineCount = sumValues(baselineForTag);
76
+ const candidateCount = sumValues(candidateForTag);
77
+ if (candidateCount > baselineCount) {
78
+ added += candidateCount - baselineCount;
79
+ }
80
+ else if (baselineCount > candidateCount) {
81
+ removed += baselineCount - candidateCount;
82
+ }
83
+ // Attribute changes = matching tag pairs whose attrSig differs.
84
+ // We compute by intersecting the two attrSig multisets and counting
85
+ // anything that doesn't match. Each unmatched-but-paired pair counts
86
+ // once toward attributeChanges; raw added/removed of the tag itself
87
+ // is already counted above, so we subtract that delta.
88
+ const overlap = Math.min(baselineCount, candidateCount);
89
+ let matchingPairs = 0;
90
+ for (const [sig, candCount] of candidateForTag) {
91
+ const baseCount = baselineForTag.get(sig) ?? 0;
92
+ matchingPairs += Math.min(baseCount, candCount);
93
+ }
94
+ attributeChanges += overlap - matchingPairs;
95
+ }
96
+ const domChanged = added > 0 || removed > 0 || attributeChanges > 0;
97
+ return {
98
+ domChanged,
99
+ summary: domChanged ? { added, removed, attributeChanges } : null,
100
+ };
101
+ }
102
+ // ── internals ──────────────────────────────────────────────────────────────
103
+ function bucketize(events) {
104
+ const buckets = new Map();
105
+ for (const ev of events) {
106
+ let inner = buckets.get(ev.tag);
107
+ if (!inner) {
108
+ inner = new Map();
109
+ buckets.set(ev.tag, inner);
110
+ }
111
+ inner.set(ev.attrSig, (inner.get(ev.attrSig) ?? 0) + 1);
112
+ }
113
+ return buckets;
114
+ }
115
+ function sumValues(m) {
116
+ let total = 0;
117
+ for (const v of m.values())
118
+ total += v;
119
+ return total;
120
+ }
121
+ /**
122
+ * Stream-tokenize HTML into open events.
123
+ *
124
+ * Skips: doctype, comments, processing instructions, CDATA, text nodes,
125
+ * script/style content (handled as opaque). Close tags are dropped.
126
+ *
127
+ * Robust against malformed HTML — we never throw; on weird input we
128
+ * just stop emitting events. Worst case = false "no DOM signal".
129
+ */
130
+ function tokenize(html) {
131
+ const events = [];
132
+ const len = html.length;
133
+ let i = 0;
134
+ while (i < len) {
135
+ // Find next '<'
136
+ const lt = html.indexOf('<', i);
137
+ if (lt < 0)
138
+ break;
139
+ i = lt + 1;
140
+ if (i >= len)
141
+ break;
142
+ const c = html[i];
143
+ // Comment <!-- ... -->
144
+ if (c === '!' && html.startsWith('!--', i)) {
145
+ const end = html.indexOf('-->', i + 3);
146
+ if (end < 0)
147
+ break;
148
+ i = end + 3;
149
+ continue;
150
+ }
151
+ // Doctype <!doctype ...>
152
+ if (c === '!') {
153
+ const end = html.indexOf('>', i + 1);
154
+ if (end < 0)
155
+ break;
156
+ i = end + 1;
157
+ continue;
158
+ }
159
+ // CDATA <![CDATA[ ... ]]> (rare in HTML; skip)
160
+ // Already handled by the c === '!' branch above.
161
+ // Processing instruction <? ... ?>
162
+ if (c === '?') {
163
+ const end = html.indexOf('?>', i + 1);
164
+ if (end < 0)
165
+ break;
166
+ i = end + 2;
167
+ continue;
168
+ }
169
+ // Close tag </tagname>
170
+ if (c === '/') {
171
+ const end = html.indexOf('>', i + 1);
172
+ if (end < 0)
173
+ break;
174
+ i = end + 1;
175
+ continue;
176
+ }
177
+ // Open tag <tagname ...>
178
+ const tagEnd = findTagEnd(html, i);
179
+ if (tagEnd < 0)
180
+ break;
181
+ const raw = html.slice(i, tagEnd);
182
+ const ev = parseOpenTag(raw);
183
+ if (ev) {
184
+ events.push(ev);
185
+ // For script/style, skip body opaquely until matching close
186
+ if (ev.tag === 'script' || ev.tag === 'style') {
187
+ const closeNeedle = `</${ev.tag}`;
188
+ const closeIdx = indexOfCaseInsensitive(html, closeNeedle, tagEnd + 1);
189
+ if (closeIdx < 0)
190
+ break;
191
+ const gtAfter = html.indexOf('>', closeIdx);
192
+ i = gtAfter < 0 ? len : gtAfter + 1;
193
+ continue;
194
+ }
195
+ }
196
+ i = tagEnd + 1;
197
+ }
198
+ return events;
199
+ }
200
+ /**
201
+ * Find the index of '>' that closes the open tag starting at `start`,
202
+ * handling quoted attribute values which may contain '>'.
203
+ */
204
+ function findTagEnd(html, start) {
205
+ let i = start;
206
+ let inQuote = null;
207
+ const len = html.length;
208
+ while (i < len) {
209
+ const c = html[i];
210
+ if (inQuote) {
211
+ if (c === inQuote)
212
+ inQuote = null;
213
+ }
214
+ else {
215
+ if (c === '"' || c === "'")
216
+ inQuote = c;
217
+ else if (c === '>')
218
+ return i;
219
+ }
220
+ i++;
221
+ }
222
+ return -1;
223
+ }
224
+ /**
225
+ * Parse the raw inside of a `<...>` (excluding the angle brackets) into
226
+ * an OpenEvent. Returns null for the empty / malformed case.
227
+ */
228
+ function parseOpenTag(raw) {
229
+ // Strip trailing '/' for self-closing forms <br/>
230
+ const trimmed = raw.trim().replace(/\/$/, '').trim();
231
+ if (!trimmed)
232
+ return null;
233
+ // First whitespace-or-end → tag name
234
+ const m = /^([a-zA-Z][a-zA-Z0-9-]*)/.exec(trimmed);
235
+ if (!m)
236
+ return null;
237
+ const tag = m[1].toLowerCase();
238
+ let rest = trimmed.slice(m[0].length).trim();
239
+ const attrs = {};
240
+ while (rest.length > 0) {
241
+ const am = /^([a-zA-Z_:][a-zA-Z0-9_:.-]*)/.exec(rest);
242
+ if (!am)
243
+ break;
244
+ const name = am[1].toLowerCase();
245
+ rest = rest.slice(am[0].length);
246
+ let value = '';
247
+ if (rest.startsWith('=')) {
248
+ rest = rest.slice(1).trimStart();
249
+ if (rest.startsWith('"') || rest.startsWith("'")) {
250
+ const quote = rest[0];
251
+ const end = rest.indexOf(quote, 1);
252
+ if (end < 0)
253
+ break;
254
+ value = rest.slice(1, end);
255
+ rest = rest.slice(end + 1);
256
+ }
257
+ else {
258
+ const ws = rest.search(/\s/);
259
+ if (ws < 0) {
260
+ value = rest;
261
+ rest = '';
262
+ }
263
+ else {
264
+ value = rest.slice(0, ws);
265
+ rest = rest.slice(ws);
266
+ }
267
+ }
268
+ }
269
+ attrs[name] = value;
270
+ rest = rest.trimStart();
271
+ }
272
+ // Build a stable, sorted attribute signature.
273
+ // Some attributes are inherently dynamic (id like 'react-aria-:r1:'); we
274
+ // don't try to be smart about that here — the signature is stable across
275
+ // identical pages but flags any attr-value drift.
276
+ const keys = Object.keys(attrs).sort();
277
+ const attrSig = keys.map((k) => `${k}=${attrs[k]}`).join('\0');
278
+ return { tag, attrSig };
279
+ }
280
+ function indexOfCaseInsensitive(haystack, needle, fromIndex) {
281
+ // Cheap case-insensitive search; needle is short ('</script' or '</style')
282
+ const h = haystack.toLowerCase();
283
+ const n = needle.toLowerCase();
284
+ return h.indexOf(n, fromIndex);
285
+ }
286
+ /**
287
+ * Internal export only used in tests; exposes the tokenizer for white-box
288
+ * verification. Not part of the package public API.
289
+ */
290
+ exports.__internals__ = { tokenize };
291
+ //# sourceMappingURL=dom-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-diff.js","sourceRoot":"","sources":["../../src/diff/dom-diff.ts"],"names":[],"mappings":"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"}
@@ -12,5 +12,7 @@ export { applyIgnoreRegions } from './ignore';
12
12
  export { applyMinimap } from './minimap';
13
13
  export { normalizeDimensions } from './resize';
14
14
  export { detectRegions } from './regions';
15
+ export { domDiff } from './dom-diff';
15
16
  export type { DiffOptions, DiffResult, DiffRegion, IgnoreRegion, SizeMismatch, PbdRawResult, } from './types';
17
+ export type { DomDiffResult, DomDiffSummary } from './dom-diff';
16
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -9,7 +9,7 @@
9
9
  * @see https://github.com/p01/pixel-buffer-diff
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.detectRegions = exports.normalizeDimensions = exports.applyMinimap = exports.applyIgnoreRegions = exports.diff = void 0;
12
+ exports.domDiff = exports.detectRegions = exports.normalizeDimensions = exports.applyMinimap = exports.applyIgnoreRegions = exports.diff = void 0;
13
13
  var diff_1 = require("./diff");
14
14
  Object.defineProperty(exports, "diff", { enumerable: true, get: function () { return diff_1.diff; } });
15
15
  var ignore_1 = require("./ignore");
@@ -20,4 +20,6 @@ var resize_1 = require("./resize");
20
20
  Object.defineProperty(exports, "normalizeDimensions", { enumerable: true, get: function () { return resize_1.normalizeDimensions; } });
21
21
  var regions_1 = require("./regions");
22
22
  Object.defineProperty(exports, "detectRegions", { enumerable: true, get: function () { return regions_1.detectRegions; } });
23
+ var dom_diff_1 = require("./dom-diff");
24
+ Object.defineProperty(exports, "domDiff", { enumerable: true, get: function () { return dom_diff_1.domDiff; } });
23
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/diff/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAC3B,qCAAyC;AAAhC,uGAAA,YAAY,OAAA;AACrB,mCAA+C;AAAtC,6GAAA,mBAAmB,OAAA;AAC5B,qCAA0C;AAAjC,wGAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/diff/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAC3B,qCAAyC;AAAhC,uGAAA,YAAY,OAAA;AACrB,mCAA+C;AAAtC,6GAAA,mBAAmB,OAAA;AAC5B,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AACtB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,cAAc,EAAkB,MAAM,WAAW,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,EAAE,CAuDpE"}
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAAqB,cAAc,EAAkB,MAAM,WAAW,CAAC;AAE9E,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,EAAE,CAmEpE"}
@@ -42,6 +42,7 @@ exports.compareAll = compareAll;
42
42
  const fs = __importStar(require("fs"));
43
43
  const path = __importStar(require("path"));
44
44
  const diff_1 = require("../diff");
45
+ const dom_diff_1 = require("../diff/dom-diff");
45
46
  const store_1 = require("../baselines/store");
46
47
  /**
47
48
  * Compare all temp screenshots against their baselines.
@@ -86,10 +87,39 @@ function compareAll(options) {
86
87
  // For simplicity and zero-dep, we do a byte-level comparison first,
87
88
  // then fall back to diff engine for actual pixel data.
88
89
  const result = compareBuffers(baselineBuffer, tempBuffer, name, snapshotImagesDir, threshold);
90
+ // DOM-level noise hint. Only meaningful when both sides captured DOM.
91
+ // For 'passed' (pixel-identical) we skip the work — it's already the
92
+ // strongest possible signal.
93
+ if (result.status === 'changed') {
94
+ const baselineDom = store.readDom(name);
95
+ const candidateDom = store.readTempDom(name);
96
+ const domSignal = computeDomSignal(baselineDom, candidateDom);
97
+ if (domSignal) {
98
+ result.dom = domSignal;
99
+ }
100
+ }
89
101
  results.push(result);
90
102
  }
91
103
  return results;
92
104
  }
105
+ /**
106
+ * Run DOM diff and turn it into a report-shaped signal.
107
+ *
108
+ * Returns null when DOM data isn't available on either side — we don't
109
+ * want to confuse the user with "DOM unchanged" hints when the adapter
110
+ * never captured DOM in the first place.
111
+ */
112
+ function computeDomSignal(baselineDom, candidateDom) {
113
+ if (!baselineDom || !candidateDom)
114
+ return null;
115
+ const result = (0, dom_diff_1.domDiff)(baselineDom, candidateDom);
116
+ return {
117
+ changed: result.domChanged,
118
+ summary: result.summary,
119
+ // The whole point: pixels differ, DOM does not → likely render noise.
120
+ noiseHint: !result.domChanged,
121
+ };
122
+ }
93
123
  /**
94
124
  * Compare two PNG buffers.
95
125
  *
@@ -1 +1 @@
1
- {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"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"}
@@ -6,5 +6,5 @@ export type { GenerateReportOptions } from './generator';
6
6
  export { compareAll } from './compare';
7
7
  export type { CompareOptions } from './compare';
8
8
  export { renderHtml } from './template';
9
- export type { ReportData, ReportSummary, SnapshotResult, SnapshotStatus, } from './results';
9
+ export type { ReportData, ReportSummary, SnapshotResult, SnapshotStatus, SnapshotDomSignal, } from './results';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,UAAU,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,WAAW,CAAC"}
@@ -4,6 +4,22 @@
4
4
  * Machine-readable output for the GitHub Action and other consumers.
5
5
  */
6
6
  export type SnapshotStatus = 'passed' | 'changed' | 'new';
7
+ export interface SnapshotDomSignal {
8
+ /** True if the DOM differs structurally between baseline and candidate. */
9
+ changed: boolean;
10
+ /** Per-bucket counts; null when changed is false. */
11
+ summary: {
12
+ added: number;
13
+ removed: number;
14
+ attributeChanges: number;
15
+ } | null;
16
+ /**
17
+ * Noise hint: pixel diff is non-zero but DOM is structurally unchanged.
18
+ * Suggests render noise (anti-aliasing, font hinting, sub-pixel layout)
19
+ * rather than a real visual regression.
20
+ */
21
+ noiseHint: boolean;
22
+ }
7
23
  export interface SnapshotResult {
8
24
  name: string;
9
25
  status: SnapshotStatus;
@@ -19,6 +35,11 @@ export interface SnapshotResult {
19
35
  currentPath?: string;
20
36
  /** Relative path to diff image (if any) */
21
37
  diffPath?: string;
38
+ /**
39
+ * DOM-level signal. Present only when both baseline and candidate
40
+ * captured DOM HTML alongside the screenshot.
41
+ */
42
+ dom?: SnapshotDomSignal;
22
43
  }
23
44
  export interface ReportSummary {
24
45
  total: number;
@@ -1 +1 @@
1
- {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../src/report/results.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B"}
1
+ {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../src/report/results.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,GAAG,CAAC,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/report/template.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAC;AAEvD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgLnD"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/report/template.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAC;AAEvD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAuLnD"}
@@ -74,6 +74,13 @@ function renderHtml(data) {
74
74
  .badge-passed { background: #3fb95022; color: #3fb950; }
75
75
  .snapshot-stats { font-size: 12px; color: #8b949e; margin-bottom: 16px; }
76
76
 
77
+ /* DOM noise hint */
78
+ .dom-hint { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding: 10px 12px; border-radius: 8px; font-size: 12px; line-height: 1.5; }
79
+ .dom-hint.noise { background: #1f6feb1a; border: 1px solid #1f6feb44; color: #79c0ff; }
80
+ .dom-hint.changed { background: #6e768166; border: 1px solid #8b949e44; color: #c9d1d9; }
81
+ .dom-hint .label { font-weight: 600; }
82
+ .dom-hint .summary { color: inherit; opacity: 0.85; }
83
+
77
84
  /* 3-column diff view */
78
85
  .diff-view { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; }
79
86
  .diff-view.two-col { grid-template-columns: 1fr 1fr; }
@@ -206,6 +213,7 @@ function renderSnapshot(snapshot) {
206
213
  <span class="snapshot-badge ${badgeClass}">${snapshot.status}</span>
207
214
  </div>
208
215
  ${snapshot.status === 'changed' ? `<div class="snapshot-stats">Diff: ${snapshot.diffPercent.toFixed(2)}% (${snapshot.diffCount} pixels)</div>` : ''}
216
+ ${renderDomHint(snapshot)}
209
217
  <div class="${gridClass}">
210
218
  ${hasBaseline ? `<div class="diff-col"><label>Baseline</label><img src="${snapshot.baselinePath}" alt="Baseline"></div>` : ''}
211
219
  ${hasDiff ? `<div class="diff-col"><label>Diff</label><img src="${snapshot.diffPath}" alt="Diff"></div>` : ''}
@@ -218,6 +226,44 @@ function renderSnapshot(snapshot) {
218
226
  </div>` : ''}
219
227
  </div>`;
220
228
  }
229
+ /**
230
+ * Render the DOM noise-hint badge for a snapshot.
231
+ *
232
+ * Two states (DOM hint is only meaningful for `changed` snapshots that
233
+ * have DOM data captured on both sides):
234
+ * - noiseHint: pixels differ but DOM is unchanged → "likely render noise"
235
+ * - changed: pixels and DOM both differ → show counts so the reviewer
236
+ * can decide whether the change is intentional
237
+ *
238
+ * Returns empty string when no DOM data was captured (the adapter didn't
239
+ * record `dom.html`); we don't want to confuse the user with "no signal".
240
+ */
241
+ function renderDomHint(snapshot) {
242
+ if (!snapshot.dom)
243
+ return '';
244
+ if (snapshot.dom.noiseHint) {
245
+ return `
246
+ <div class="dom-hint noise" title="DOM tree is identical between baseline and candidate; the pixel diff is likely render noise.">
247
+ <span class="label">DOM unchanged</span>
248
+ <span class="summary">— pixel diff is likely render noise (anti-aliasing, font hinting).</span>
249
+ </div>`;
250
+ }
251
+ const s = snapshot.dom.summary;
252
+ if (!s)
253
+ return '';
254
+ const parts = [];
255
+ if (s.added > 0)
256
+ parts.push(`${s.added} added`);
257
+ if (s.removed > 0)
258
+ parts.push(`${s.removed} removed`);
259
+ if (s.attributeChanges > 0)
260
+ parts.push(`${s.attributeChanges} attribute change${s.attributeChanges === 1 ? '' : 's'}`);
261
+ return `
262
+ <div class="dom-hint changed" title="Structural DOM changes detected alongside the pixel diff.">
263
+ <span class="label">DOM changed</span>
264
+ <span class="summary">— ${escapeHtml(parts.join(', ') || 'structural difference')}.</span>
265
+ </div>`;
266
+ }
221
267
  function escapeHtml(str) {
222
268
  return str
223
269
  .replace(/&/g, '&amp;')
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/report/template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/report/template.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testivai/witness",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Framework-agnostic visual regression testing CLI for TestivAI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",