@testivai/witness 1.0.1 → 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.
- package/README.md +44 -13
- package/dist/baselines/index.d.ts +6 -0
- package/dist/baselines/index.d.ts.map +1 -0
- package/dist/baselines/index.js +9 -0
- package/dist/baselines/index.js.map +1 -0
- package/dist/baselines/store.d.ts +100 -0
- package/dist/baselines/store.d.ts.map +1 -0
- package/dist/baselines/store.js +298 -0
- package/dist/baselines/store.js.map +1 -0
- package/dist/bin/testivai.js +2 -0
- package/dist/bin/testivai.js.map +1 -1
- package/dist/browser/binding.d.ts.map +1 -1
- package/dist/browser/binding.js +173 -42
- package/dist/browser/binding.js.map +1 -1
- package/dist/browser/capture.d.ts.map +1 -1
- package/dist/browser/capture.js +7 -4
- package/dist/browser/capture.js.map +1 -1
- package/dist/commands/approve.d.ts +3 -0
- package/dist/commands/approve.d.ts.map +1 -0
- package/dist/commands/approve.js +94 -0
- package/dist/commands/approve.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +53 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +98 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +14 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/local-config.d.ts +54 -0
- package/dist/config/local-config.d.ts.map +1 -0
- package/dist/config/local-config.js +130 -0
- package/dist/config/local-config.js.map +1 -0
- package/dist/diff/diff.d.ts +27 -0
- package/dist/diff/diff.d.ts.map +1 -0
- package/dist/diff/diff.js +216 -0
- package/dist/diff/diff.js.map +1 -0
- package/dist/diff/dom-diff.d.ts +85 -0
- package/dist/diff/dom-diff.d.ts.map +1 -0
- package/dist/diff/dom-diff.js +291 -0
- package/dist/diff/dom-diff.js.map +1 -0
- package/dist/diff/ignore.d.ts +22 -0
- package/dist/diff/ignore.d.ts.map +1 -0
- package/dist/diff/ignore.js +43 -0
- package/dist/diff/ignore.js.map +1 -0
- package/dist/diff/index.d.ts +18 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +25 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/minimap.d.ts +23 -0
- package/dist/diff/minimap.d.ts.map +1 -0
- package/dist/diff/minimap.js +43 -0
- package/dist/diff/minimap.js.map +1 -0
- package/dist/diff/regions.d.ts +23 -0
- package/dist/diff/regions.d.ts.map +1 -0
- package/dist/diff/regions.js +129 -0
- package/dist/diff/regions.js.map +1 -0
- package/dist/diff/resize.d.ts +27 -0
- package/dist/diff/resize.d.ts.map +1 -0
- package/dist/diff/resize.js +82 -0
- package/dist/diff/resize.js.map +1 -0
- package/dist/diff/types.d.ts +79 -0
- package/dist/diff/types.d.ts.map +1 -0
- package/dist/diff/types.js +10 -0
- package/dist/diff/types.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -1
- package/dist/report/compare.d.ts +18 -0
- package/dist/report/compare.d.ts.map +1 -0
- package/dist/report/compare.js +193 -0
- package/dist/report/compare.js.map +1 -0
- package/dist/report/generator.d.ts +31 -0
- package/dist/report/generator.d.ts.map +1 -0
- package/dist/report/generator.js +123 -0
- package/dist/report/generator.js.map +1 -0
- package/dist/report/index.d.ts +10 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +13 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/results.d.ts +56 -0
- package/dist/report/results.d.ts.map +1 -0
- package/dist/report/results.js +8 -0
- package/dist/report/results.js.map +1 -0
- package/dist/report/template.d.ts +14 -0
- package/dist/report/template.d.ts.map +1 -0
- package/dist/report/template.js +275 -0
- package/dist/report/template.js.map +1 -0
- package/package.json +58 -15
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TestivAI Diff Engine — Ignore regions
|
|
4
|
+
*
|
|
5
|
+
* Before the diff loop runs, copy candidate pixel values into the
|
|
6
|
+
* baseline buffer for ignored regions. This makes ignored areas
|
|
7
|
+
* appear identical to the differ.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.applyIgnoreRegions = applyIgnoreRegions;
|
|
11
|
+
/**
|
|
12
|
+
* Mask ignored regions by copying candidate pixels into baseline.
|
|
13
|
+
* After this, the diff loop will see no difference in those areas.
|
|
14
|
+
*
|
|
15
|
+
* Mutates `baseline` in place.
|
|
16
|
+
*
|
|
17
|
+
* @param baseline - Baseline pixel buffer (will be mutated)
|
|
18
|
+
* @param candidate - Candidate pixel buffer
|
|
19
|
+
* @param width - Image width
|
|
20
|
+
* @param height - Image height
|
|
21
|
+
* @param regions - Regions to ignore
|
|
22
|
+
*/
|
|
23
|
+
function applyIgnoreRegions(baseline, candidate, width, height, regions) {
|
|
24
|
+
for (const region of regions) {
|
|
25
|
+
// Clamp to image bounds
|
|
26
|
+
const x0 = Math.max(0, Math.min(region.x, width));
|
|
27
|
+
const y0 = Math.max(0, Math.min(region.y, height));
|
|
28
|
+
const x1 = Math.max(0, Math.min(region.x + region.width, width));
|
|
29
|
+
const y1 = Math.max(0, Math.min(region.y + region.height, height));
|
|
30
|
+
for (let y = y0; y < y1; y++) {
|
|
31
|
+
const rowOffset = y * width * 4;
|
|
32
|
+
for (let x = x0; x < x1; x++) {
|
|
33
|
+
const pixelOffset = rowOffset + x * 4;
|
|
34
|
+
// Copy RGBA from candidate to baseline
|
|
35
|
+
baseline[pixelOffset] = candidate[pixelOffset];
|
|
36
|
+
baseline[pixelOffset + 1] = candidate[pixelOffset + 1];
|
|
37
|
+
baseline[pixelOffset + 2] = candidate[pixelOffset + 2];
|
|
38
|
+
baseline[pixelOffset + 3] = candidate[pixelOffset + 3];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore.js","sourceRoot":"","sources":["../../src/diff/ignore.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAgBH,gDA0BC;AAtCD;;;;;;;;;;;GAWG;AACH,SAAgB,kBAAkB,CAChC,QAAwC,EACxC,SAAyC,EACzC,KAAa,EACb,MAAc,EACd,OAAuB;IAEvB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,wBAAwB;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACjE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAEnE,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YAChC,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;gBACtC,uCAAuC;gBACvC,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;gBAC/C,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;gBACvD,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;gBACvD,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestivAI Diff Engine
|
|
3
|
+
*
|
|
4
|
+
* Pixel-level visual comparison engine forked from pixel-buffer-diff (Pbd)
|
|
5
|
+
* by @p01 (MIT license). Extended with ignore regions, size mismatch
|
|
6
|
+
* handling, region detection, and TypeScript support.
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/p01/pixel-buffer-diff
|
|
9
|
+
*/
|
|
10
|
+
export { diff } from './diff';
|
|
11
|
+
export { applyIgnoreRegions } from './ignore';
|
|
12
|
+
export { applyMinimap } from './minimap';
|
|
13
|
+
export { normalizeDimensions } from './resize';
|
|
14
|
+
export { detectRegions } from './regions';
|
|
15
|
+
export { domDiff } from './dom-diff';
|
|
16
|
+
export type { DiffOptions, DiffResult, DiffRegion, IgnoreRegion, SizeMismatch, PbdRawResult, } from './types';
|
|
17
|
+
export type { DomDiffResult, DomDiffSummary } from './dom-diff';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TestivAI Diff Engine
|
|
4
|
+
*
|
|
5
|
+
* Pixel-level visual comparison engine forked from pixel-buffer-diff (Pbd)
|
|
6
|
+
* by @p01 (MIT license). Extended with ignore regions, size mismatch
|
|
7
|
+
* handling, region detection, and TypeScript support.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/p01/pixel-buffer-diff
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.domDiff = exports.detectRegions = exports.normalizeDimensions = exports.applyMinimap = exports.applyIgnoreRegions = exports.diff = void 0;
|
|
13
|
+
var diff_1 = require("./diff");
|
|
14
|
+
Object.defineProperty(exports, "diff", { enumerable: true, get: function () { return diff_1.diff; } });
|
|
15
|
+
var ignore_1 = require("./ignore");
|
|
16
|
+
Object.defineProperty(exports, "applyIgnoreRegions", { enumerable: true, get: function () { return ignore_1.applyIgnoreRegions; } });
|
|
17
|
+
var minimap_1 = require("./minimap");
|
|
18
|
+
Object.defineProperty(exports, "applyMinimap", { enumerable: true, get: function () { return minimap_1.applyMinimap; } });
|
|
19
|
+
var resize_1 = require("./resize");
|
|
20
|
+
Object.defineProperty(exports, "normalizeDimensions", { enumerable: true, get: function () { return resize_1.normalizeDimensions; } });
|
|
21
|
+
var regions_1 = require("./regions");
|
|
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; } });
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;AACtB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestivAI Diff Engine — Minimap overlay
|
|
3
|
+
*
|
|
4
|
+
* Applies a low-resolution overlay on the diff buffer to help
|
|
5
|
+
* spot isolated pixel changes at a glance.
|
|
6
|
+
*
|
|
7
|
+
* Ported from pixel-buffer-diff by @p01, licensed under MIT.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Apply minimap overlay to the diff buffer.
|
|
11
|
+
* Regions with any changed pixels get a colored tint.
|
|
12
|
+
*
|
|
13
|
+
* @param diff32 - Diff image as Uint32Array
|
|
14
|
+
* @param miniMap - Minimap cell hit counts
|
|
15
|
+
* @param miniWidth - Number of minimap columns
|
|
16
|
+
* @param miniHeight - Number of minimap rows
|
|
17
|
+
* @param width - Full image width
|
|
18
|
+
* @param height - Full image height
|
|
19
|
+
* @param scale - Pixels per minimap cell (e.g. 128)
|
|
20
|
+
* @param color - 32-bit ABGR color to OR into diff pixels
|
|
21
|
+
*/
|
|
22
|
+
export declare function applyMinimap(diff32: Uint32Array, miniMap: Uint8ClampedArray, miniWidth: number, miniHeight: number, width: number, height: number, scale: number, color: number): void;
|
|
23
|
+
//# sourceMappingURL=minimap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimap.d.ts","sourceRoot":"","sources":["../../src/diff/minimap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,IAAI,CAkBN"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TestivAI Diff Engine — Minimap overlay
|
|
4
|
+
*
|
|
5
|
+
* Applies a low-resolution overlay on the diff buffer to help
|
|
6
|
+
* spot isolated pixel changes at a glance.
|
|
7
|
+
*
|
|
8
|
+
* Ported from pixel-buffer-diff by @p01, licensed under MIT.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.applyMinimap = applyMinimap;
|
|
12
|
+
/**
|
|
13
|
+
* Apply minimap overlay to the diff buffer.
|
|
14
|
+
* Regions with any changed pixels get a colored tint.
|
|
15
|
+
*
|
|
16
|
+
* @param diff32 - Diff image as Uint32Array
|
|
17
|
+
* @param miniMap - Minimap cell hit counts
|
|
18
|
+
* @param miniWidth - Number of minimap columns
|
|
19
|
+
* @param miniHeight - Number of minimap rows
|
|
20
|
+
* @param width - Full image width
|
|
21
|
+
* @param height - Full image height
|
|
22
|
+
* @param scale - Pixels per minimap cell (e.g. 128)
|
|
23
|
+
* @param color - 32-bit ABGR color to OR into diff pixels
|
|
24
|
+
*/
|
|
25
|
+
function applyMinimap(diff32, miniMap, miniWidth, miniHeight, width, height, scale, color) {
|
|
26
|
+
for (let i = 0; i < miniWidth * miniHeight; i++) {
|
|
27
|
+
if (miniMap[i] > 0) {
|
|
28
|
+
const miniX = i % miniWidth;
|
|
29
|
+
const miniY = (i / miniWidth) | 0;
|
|
30
|
+
const x0 = miniX * scale;
|
|
31
|
+
const x1 = Math.min(x0 + scale, width);
|
|
32
|
+
const y0 = miniY * scale;
|
|
33
|
+
const y1 = Math.min(y0 + scale, height);
|
|
34
|
+
for (let y = y0; y < y1; y++) {
|
|
35
|
+
let d32i = x0 + y * width;
|
|
36
|
+
for (let x = x0; x < x1; x++) {
|
|
37
|
+
diff32[d32i++] |= color;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=minimap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimap.js","sourceRoot":"","sources":["../../src/diff/minimap.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAeH,oCA2BC;AAxCD;;;;;;;;;;;;GAYG;AACH,SAAgB,YAAY,CAC1B,MAAmB,EACnB,OAA0B,EAC1B,SAAiB,EACjB,UAAkB,EAClB,KAAa,EACb,MAAc,EACd,KAAa,EACb,KAAa;IAEb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;YAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,EAAE,GAAG,KAAK,GAAG,KAAK,CAAC;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC;YACvC,MAAM,EAAE,GAAG,KAAK,GAAG,KAAK,CAAC;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC;YAExC,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;gBAC1B,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7B,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestivAI Diff Engine — Region bounding box detection
|
|
3
|
+
*
|
|
4
|
+
* Scans the diff output buffer for non-zero (changed) pixels
|
|
5
|
+
* and groups them into rectangular bounding boxes using a simple
|
|
6
|
+
* connected-component labeling approach.
|
|
7
|
+
*/
|
|
8
|
+
import { DiffRegion } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Detect regions of change in the diff buffer.
|
|
11
|
+
*
|
|
12
|
+
* Scans for non-transparent pixels (any pixel with alpha > 0 in
|
|
13
|
+
* the diff output), groups adjacent changed pixels into rectangular
|
|
14
|
+
* bounding boxes, and filters out regions smaller than minSize.
|
|
15
|
+
*
|
|
16
|
+
* @param diff8 - Diff image pixel buffer (RGBA)
|
|
17
|
+
* @param width - Image width
|
|
18
|
+
* @param height - Image height
|
|
19
|
+
* @param minSize - Minimum pixels to include a region (default: 10)
|
|
20
|
+
* @returns Array of DiffRegion bounding boxes
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectRegions(diff8: Uint8Array | Uint8ClampedArray, width: number, height: number, minSize?: number): DiffRegion[];
|
|
23
|
+
//# sourceMappingURL=regions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regions.d.ts","sourceRoot":"","sources":["../../src/diff/regions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,GAAG,iBAAiB,EACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAAW,GACnB,UAAU,EAAE,CAkHd"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TestivAI Diff Engine — Region bounding box detection
|
|
4
|
+
*
|
|
5
|
+
* Scans the diff output buffer for non-zero (changed) pixels
|
|
6
|
+
* and groups them into rectangular bounding boxes using a simple
|
|
7
|
+
* connected-component labeling approach.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.detectRegions = detectRegions;
|
|
11
|
+
/**
|
|
12
|
+
* Detect regions of change in the diff buffer.
|
|
13
|
+
*
|
|
14
|
+
* Scans for non-transparent pixels (any pixel with alpha > 0 in
|
|
15
|
+
* the diff output), groups adjacent changed pixels into rectangular
|
|
16
|
+
* bounding boxes, and filters out regions smaller than minSize.
|
|
17
|
+
*
|
|
18
|
+
* @param diff8 - Diff image pixel buffer (RGBA)
|
|
19
|
+
* @param width - Image width
|
|
20
|
+
* @param height - Image height
|
|
21
|
+
* @param minSize - Minimum pixels to include a region (default: 10)
|
|
22
|
+
* @returns Array of DiffRegion bounding boxes
|
|
23
|
+
*/
|
|
24
|
+
function detectRegions(diff8, width, height, minSize = 10) {
|
|
25
|
+
// Build a binary grid: 1 = changed pixel, 0 = unchanged
|
|
26
|
+
const changed = new Uint8Array(width * height);
|
|
27
|
+
for (let y = 0; y < height; y++) {
|
|
28
|
+
for (let x = 0; x < width; x++) {
|
|
29
|
+
const idx = (y * width + x) * 4;
|
|
30
|
+
// A pixel is considered "changed" if it has any non-zero alpha
|
|
31
|
+
// in the diff buffer (the diff engine writes colored pixels for changes)
|
|
32
|
+
if (diff8[idx + 3] > 0) {
|
|
33
|
+
changed[y * width + x] = 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Connected-component labeling using union-find
|
|
38
|
+
const labels = new Int32Array(width * height).fill(-1);
|
|
39
|
+
const parent = [];
|
|
40
|
+
let nextLabel = 0;
|
|
41
|
+
function find(x) {
|
|
42
|
+
while (parent[x] !== x) {
|
|
43
|
+
parent[x] = parent[parent[x]]; // path compression
|
|
44
|
+
x = parent[x];
|
|
45
|
+
}
|
|
46
|
+
return x;
|
|
47
|
+
}
|
|
48
|
+
function union(a, b) {
|
|
49
|
+
const ra = find(a);
|
|
50
|
+
const rb = find(b);
|
|
51
|
+
if (ra !== rb) {
|
|
52
|
+
parent[rb] = ra;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// First pass: assign labels
|
|
56
|
+
for (let y = 0; y < height; y++) {
|
|
57
|
+
for (let x = 0; x < width; x++) {
|
|
58
|
+
const idx = y * width + x;
|
|
59
|
+
if (!changed[idx])
|
|
60
|
+
continue;
|
|
61
|
+
const neighbors = [];
|
|
62
|
+
// Check left
|
|
63
|
+
if (x > 0 && labels[idx - 1] >= 0) {
|
|
64
|
+
neighbors.push(labels[idx - 1]);
|
|
65
|
+
}
|
|
66
|
+
// Check above
|
|
67
|
+
if (y > 0 && labels[idx - width] >= 0) {
|
|
68
|
+
neighbors.push(labels[idx - width]);
|
|
69
|
+
}
|
|
70
|
+
if (neighbors.length === 0) {
|
|
71
|
+
// New label
|
|
72
|
+
labels[idx] = nextLabel;
|
|
73
|
+
parent.push(nextLabel);
|
|
74
|
+
nextLabel++;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Use the smallest label
|
|
78
|
+
const minLabel = Math.min(...neighbors.map(find));
|
|
79
|
+
labels[idx] = minLabel;
|
|
80
|
+
// Union all neighbor labels
|
|
81
|
+
for (const n of neighbors) {
|
|
82
|
+
union(minLabel, n);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Second pass: collect bounding boxes per component
|
|
88
|
+
const boxes = new Map();
|
|
89
|
+
for (let y = 0; y < height; y++) {
|
|
90
|
+
for (let x = 0; x < width; x++) {
|
|
91
|
+
const idx = y * width + x;
|
|
92
|
+
if (labels[idx] < 0)
|
|
93
|
+
continue;
|
|
94
|
+
const root = find(labels[idx]);
|
|
95
|
+
const box = boxes.get(root);
|
|
96
|
+
if (box) {
|
|
97
|
+
box.x0 = Math.min(box.x0, x);
|
|
98
|
+
box.y0 = Math.min(box.y0, y);
|
|
99
|
+
box.x1 = Math.max(box.x1, x);
|
|
100
|
+
box.y1 = Math.max(box.y1, y);
|
|
101
|
+
box.count++;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
boxes.set(root, { x0: x, y0: y, x1: x, y1: y, count: 1 });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Convert to DiffRegion array, filtering by minSize
|
|
109
|
+
const regions = [];
|
|
110
|
+
for (const box of boxes.values()) {
|
|
111
|
+
if (box.count < minSize)
|
|
112
|
+
continue;
|
|
113
|
+
const regionWidth = box.x1 - box.x0 + 1;
|
|
114
|
+
const regionHeight = box.y1 - box.y0 + 1;
|
|
115
|
+
const regionArea = regionWidth * regionHeight;
|
|
116
|
+
regions.push({
|
|
117
|
+
x: box.x0,
|
|
118
|
+
y: box.y0,
|
|
119
|
+
width: regionWidth,
|
|
120
|
+
height: regionHeight,
|
|
121
|
+
diffPixels: box.count,
|
|
122
|
+
diffPercent: regionArea > 0 ? (box.count / regionArea) * 100 : 0,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// Sort by position (top-left first)
|
|
126
|
+
regions.sort((a, b) => a.y - b.y || a.x - b.x);
|
|
127
|
+
return regions;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=regions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regions.js","sourceRoot":"","sources":["../../src/diff/regions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestivAI Diff Engine — Size mismatch handling
|
|
3
|
+
*
|
|
4
|
+
* When baseline and candidate have different dimensions,
|
|
5
|
+
* normalize them before diffing.
|
|
6
|
+
*/
|
|
7
|
+
import { SizeMismatch } from './types';
|
|
8
|
+
export interface NormalizeResult {
|
|
9
|
+
normalizedBaseline: Uint8ClampedArray;
|
|
10
|
+
normalizedCandidate: Uint8ClampedArray;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
sizeMismatch: SizeMismatch;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Normalize two pixel buffers to the same dimensions.
|
|
17
|
+
*
|
|
18
|
+
* @param baseline - Baseline pixel buffer (RGBA)
|
|
19
|
+
* @param bw - Baseline width
|
|
20
|
+
* @param bh - Baseline height
|
|
21
|
+
* @param candidate - Candidate pixel buffer (RGBA)
|
|
22
|
+
* @param cw - Candidate width
|
|
23
|
+
* @param ch - Candidate height
|
|
24
|
+
* @param mode - 'pad' (fill with transparent), 'crop' (use min dims), or 'error'
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeDimensions(baseline: Uint8Array | Uint8ClampedArray, bw: number, bh: number, candidate: Uint8Array | Uint8ClampedArray, cw: number, ch: number, mode: 'pad' | 'crop' | 'error'): NormalizeResult;
|
|
27
|
+
//# sourceMappingURL=resize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../src/diff/resize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,mBAAmB,EAAE,iBAAiB,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,UAAU,GAAG,iBAAiB,EACxC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,UAAU,GAAG,iBAAiB,EACzC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAC7B,eAAe,CA0EjB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TestivAI Diff Engine — Size mismatch handling
|
|
4
|
+
*
|
|
5
|
+
* When baseline and candidate have different dimensions,
|
|
6
|
+
* normalize them before diffing.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.normalizeDimensions = normalizeDimensions;
|
|
10
|
+
/**
|
|
11
|
+
* Normalize two pixel buffers to the same dimensions.
|
|
12
|
+
*
|
|
13
|
+
* @param baseline - Baseline pixel buffer (RGBA)
|
|
14
|
+
* @param bw - Baseline width
|
|
15
|
+
* @param bh - Baseline height
|
|
16
|
+
* @param candidate - Candidate pixel buffer (RGBA)
|
|
17
|
+
* @param cw - Candidate width
|
|
18
|
+
* @param ch - Candidate height
|
|
19
|
+
* @param mode - 'pad' (fill with transparent), 'crop' (use min dims), or 'error'
|
|
20
|
+
*/
|
|
21
|
+
function normalizeDimensions(baseline, bw, bh, candidate, cw, ch, mode) {
|
|
22
|
+
if (bw === cw && bh === ch) {
|
|
23
|
+
return {
|
|
24
|
+
normalizedBaseline: new Uint8ClampedArray(baseline),
|
|
25
|
+
normalizedCandidate: new Uint8ClampedArray(candidate),
|
|
26
|
+
width: bw,
|
|
27
|
+
height: bh,
|
|
28
|
+
sizeMismatch: {
|
|
29
|
+
baseline: { width: bw, height: bh },
|
|
30
|
+
candidate: { width: cw, height: ch },
|
|
31
|
+
normalized: { width: bw, height: bh },
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (mode === 'error') {
|
|
36
|
+
throw new Error(`Size mismatch: baseline is ${bw}×${bh}, candidate is ${cw}×${ch}. ` +
|
|
37
|
+
`Set handleSizeMismatch to 'pad' or 'crop' to handle this automatically.`);
|
|
38
|
+
}
|
|
39
|
+
let targetWidth;
|
|
40
|
+
let targetHeight;
|
|
41
|
+
if (mode === 'pad') {
|
|
42
|
+
targetWidth = Math.max(bw, cw);
|
|
43
|
+
targetHeight = Math.max(bh, ch);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// crop
|
|
47
|
+
targetWidth = Math.min(bw, cw);
|
|
48
|
+
targetHeight = Math.min(bh, ch);
|
|
49
|
+
}
|
|
50
|
+
const normalizedBaseline = new Uint8ClampedArray(targetWidth * targetHeight * 4);
|
|
51
|
+
const normalizedCandidate = new Uint8ClampedArray(targetWidth * targetHeight * 4);
|
|
52
|
+
// Copy baseline rows
|
|
53
|
+
const copyWidthB = Math.min(bw, targetWidth);
|
|
54
|
+
const copyHeightB = Math.min(bh, targetHeight);
|
|
55
|
+
for (let y = 0; y < copyHeightB; y++) {
|
|
56
|
+
const srcStart = y * bw * 4;
|
|
57
|
+
const dstStart = y * targetWidth * 4;
|
|
58
|
+
const bytesToCopy = copyWidthB * 4;
|
|
59
|
+
normalizedBaseline.set(baseline.slice(srcStart, srcStart + bytesToCopy), dstStart);
|
|
60
|
+
}
|
|
61
|
+
// Copy candidate rows
|
|
62
|
+
const copyWidthC = Math.min(cw, targetWidth);
|
|
63
|
+
const copyHeightC = Math.min(ch, targetHeight);
|
|
64
|
+
for (let y = 0; y < copyHeightC; y++) {
|
|
65
|
+
const srcStart = y * cw * 4;
|
|
66
|
+
const dstStart = y * targetWidth * 4;
|
|
67
|
+
const bytesToCopy = copyWidthC * 4;
|
|
68
|
+
normalizedCandidate.set(candidate.slice(srcStart, srcStart + bytesToCopy), dstStart);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
normalizedBaseline,
|
|
72
|
+
normalizedCandidate,
|
|
73
|
+
width: targetWidth,
|
|
74
|
+
height: targetHeight,
|
|
75
|
+
sizeMismatch: {
|
|
76
|
+
baseline: { width: bw, height: bh },
|
|
77
|
+
candidate: { width: cw, height: ch },
|
|
78
|
+
normalized: { width: targetWidth, height: targetHeight },
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=resize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../src/diff/resize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestivAI Diff Engine Types
|
|
3
|
+
*
|
|
4
|
+
* Originally forked from pixel-buffer-diff (Pbd) by @p01.
|
|
5
|
+
* Extended with ignore regions, size mismatch handling,
|
|
6
|
+
* region detection, and TypeScript support.
|
|
7
|
+
*/
|
|
8
|
+
export interface DiffOptions {
|
|
9
|
+
/** Individual pixel matching threshold (0-1). Default: 0.1 */
|
|
10
|
+
threshold?: number;
|
|
11
|
+
/** Cumulated pixel matching threshold for anti-aliasing filtering. Default: 0.5 */
|
|
12
|
+
cumulatedThreshold?: number;
|
|
13
|
+
/** Enable low-resolution minimap overlay on diff output. Default: false */
|
|
14
|
+
enableMinimap?: boolean;
|
|
15
|
+
/** Coordinate-based regions to ignore during comparison */
|
|
16
|
+
ignoreRegions?: IgnoreRegion[];
|
|
17
|
+
/** Detect and return bounding boxes of changed regions. Default: false */
|
|
18
|
+
detectRegions?: boolean;
|
|
19
|
+
/** How to handle size mismatches between baseline and candidate */
|
|
20
|
+
handleSizeMismatch?: 'pad' | 'crop' | 'error';
|
|
21
|
+
}
|
|
22
|
+
export interface IgnoreRegion {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DiffResult {
|
|
29
|
+
/** Number of pixels that exceeded the threshold */
|
|
30
|
+
diffCount: number;
|
|
31
|
+
/** Cumulated difference of every pixel change (for anti-aliasing detection) */
|
|
32
|
+
cumulatedDiff: number;
|
|
33
|
+
/** Numeric hash of pixel changes for deduplication */
|
|
34
|
+
hash: number;
|
|
35
|
+
/** Percentage of pixels that differ (0-100) */
|
|
36
|
+
diffPercent: number;
|
|
37
|
+
/** Total number of pixels compared */
|
|
38
|
+
totalPixels: number;
|
|
39
|
+
/** True if images are identical (within thresholds) */
|
|
40
|
+
isIdentical: boolean;
|
|
41
|
+
/** Bounding boxes of change clusters (if detectRegions was enabled) */
|
|
42
|
+
regions?: DiffRegion[];
|
|
43
|
+
/** Size mismatch info (if dimensions differed and were normalized) */
|
|
44
|
+
sizeMismatch?: SizeMismatch;
|
|
45
|
+
}
|
|
46
|
+
export interface DiffRegion {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
/** Number of changed pixels within this region's bounding box */
|
|
52
|
+
diffPixels: number;
|
|
53
|
+
/** Percentage of changed pixels within this region's bounding box */
|
|
54
|
+
diffPercent: number;
|
|
55
|
+
}
|
|
56
|
+
export interface SizeMismatch {
|
|
57
|
+
baseline: {
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
};
|
|
61
|
+
candidate: {
|
|
62
|
+
width: number;
|
|
63
|
+
height: number;
|
|
64
|
+
};
|
|
65
|
+
normalized: {
|
|
66
|
+
width: number;
|
|
67
|
+
height: number;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Raw result from the core Pbd diff loop (before extensions).
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
export interface PbdRawResult {
|
|
75
|
+
diff: number;
|
|
76
|
+
cumulatedDiff: number;
|
|
77
|
+
hash: number;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/diff/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,aAAa,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,WAAW,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,sEAAsE;IACtE,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TestivAI Diff Engine Types
|
|
4
|
+
*
|
|
5
|
+
* Originally forked from pixel-buffer-diff (Pbd) by @p01.
|
|
6
|
+
* Extended with ignore regions, size mismatch handling,
|
|
7
|
+
* region detection, and TypeScript support.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/diff/types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,10 +11,18 @@ export { logger, createLogger } from './utils/logger';
|
|
|
11
11
|
export { toSafeFilename, generateUniqueFilename, extractNameFromUrl, sanitizeTestName, isSafeFilename } from './utils/file-naming';
|
|
12
12
|
export { ProcessManager, spawnProcess, setupSignalHandlers, commandExists } from './utils/process';
|
|
13
13
|
export { FrameworkDetector } from './utils/framework-detect';
|
|
14
|
+
export * from './diff';
|
|
15
|
+
export { BaselineStore } from './baselines';
|
|
16
|
+
export type { BaselineMetadata } from './baselines';
|
|
17
|
+
export { loadLocalConfig, createDefaultConfig, localConfigExists, isLocalMode, getConfigPath, getDefaultConfig, } from './config';
|
|
18
|
+
export type { LocalConfig } from './config';
|
|
19
|
+
export { generateReport, compareAll, renderHtml } from './report';
|
|
20
|
+
export type { GenerateReportOptions, CompareOptions, ReportData, ReportSummary, SnapshotResult, SnapshotStatus } from './report';
|
|
14
21
|
export { authCommand } from './commands/auth';
|
|
15
22
|
export { initCommand } from './commands/init';
|
|
16
23
|
export { runCommand } from './commands/run';
|
|
17
24
|
export { witnessCommand } from './commands/capture';
|
|
25
|
+
export { approveCommand } from './commands/approve';
|
|
18
26
|
export { CoreApiClient, DEFAULT_CORE_API_URL, saveCredentials, loadCredentials, deleteCredentials, getApiKey, isAuthenticated, findConfigFile, loadConfig, configExists, getOutputDir, CompressionHelper, compressionHelper, } from '@testivai/common';
|
|
19
27
|
export declare const VERSION: any;
|
|
20
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnI,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACnI,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,cAAc,QAAQ,CAAC;AAGvB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAClE,YAAY,EAAE,qBAAqB,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGjI,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAI1B,eAAO,MAAM,OAAO,KAAqC,CAAC"}
|