@testivai/witness 2.4.0 → 2.6.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/README.md +9 -2
- package/dist/baselines/store.d.ts +31 -0
- package/dist/baselines/store.d.ts.map +1 -1
- package/dist/baselines/store.js +38 -1
- package/dist/baselines/store.js.map +1 -1
- package/dist/bin/testivai.js +2 -0
- package/dist/bin/testivai.js.map +1 -1
- package/dist/capture/element-map.d.ts +23 -2
- package/dist/capture/element-map.d.ts.map +1 -1
- package/dist/capture/element-map.js +102 -4
- package/dist/capture/element-map.js.map +1 -1
- package/dist/capture/environment.d.ts +243 -0
- package/dist/capture/environment.d.ts.map +1 -0
- package/dist/capture/environment.js +403 -0
- package/dist/capture/environment.js.map +1 -0
- package/dist/capture/health-limits.d.ts +14 -0
- package/dist/capture/health-limits.d.ts.map +1 -0
- package/dist/capture/health-limits.js +17 -0
- package/dist/capture/health-limits.js.map +1 -0
- package/dist/capture/health.d.ts +124 -0
- package/dist/capture/health.d.ts.map +1 -0
- package/dist/capture/health.js +327 -0
- package/dist/capture/health.js.map +1 -0
- package/dist/capture/native-app.d.ts +77 -0
- package/dist/capture/native-app.d.ts.map +1 -0
- package/dist/capture/native-app.js +172 -0
- package/dist/capture/native-app.js.map +1 -0
- package/dist/capture/shard.d.ts +17 -0
- package/dist/capture/shard.d.ts.map +1 -1
- package/dist/capture/shard.js +8 -1
- package/dist/capture/shard.js.map +1 -1
- package/dist/commands/approve.d.ts.map +1 -1
- package/dist/commands/approve.js +20 -0
- package/dist/commands/approve.js.map +1 -1
- package/dist/commands/env.d.ts +37 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +113 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/merge-captures.d.ts.map +1 -1
- package/dist/commands/merge-captures.js +10 -0
- package/dist/commands/merge-captures.js.map +1 -1
- package/dist/config/local-config.d.ts +27 -0
- package/dist/config/local-config.d.ts.map +1 -1
- package/dist/config/local-config.js +1 -0
- package/dist/config/local-config.js.map +1 -1
- package/dist/config/validate-config.d.ts.map +1 -1
- package/dist/config/validate-config.js +22 -0
- package/dist/config/validate-config.js.map +1 -1
- package/dist/diff/attribution.d.ts +16 -2
- package/dist/diff/attribution.d.ts.map +1 -1
- package/dist/diff/attribution.js +5 -4
- package/dist/diff/attribution.js.map +1 -1
- package/dist/diff/dom-diff.d.ts.map +1 -1
- package/dist/diff/dom-diff.js +7 -1
- package/dist/diff/dom-diff.js.map +1 -1
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -1
- package/dist/index.js.map +1 -1
- package/dist/report/anchor.d.ts +18 -0
- package/dist/report/anchor.d.ts.map +1 -0
- package/dist/report/anchor.js +51 -0
- package/dist/report/anchor.js.map +1 -0
- package/dist/report/compare.d.ts +18 -1
- package/dist/report/compare.d.ts.map +1 -1
- package/dist/report/compare.js +107 -16
- package/dist/report/compare.js.map +1 -1
- package/dist/report/environment.d.ts +101 -0
- package/dist/report/environment.d.ts.map +1 -0
- package/dist/report/environment.js +354 -0
- package/dist/report/environment.js.map +1 -0
- package/dist/report/generator.d.ts +20 -2
- package/dist/report/generator.d.ts.map +1 -1
- package/dist/report/generator.js +46 -6
- package/dist/report/generator.js.map +1 -1
- package/dist/report/health.d.ts +115 -0
- package/dist/report/health.d.ts.map +1 -0
- package/dist/report/health.js +279 -0
- package/dist/report/health.js.map +1 -0
- package/dist/report/index.d.ts +9 -2
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +25 -1
- package/dist/report/index.js.map +1 -1
- package/dist/report/results.d.ts +73 -1
- package/dist/report/results.d.ts.map +1 -1
- package/dist/report/shift-check.d.ts +40 -0
- package/dist/report/shift-check.d.ts.map +1 -0
- package/dist/report/shift-check.js +109 -0
- package/dist/report/shift-check.js.map +1 -0
- package/dist/report/template.d.ts +28 -1
- package/dist/report/template.d.ts.map +1 -1
- package/dist/report/template.js +179 -16
- package/dist/report/template.js.map +1 -1
- package/dist/report/thumbnail.d.ts +76 -0
- package/dist/report/thumbnail.d.ts.map +1 -0
- package/dist/report/thumbnail.js +166 -0
- package/dist/report/thumbnail.js.map +1 -0
- package/dist/report/validate.d.ts +53 -0
- package/dist/report/validate.d.ts.map +1 -0
- package/dist/report/validate.js +383 -0
- package/dist/report/validate.js.map +1 -0
- package/dist/standalone/run.d.ts +39 -1
- package/dist/standalone/run.d.ts.map +1 -1
- package/dist/standalone/run.js +142 -3
- package/dist/standalone/run.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native app captures (experimental): what an Appium session's capabilities
|
|
4
|
+
* say about the device a native screen was captured on.
|
|
5
|
+
*
|
|
6
|
+
* A native screen has no page, so nothing is measured in it: the device, its
|
|
7
|
+
* OS, its screen and the status bar come from the capabilities. Appium answers
|
|
8
|
+
* a new session with unprefixed keys (`platformVersion`, `deviceModel`) and
|
|
9
|
+
* keeps what was asked for under `desired`; a session started with W3C keys
|
|
10
|
+
* has them prefixed (`appium:deviceName`). Every reader here accepts both.
|
|
11
|
+
* Whatever the capabilities do not say is left out, never guessed.
|
|
12
|
+
*
|
|
13
|
+
* The Android readings are what Appium 3.9 + UiAutomator2 8.7 returned on an
|
|
14
|
+
* Android 14 emulator; the iOS ones follow XCUITest's documented
|
|
15
|
+
* capabilities and are not verified on a simulator in this repository's CI.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.mobilePlatform = mobilePlatform;
|
|
19
|
+
exports.namesBrowser = namesBrowser;
|
|
20
|
+
exports.isNativeAppCapabilities = isNativeAppCapabilities;
|
|
21
|
+
exports.nativeAppDevice = nativeAppDevice;
|
|
22
|
+
exports.nativeAppVariant = nativeAppVariant;
|
|
23
|
+
exports.statusBarFromCapabilities = statusBarFromCapabilities;
|
|
24
|
+
exports.statusBarFromViewportRect = statusBarFromViewportRect;
|
|
25
|
+
exports.statusBarFromSystemBars = statusBarFromSystemBars;
|
|
26
|
+
exports.appiumEnvironment = appiumEnvironment;
|
|
27
|
+
const environment_1 = require("./environment");
|
|
28
|
+
const asRecord = (v) => (v && typeof v === 'object' && !Array.isArray(v) ? v : null);
|
|
29
|
+
/** A capability as the session returned it, else as it was asked for. */
|
|
30
|
+
function returned(caps, key) {
|
|
31
|
+
return caps[key] ?? caps[`appium:${key}`];
|
|
32
|
+
}
|
|
33
|
+
function requested(caps, key) {
|
|
34
|
+
const desired = asRecord(caps.desired);
|
|
35
|
+
return desired?.[key] ?? desired?.[`appium:${key}`] ?? caps[`appium:${key}`];
|
|
36
|
+
}
|
|
37
|
+
const text = (v) => (typeof v === 'string' && v.trim().length > 0 ? v.trim() : undefined);
|
|
38
|
+
function positive(v) {
|
|
39
|
+
const n = typeof v === 'string' ? Number(v) : v;
|
|
40
|
+
return typeof n === 'number' && Number.isFinite(n) && n > 0 ? n : undefined;
|
|
41
|
+
}
|
|
42
|
+
/** android / ios, or null for anything else (a desktop browser, no capabilities). */
|
|
43
|
+
function mobilePlatform(capabilities) {
|
|
44
|
+
const caps = asRecord(capabilities);
|
|
45
|
+
const name = caps ? text(returned(caps, 'platformName'))?.toLowerCase() : undefined;
|
|
46
|
+
return name === 'android' || name === 'ios' ? name : null;
|
|
47
|
+
}
|
|
48
|
+
/** Whether the session names a browser (a mobile or desktop browser session). */
|
|
49
|
+
function namesBrowser(capabilities) {
|
|
50
|
+
const caps = asRecord(capabilities);
|
|
51
|
+
return Boolean(caps && text(caps.browserName));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* An Appium session started on an app: Android or iOS, no browser, and an
|
|
55
|
+
* `app`, `appPackage` or `bundleId`. A mobile session that names neither is
|
|
56
|
+
* decided by its current context (the adapter asks).
|
|
57
|
+
*/
|
|
58
|
+
function isNativeAppCapabilities(capabilities) {
|
|
59
|
+
const caps = asRecord(capabilities);
|
|
60
|
+
if (!caps || !mobilePlatform(caps) || namesBrowser(caps))
|
|
61
|
+
return false;
|
|
62
|
+
return ['app', 'appPackage', 'bundleId'].some((key) => text(returned(caps, key)) !== undefined);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The device from the capabilities. The name is the one the session asked for:
|
|
66
|
+
* on Android, Appium puts the device serial (`emulator-5554`) in the
|
|
67
|
+
* deviceName it returns.
|
|
68
|
+
*/
|
|
69
|
+
function nativeAppDevice(capabilities) {
|
|
70
|
+
const caps = asRecord(capabilities) ?? {};
|
|
71
|
+
const platform = mobilePlatform(caps) ?? 'unknown';
|
|
72
|
+
const device = { platform };
|
|
73
|
+
const osVersion = text(returned(caps, 'platformVersion'));
|
|
74
|
+
if (osVersion)
|
|
75
|
+
device.osVersion = osVersion;
|
|
76
|
+
const model = text(returned(caps, 'deviceModel'));
|
|
77
|
+
if (model)
|
|
78
|
+
device.model = model;
|
|
79
|
+
const name = text(requested(caps, 'deviceName')) ?? (platform === 'ios' ? text(returned(caps, 'deviceName')) : undefined);
|
|
80
|
+
if (name)
|
|
81
|
+
device.name = name;
|
|
82
|
+
const automation = text(returned(caps, 'automationName'));
|
|
83
|
+
if (automation)
|
|
84
|
+
device.automation = automation;
|
|
85
|
+
const screen = text(returned(caps, 'deviceScreenSize'));
|
|
86
|
+
if (screen && /^\d+x\d+$/.test(screen))
|
|
87
|
+
device.screen = screen;
|
|
88
|
+
const density = positive(returned(caps, 'deviceScreenDensity'));
|
|
89
|
+
if (density)
|
|
90
|
+
device.density = density;
|
|
91
|
+
return device;
|
|
92
|
+
}
|
|
93
|
+
/** Lowercase, every run of other characters one `_`, none leading or trailing. */
|
|
94
|
+
function segment(s) {
|
|
95
|
+
let out = s.toLowerCase().replace(/[^a-z0-9]+/g, '_');
|
|
96
|
+
// Runs are collapsed above, so at most one `_` sits at either end.
|
|
97
|
+
if (out.startsWith('_'))
|
|
98
|
+
out = out.slice(1);
|
|
99
|
+
if (out.endsWith('_'))
|
|
100
|
+
out = out.slice(0, -1);
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The snapshot key for a device, `<platform>-<device>-<osMajor>`: the model
|
|
105
|
+
* the device reports, else the name the session asked for, and the OS major
|
|
106
|
+
* version. A part the capabilities do not give is left out.
|
|
107
|
+
*/
|
|
108
|
+
function nativeAppVariant(device) {
|
|
109
|
+
const who = device.model ?? device.name;
|
|
110
|
+
const major = device.osVersion?.split('.')[0];
|
|
111
|
+
return [device.platform, who, major]
|
|
112
|
+
.filter((p) => Boolean(p))
|
|
113
|
+
.map(segment)
|
|
114
|
+
.filter((p) => p.length > 0)
|
|
115
|
+
.join('-');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The status bar's height in screenshot pixels from the session's
|
|
119
|
+
* capabilities (UiAutomator2 returns `viewportRect` and `statBarHeight`), or
|
|
120
|
+
* null. UiAutomator2 reads it once, when the session starts, from a resource
|
|
121
|
+
* of its own server app, so it can be short (63 px for a 136 px bar on an
|
|
122
|
+
* Android 14 emulator) and does not follow a rotation: on Android the
|
|
123
|
+
* adapters prefer the window manager's frame (`statusBarFromSystemBars`).
|
|
124
|
+
*/
|
|
125
|
+
function statusBarFromCapabilities(capabilities) {
|
|
126
|
+
const caps = asRecord(capabilities) ?? {};
|
|
127
|
+
return statusBarFromViewportRect(returned(caps, 'viewportRect')) ?? positive(returned(caps, 'statBarHeight')) ?? null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The top of a viewport rectangle (`mobile: viewportRect`), or null. On
|
|
131
|
+
* UiAutomator2 its top is the session-start reading above; on XCUITest it is
|
|
132
|
+
* the iOS source.
|
|
133
|
+
*/
|
|
134
|
+
function statusBarFromViewportRect(rect) {
|
|
135
|
+
const top = asRecord(rect)?.top;
|
|
136
|
+
return typeof top === 'number' && Number.isFinite(top) && top > 0 ? Math.round(top) : null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The bottom of the status bar's window frame in screenshot pixels, from
|
|
140
|
+
* Appium's Android `mobile: getSystemBars` (`{ statusBar: { visible, x, y,
|
|
141
|
+
* width, height }, navigationBar }`, read from the window manager when it is
|
|
142
|
+
* called), or null when the bar is not visible, the driver found none
|
|
143
|
+
* (it answers a zero frame), or the answer is not that shape.
|
|
144
|
+
*/
|
|
145
|
+
function statusBarFromSystemBars(bars) {
|
|
146
|
+
const bar = asRecord(asRecord(bars)?.statusBar);
|
|
147
|
+
if (!bar || bar.visible === false)
|
|
148
|
+
return null;
|
|
149
|
+
const { y, height } = bar;
|
|
150
|
+
if (typeof y !== 'number' || typeof height !== 'number' || !Number.isFinite(y) || !Number.isFinite(height))
|
|
151
|
+
return null;
|
|
152
|
+
const bottom = Math.ceil(y + height);
|
|
153
|
+
return height > 0 && bottom > 0 ? bottom : null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The environment block of a native app capture: the machine the tests ran on
|
|
157
|
+
* (`os`), `browser.name: "native-app"` so every reader of the contract still
|
|
158
|
+
* reads it, the device, and the pixel ratio as the device scale.
|
|
159
|
+
*/
|
|
160
|
+
function appiumEnvironment(input) {
|
|
161
|
+
const caps = asRecord(input.capabilities) ?? {};
|
|
162
|
+
const scale = positive(returned(caps, 'pixelRatio'));
|
|
163
|
+
return (0, environment_1.buildCaptureEnvironment)({
|
|
164
|
+
host: input.host ?? (0, environment_1.collectHostEnvironment)(),
|
|
165
|
+
browser: { name: 'native-app', version: null },
|
|
166
|
+
framework: { ...input.framework },
|
|
167
|
+
adapter: input.adapter,
|
|
168
|
+
render: scale ? { deviceScaleFactor: scale } : undefined,
|
|
169
|
+
device: nativeAppDevice(caps),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=native-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-app.js","sourceRoot":"","sources":["../../src/capture/native-app.ts"],"names":[],"mappings":"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"}
|
package/dist/capture/shard.d.ts
CHANGED
|
@@ -17,6 +17,23 @@ export interface ShardInfo {
|
|
|
17
17
|
total: number;
|
|
18
18
|
}
|
|
19
19
|
export declare const SHARD_MANIFEST = "testivai-shard.json";
|
|
20
|
+
/**
|
|
21
|
+
* Written by `merge-captures` beside the captures it merged: whether every
|
|
22
|
+
* shard reported. When one did not, the merge fails and the comparison after
|
|
23
|
+
* it does not run; the GitHub Action, which runs after a failure too, reads
|
|
24
|
+
* this so it never compares part of the suite as if it were the whole.
|
|
25
|
+
*/
|
|
26
|
+
export declare const MERGE_RECORD = "testivai-merge.json";
|
|
27
|
+
export interface MergeRecord {
|
|
28
|
+
/** The shard total the manifests declare (or --expect); null for an unsharded merge. */
|
|
29
|
+
shardTotal: number | null;
|
|
30
|
+
shardsSeen: number[];
|
|
31
|
+
/** Shards that never reported: the merged captures are part of the suite. */
|
|
32
|
+
shardsMissing: number[];
|
|
33
|
+
/** How many captures were merged. */
|
|
34
|
+
merged: number;
|
|
35
|
+
timestamp: string;
|
|
36
|
+
}
|
|
20
37
|
/** Parse `TESTIVAI_SHARD` in either `3/8` or `3of8` form. Invalid → null. */
|
|
21
38
|
export declare function parseShardEnv(value: string | undefined): ShardInfo | null;
|
|
22
39
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shard.d.ts","sourceRoot":"","sources":["../../src/capture/shard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CASzE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,GAAG,SAAS,EAC7B,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAKT;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,IAAI,CAqBN"}
|
|
1
|
+
{"version":3,"file":"shard.d.ts","sourceRoot":"","sources":["../../src/capture/shard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,cAAc,wBAAwB,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,wFAAwF;IACxF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CASzE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,GAAG,SAAS,EAC7B,KAAK,EAAE,SAAS,GAAG,IAAI,EACvB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAKT;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,IAAI,CAqBN"}
|
package/dist/capture/shard.js
CHANGED
|
@@ -47,13 +47,20 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
47
47
|
};
|
|
48
48
|
})();
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.SHARD_MANIFEST = void 0;
|
|
50
|
+
exports.MERGE_RECORD = exports.SHARD_MANIFEST = void 0;
|
|
51
51
|
exports.parseShardEnv = parseShardEnv;
|
|
52
52
|
exports.resolveCaptureOnly = resolveCaptureOnly;
|
|
53
53
|
exports.writeShardManifest = writeShardManifest;
|
|
54
54
|
const fs = __importStar(require("fs"));
|
|
55
55
|
const path = __importStar(require("path"));
|
|
56
56
|
exports.SHARD_MANIFEST = 'testivai-shard.json';
|
|
57
|
+
/**
|
|
58
|
+
* Written by `merge-captures` beside the captures it merged: whether every
|
|
59
|
+
* shard reported. When one did not, the merge fails and the comparison after
|
|
60
|
+
* it does not run; the GitHub Action, which runs after a failure too, reads
|
|
61
|
+
* this so it never compares part of the suite as if it were the whole.
|
|
62
|
+
*/
|
|
63
|
+
exports.MERGE_RECORD = 'testivai-merge.json';
|
|
57
64
|
/** Parse `TESTIVAI_SHARD` in either `3/8` or `3of8` form. Invalid → null. */
|
|
58
65
|
function parseShardEnv(value) {
|
|
59
66
|
if (!value)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shard.js","sourceRoot":"","sources":["../../src/capture/shard.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"shard.js","sourceRoot":"","sources":["../../src/capture/shard.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCH,sCASC;AAMD,gDASC;AAuBD,gDAyBC;AAtGD,uCAAyB;AACzB,2CAA6B;AAOhB,QAAA,cAAc,GAAG,qBAAqB,CAAC;AAEpD;;;;;GAKG;AACU,QAAA,YAAY,GAAG,qBAAqB,CAAC;AAalD,6EAA6E;AAC7E,SAAgB,aAAa,CAAC,KAAyB;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,KAAK;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAChC,QAA6B,EAC7B,KAAuB,EACvB,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,OAAO,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACnD,MAAM,GAAG,GAAG,GAAG,CAAC,qBAAqB,CAAC;IACtC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC;IACzF,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC;AAgBD;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,QAAgB,EAChB,KAAgB,EAChB,UAAmD,EAAE;IAErD,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,EAAE;aAChB,WAAW,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,EAAE,CAAC;QAEV,MAAM,QAAQ,GAAkB;YAC9B,KAAK;YACL,QAAQ;YACR,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;YACnC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAc,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3F,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,mDAAmD;IACrD,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,eAAO,MAAM,cAAc,SA6HvB,CAAC"}
|
package/dist/commands/approve.js
CHANGED
|
@@ -7,7 +7,25 @@ exports.approveCommand = void 0;
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const store_1 = require("../baselines/store");
|
|
10
|
+
const health_1 = require("../capture/health");
|
|
11
|
+
const health_2 = require("../report/health");
|
|
10
12
|
const logger_1 = require("../utils/logger");
|
|
13
|
+
/**
|
|
14
|
+
* Warn when the capture about to become the baseline is unhealthy (a font or
|
|
15
|
+
* stylesheet failed to load): every compare against it would say so. It is
|
|
16
|
+
* still approved. With --json the warning goes to stderr, so stdout stays the
|
|
17
|
+
* JSON result.
|
|
18
|
+
*/
|
|
19
|
+
function warnIfUnhealthy(store, name, json) {
|
|
20
|
+
const warning = (0, health_2.approveHealthWarning)((0, health_1.parseHealth)(store.readTempMetadata(name)?.health));
|
|
21
|
+
if (!warning)
|
|
22
|
+
return;
|
|
23
|
+
const line = ` ⚠ ${name}: ${warning}.`;
|
|
24
|
+
if (json)
|
|
25
|
+
process.stderr.write(`${line}\n`);
|
|
26
|
+
else
|
|
27
|
+
console.log(chalk_1.default.yellow(line));
|
|
28
|
+
}
|
|
11
29
|
exports.approveCommand = new commander_1.Command('approve')
|
|
12
30
|
.description('Approve visual snapshots as new baselines')
|
|
13
31
|
.argument('[name]', 'Snapshot name to approve (omit for interactive list)')
|
|
@@ -72,6 +90,7 @@ exports.approveCommand = new commander_1.Command('approve')
|
|
|
72
90
|
const failed = [];
|
|
73
91
|
for (const snapName of tempNames) {
|
|
74
92
|
try {
|
|
93
|
+
warnIfUnhealthy(store, snapName, options.json);
|
|
75
94
|
store.approve(snapName);
|
|
76
95
|
approvedNames.push(snapName);
|
|
77
96
|
if (!options.json)
|
|
@@ -98,6 +117,7 @@ exports.approveCommand = new commander_1.Command('approve')
|
|
|
98
117
|
// ── Approve specific name ─────────────────────────────────────────────
|
|
99
118
|
if (name) {
|
|
100
119
|
try {
|
|
120
|
+
warnIfUnhealthy(store, name, options.json);
|
|
101
121
|
store.approve(name);
|
|
102
122
|
if (options.json)
|
|
103
123
|
process.stdout.write(JSON.stringify({ approved: [name], failed: [] }) + '\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAoC;AACpC,kDAA0B;AAC1B,8CAAmD;AACnD,4CAAyC;
|
|
1
|
+
{"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/commands/approve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { type EnvironmentPolicy, type HostEnvironment } from '../capture/environment';
|
|
3
|
+
/**
|
|
4
|
+
* `testivai env` — this machine's part of the capture environment: the OS
|
|
5
|
+
* and distro, CI and its runner image, a container, TESTIVAI_ENV_LABEL,
|
|
6
|
+
* and the environmentPolicy that decides what a change of environment does.
|
|
7
|
+
* The rest of the block (browser, framework, adapter, render settings) is
|
|
8
|
+
* recorded by each capture, since it depends on the browser a test opens.
|
|
9
|
+
*
|
|
10
|
+
* `--fonts` adds a fingerprint of the installed font list (fc-list): two
|
|
11
|
+
* machines whose fingerprints differ draw text differently, the most common
|
|
12
|
+
* reason the same page renders differently "at the same URL". Not recorded
|
|
13
|
+
* per capture: listing fonts costs a process spawn.
|
|
14
|
+
*/
|
|
15
|
+
/** Count and a short hash of a font list (fc-list output), independent of its order and duplicates. */
|
|
16
|
+
export declare function fontFingerprint(fcListOutput: string): {
|
|
17
|
+
count: number;
|
|
18
|
+
sha256: string;
|
|
19
|
+
};
|
|
20
|
+
/** The installed fonts' fingerprint, or 'unavailable' when fc-list cannot run here. */
|
|
21
|
+
export declare function readFontFingerprint(): {
|
|
22
|
+
count: number;
|
|
23
|
+
sha256: string;
|
|
24
|
+
} | 'unavailable';
|
|
25
|
+
export interface EnvironmentReport {
|
|
26
|
+
host: HostEnvironment;
|
|
27
|
+
policy: EnvironmentPolicy;
|
|
28
|
+
/** null: not asked for; 'unavailable': no fc-list. */
|
|
29
|
+
fonts: {
|
|
30
|
+
count: number;
|
|
31
|
+
sha256: string;
|
|
32
|
+
} | 'unavailable' | null;
|
|
33
|
+
}
|
|
34
|
+
/** The human-readable `testivai env` output. */
|
|
35
|
+
export declare function formatEnvironment(report: EnvironmentReport): string;
|
|
36
|
+
export declare const envCommand: Command;
|
|
37
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAA0B,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9G;;;;;;;;;;;GAWG;AAEH,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAGvF;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAOvF;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,sDAAsD;IACtD,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,GAAG,IAAI,CAAC;CACjE;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAoBnE;AAED,eAAO,MAAM,UAAU,SAiBnB,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.envCommand = void 0;
|
|
37
|
+
exports.fontFingerprint = fontFingerprint;
|
|
38
|
+
exports.readFontFingerprint = readFontFingerprint;
|
|
39
|
+
exports.formatEnvironment = formatEnvironment;
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
42
|
+
const crypto = __importStar(require("crypto"));
|
|
43
|
+
const environment_1 = require("../capture/environment");
|
|
44
|
+
const local_config_1 = require("../config/local-config");
|
|
45
|
+
/**
|
|
46
|
+
* `testivai env` — this machine's part of the capture environment: the OS
|
|
47
|
+
* and distro, CI and its runner image, a container, TESTIVAI_ENV_LABEL,
|
|
48
|
+
* and the environmentPolicy that decides what a change of environment does.
|
|
49
|
+
* The rest of the block (browser, framework, adapter, render settings) is
|
|
50
|
+
* recorded by each capture, since it depends on the browser a test opens.
|
|
51
|
+
*
|
|
52
|
+
* `--fonts` adds a fingerprint of the installed font list (fc-list): two
|
|
53
|
+
* machines whose fingerprints differ draw text differently, the most common
|
|
54
|
+
* reason the same page renders differently "at the same URL". Not recorded
|
|
55
|
+
* per capture: listing fonts costs a process spawn.
|
|
56
|
+
*/
|
|
57
|
+
/** Count and a short hash of a font list (fc-list output), independent of its order and duplicates. */
|
|
58
|
+
function fontFingerprint(fcListOutput) {
|
|
59
|
+
const fonts = [...new Set(fcListOutput.split(/\r?\n/).map((l) => l.trim()).filter(Boolean))].sort();
|
|
60
|
+
return { count: fonts.length, sha256: crypto.createHash('sha256').update(fonts.join('\n')).digest('hex').slice(0, 12) };
|
|
61
|
+
}
|
|
62
|
+
/** The installed fonts' fingerprint, or 'unavailable' when fc-list cannot run here. */
|
|
63
|
+
function readFontFingerprint() {
|
|
64
|
+
try {
|
|
65
|
+
const out = (0, child_process_1.execFileSync)('fc-list', [':', 'family', 'style'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 10000 });
|
|
66
|
+
return fontFingerprint(out);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return 'unavailable';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** The human-readable `testivai env` output. */
|
|
73
|
+
function formatEnvironment(report) {
|
|
74
|
+
const { host, policy, fonts } = report;
|
|
75
|
+
const os = `${host.os.platform} ${host.os.release} ${host.os.arch}${host.os.distro ? ` (${host.os.distro})` : ''}`;
|
|
76
|
+
const ci = host.ci ? `${host.ci.provider}${host.ci.runnerImage ? ` (runner image ${host.ci.runnerImage})` : ''}` : 'none';
|
|
77
|
+
const fontLine = fonts === null
|
|
78
|
+
? 'not checked (pass --fonts)'
|
|
79
|
+
: fonts === 'unavailable'
|
|
80
|
+
? 'fc-list is not available on this machine'
|
|
81
|
+
: `${fonts.count} installed, fingerprint ${fonts.sha256}`;
|
|
82
|
+
return [
|
|
83
|
+
'TestivAI capture environment (this machine)',
|
|
84
|
+
` os: ${os}`,
|
|
85
|
+
` ci: ${ci}`,
|
|
86
|
+
` container: ${host.container ? 'yes' : 'no'}`,
|
|
87
|
+
` label: ${host.label ?? 'none (set TESTIVAI_ENV_LABEL to name this environment)'}`,
|
|
88
|
+
` fonts: ${fontLine}`,
|
|
89
|
+
` policy: environmentPolicy "${policy}"`,
|
|
90
|
+
'Browser, framework, adapter and render settings are recorded by each capture (metadata.json `environment`).',
|
|
91
|
+
].join('\n');
|
|
92
|
+
}
|
|
93
|
+
exports.envCommand = new commander_1.Command('env')
|
|
94
|
+
.description("Print this machine's capture environment (OS, distro, CI, container, label) and the environmentPolicy")
|
|
95
|
+
.option('--fonts', 'Also fingerprint the installed fonts (fc-list): differing fingerprints mean text renders differently')
|
|
96
|
+
.option('--json', 'Print machine-readable JSON')
|
|
97
|
+
.action((options) => {
|
|
98
|
+
const report = {
|
|
99
|
+
host: (0, environment_1.collectHostEnvironment)(),
|
|
100
|
+
policy: (0, local_config_1.loadLocalConfig)(process.cwd()).environmentPolicy ?? 'warn',
|
|
101
|
+
fonts: options.fonts ? readFontFingerprint() : null,
|
|
102
|
+
};
|
|
103
|
+
if (options.json) {
|
|
104
|
+
const payload = { environment: report.host, environmentPolicy: report.policy };
|
|
105
|
+
if (report.fonts !== null)
|
|
106
|
+
payload.fonts = report.fonts;
|
|
107
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
process.stdout.write(`${formatEnvironment(report)}\n`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-captures.d.ts","sourceRoot":"","sources":["../../src/commands/merge-captures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"merge-captures.d.ts","sourceRoot":"","sources":["../../src/commands/merge-captures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iEAAiE;IACjE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gDAAgD;IAChD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kEAAkE;IAClE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAgBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,WAAW,CAkFb;AAED,eAAO,MAAM,oBAAoB,SAiE7B,CAAC"}
|
|
@@ -67,6 +67,7 @@ const commander_1 = require("commander");
|
|
|
67
67
|
const chalk_1 = __importDefault(require("chalk"));
|
|
68
68
|
const fs = __importStar(require("fs"));
|
|
69
69
|
const path = __importStar(require("path"));
|
|
70
|
+
const shard_1 = require("../capture/shard");
|
|
70
71
|
/** A directory is a capture if it holds the file every capture must have. */
|
|
71
72
|
function isCaptureDir(dir) {
|
|
72
73
|
return fs.existsSync(path.join(dir, 'screenshot.png'));
|
|
@@ -161,6 +162,15 @@ function mergeCaptures(sources, destTemp, options = {}) {
|
|
|
161
162
|
const shardsMissing = shardTotal === null
|
|
162
163
|
? []
|
|
163
164
|
: Array.from({ length: shardTotal }, (_, i) => i + 1).filter((i) => !shardsSeen.includes(i));
|
|
165
|
+
// Say whether the merge is the whole suite, beside the captures (shard.ts).
|
|
166
|
+
const record = {
|
|
167
|
+
shardTotal,
|
|
168
|
+
shardsSeen,
|
|
169
|
+
shardsMissing,
|
|
170
|
+
merged: seen.size,
|
|
171
|
+
timestamp: new Date().toISOString(),
|
|
172
|
+
};
|
|
173
|
+
fs.writeFileSync(path.join(destTemp, shard_1.MERGE_RECORD), JSON.stringify(record, null, 2));
|
|
164
174
|
return {
|
|
165
175
|
merged: [...seen.keys()].sort(),
|
|
166
176
|
conflicts: [...new Set(conflicts)].sort(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge-captures.js","sourceRoot":"","sources":["../../src/commands/merge-captures.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"merge-captures.js","sourceRoot":"","sources":["../../src/commands/merge-captures.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Reads/writes `.testivai/config.json`. Everything runs locally, so this
|
|
5
5
|
* file is optional — absent, every field falls back to its default.
|
|
6
6
|
*/
|
|
7
|
+
import type { EnvironmentPolicy } from '../capture/environment';
|
|
7
8
|
export interface LocalConfig {
|
|
8
9
|
/** Pixel diff threshold (0-1). Default: 0.1 */
|
|
9
10
|
threshold: number;
|
|
@@ -135,6 +136,32 @@ export interface LocalConfig {
|
|
|
135
136
|
* server's --approval-prompt / --no-approval-prompt flag overrides this.
|
|
136
137
|
*/
|
|
137
138
|
mcpApprovalPrompt?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* What a change of capture environment (browser, OS, device scale,
|
|
141
|
+
* capture method…: the recorded `environment`) since the baseline does:
|
|
142
|
+
* - "warn" (default): never changes a status; the report says when a
|
|
143
|
+
* diff is rendering drift rather than calling it render noise.
|
|
144
|
+
* - "separate": adapters key each snapshot by environment,
|
|
145
|
+
* `<name>__<browser>__<platform>`, so each browser and OS gates
|
|
146
|
+
* against its own baselines (never keyed by version). Only baselines
|
|
147
|
+
* of an environment this run captured can be missing.
|
|
148
|
+
* - "strict": a snapshot whose rendering environment changed is
|
|
149
|
+
* changed, whatever its pixels say (exit 1 with --fail-on-diff).
|
|
150
|
+
*/
|
|
151
|
+
environmentPolicy?: EnvironmentPolicy;
|
|
152
|
+
/**
|
|
153
|
+
* Opt-in: attribute names (e.g. ["data-testid"]) that anchor element
|
|
154
|
+
* paths in the element map. An element's path then starts at its nearest
|
|
155
|
+
* ancestor-or-self carrying one of them with a value unique in the page:
|
|
156
|
+
* `div[data-testid="board"] > div.css-146c3p1` instead of a
|
|
157
|
+
* `div.css-…:nth-of-type(4)` chain from body. Content inserted above an
|
|
158
|
+
* anchored element no longer renames it, so a moved element reads as a
|
|
159
|
+
* shift. Listed order is the precedence; a value used twice is not an
|
|
160
|
+
* anchor. Unset (the default): paths are unchanged. Changing it changes
|
|
161
|
+
* the paths, so styles are not compared against baselines captured with
|
|
162
|
+
* another setting until they are re-approved.
|
|
163
|
+
*/
|
|
164
|
+
elementIdAttributes?: string[];
|
|
138
165
|
}
|
|
139
166
|
/**
|
|
140
167
|
* Load local config from `.testivai/config.json`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-config.d.ts","sourceRoot":"","sources":["../../src/config/local-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"local-config.d.ts","sourceRoot":"","sources":["../../src/config/local-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IACvD;;;;OAIG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;OAcG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAqChE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC/B,WAAW,CAab;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAE9C"}
|