@recursica/adapter-tester 3.0.0 → 4.0.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 +36 -21
- package/dist/adapter-tester.schema.json.d.ts +18 -9
- package/dist/cli.cjs +31 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +231 -181
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +23 -12
- package/dist/config.d.ts.map +1 -1
- package/dist/fileConfig.d.ts +14 -5
- package/dist/fileConfig.d.ts.map +1 -1
- package/dist/golden/diffPng.d.ts +12 -7
- package/dist/golden/diffPng.d.ts.map +1 -1
- package/dist/golden/manifestStore.d.ts +19 -1
- package/dist/golden/manifestStore.d.ts.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/testing/runVisualRegression.d.ts +46 -21
- package/dist/testing/runVisualRegression.d.ts.map +1 -1
- package/dist/testing.cjs +3 -3
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +251 -165
- package/dist/testing.js.map +1 -1
- package/package.json +2 -6
- package/src/adapter-tester.schema.json +18 -9
package/dist/testing.js
CHANGED
|
@@ -1,156 +1,209 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { existsSync as
|
|
3
|
-
import
|
|
4
|
-
import { PNG as
|
|
5
|
-
import { join as
|
|
6
|
-
import { a as
|
|
7
|
-
function
|
|
8
|
-
const
|
|
9
|
-
if (
|
|
10
|
-
return 1 / 0;
|
|
11
|
-
const o = new
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
import { expect as K } from "@playwright/test";
|
|
2
|
+
import { existsSync as g, unlinkSync as J, readFileSync as $, mkdirSync as x, writeFileSync as P, closeSync as V, openSync as W, renameSync as X, rmSync as q } from "node:fs";
|
|
3
|
+
import H from "pixelmatch";
|
|
4
|
+
import { PNG as S } from "pngjs";
|
|
5
|
+
import { join as E } from "node:path";
|
|
6
|
+
import { a as z, i as Y } from "./index-DqQzFSAH.js";
|
|
7
|
+
function N(e, t) {
|
|
8
|
+
const n = S.sync.read(e), r = S.sync.read(t);
|
|
9
|
+
if (n.width !== r.width || n.height !== r.height)
|
|
10
|
+
return { diffPixels: 1 / 0, diffImage: null };
|
|
11
|
+
const o = new S({ width: n.width, height: n.height });
|
|
12
|
+
return { diffPixels: H(
|
|
13
|
+
n.data,
|
|
14
|
+
r.data,
|
|
15
|
+
o.data,
|
|
16
|
+
n.width,
|
|
17
|
+
n.height,
|
|
18
|
+
{ threshold: 0.1 }
|
|
19
|
+
), diffImage: S.sync.write(o) };
|
|
20
|
+
}
|
|
21
|
+
const Q = "http://json-schema.org/draft-07/schema#", Z = "https://github.com/borderux/recursica/tree/main/packages/adapter-tester/src/golden/manifest.schema.json", ee = "test/golden/manifest.json", te = "Tracks golden (baseline) image metadata for @recursica/adapter-tester's golden-image visual regression checks. One manifest lives alongside its adapter's test/golden/<story-id>.png files, keyed by story id.", re = "object", ne = { type: "object", additionalProperties: !1, required: ["createdAt"], properties: { createdAt: { type: "string", format: "date-time", description: "When this story's own golden PNG was last captured, via --update-golden, --approve-divergence, or first-run auto-create." }, sourceOfTruthCreatedAt: { type: "string", format: "date-time", description: "The source-of-truth adapter's (mantine) manifest `createdAt` for this story at the time this adapter's divergence from it was last reviewed via --approve-divergence. Omitted on the source-of-truth adapter's own manifest, and omitted here until the first approval. If mantine's current `createdAt` for this story is newer than this value, the divergence is flagged again for re-review." } } }, oe = {
|
|
22
|
+
$schema: Q,
|
|
23
|
+
$id: Z,
|
|
24
|
+
title: ee,
|
|
25
|
+
description: te,
|
|
26
|
+
type: re,
|
|
27
|
+
additionalProperties: ne
|
|
28
|
+
}, se = Y, B = new z.Ajv({ allErrors: !0, strict: !0 });
|
|
29
|
+
se(B);
|
|
30
|
+
const L = B.compile(oe);
|
|
31
|
+
function M(e, t) {
|
|
32
|
+
if (L(e)) return;
|
|
33
|
+
const n = (L.errors ?? []).map((r) => {
|
|
34
|
+
var a;
|
|
35
|
+
const o = (a = r.params) != null && a.additionalProperty ? ` '${r.params.additionalProperty}'` : "";
|
|
36
|
+
return ` - ${r.instancePath || "root"} ${r.message}${o}`;
|
|
32
37
|
}).join(`
|
|
33
38
|
`);
|
|
34
39
|
throw new Error(`Invalid ${t}:
|
|
35
|
-
${
|
|
40
|
+
${n}`);
|
|
41
|
+
}
|
|
42
|
+
function j(e) {
|
|
43
|
+
return E(e, "manifest.json");
|
|
36
44
|
}
|
|
37
|
-
function
|
|
38
|
-
return
|
|
45
|
+
function F(e) {
|
|
46
|
+
return E(e, "manifest.json.lock");
|
|
39
47
|
}
|
|
40
|
-
function
|
|
41
|
-
return
|
|
48
|
+
function O(e, t) {
|
|
49
|
+
return E(e, `${t}.png`);
|
|
42
50
|
}
|
|
43
51
|
function b(e) {
|
|
44
|
-
const t =
|
|
45
|
-
if (!
|
|
46
|
-
const
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
for (const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
const t = j(e);
|
|
53
|
+
if (!g(t)) return {};
|
|
54
|
+
const n = JSON.parse($(t, "utf8"));
|
|
55
|
+
return M(n, t), n;
|
|
56
|
+
}
|
|
57
|
+
function ie(e, t) {
|
|
58
|
+
const n = j(e);
|
|
59
|
+
M(t, n);
|
|
60
|
+
const r = {};
|
|
61
|
+
for (const a of Object.keys(t).sort())
|
|
62
|
+
r[a] = t[a];
|
|
63
|
+
x(e, { recursive: !0 });
|
|
64
|
+
const o = `${n}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
65
|
+
P(o, JSON.stringify(r, null, 2) + `
|
|
66
|
+
`), X(o, n);
|
|
67
|
+
}
|
|
68
|
+
const ae = 25, ce = 15e3;
|
|
69
|
+
function de(e) {
|
|
70
|
+
return new Promise((t) => setTimeout(t, e));
|
|
71
|
+
}
|
|
72
|
+
async function ue(e) {
|
|
73
|
+
x(e, { recursive: !0 });
|
|
74
|
+
const t = F(e), n = Date.now() + ce;
|
|
75
|
+
for (; ; )
|
|
76
|
+
try {
|
|
77
|
+
V(W(t, "wx"));
|
|
78
|
+
return;
|
|
79
|
+
} catch (r) {
|
|
80
|
+
if (r.code !== "EEXIST") throw r;
|
|
81
|
+
if (Date.now() >= n)
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Timed out waiting for the manifest lock at "${t}" — delete it if a previous run crashed while holding it.`
|
|
84
|
+
);
|
|
85
|
+
await de(ae);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function fe(e) {
|
|
89
|
+
q(F(e), { force: !0 });
|
|
90
|
+
}
|
|
91
|
+
async function _(e, t, n) {
|
|
92
|
+
await ue(e);
|
|
93
|
+
try {
|
|
94
|
+
const r = b(e), o = n(r[t]);
|
|
95
|
+
return o === void 0 ? delete r[t] : r[t] = o, ie(e, r), o;
|
|
96
|
+
} finally {
|
|
97
|
+
fe(e);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function he(e, t, n) {
|
|
101
|
+
x(e, { recursive: !0 }), P(O(e, t), n);
|
|
57
102
|
}
|
|
58
|
-
function
|
|
59
|
-
|
|
103
|
+
async function le(e, t) {
|
|
104
|
+
const n = b(e), r = Object.keys(n).filter(
|
|
105
|
+
(o) => !t.has(o)
|
|
106
|
+
);
|
|
107
|
+
for (const o of r) {
|
|
108
|
+
const a = O(e, o);
|
|
109
|
+
g(a) && J(a), await _(e, o, () => {
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return r;
|
|
60
113
|
}
|
|
61
|
-
const
|
|
62
|
-
async function
|
|
63
|
-
var
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
114
|
+
const pe = "borderux/recursica";
|
|
115
|
+
async function me(e, t) {
|
|
116
|
+
var a, d;
|
|
117
|
+
const n = await fetch(`https://registry.npmjs.org/${e}`);
|
|
118
|
+
if (!n.ok)
|
|
66
119
|
throw new Error(
|
|
67
|
-
`Could not reach npm registry for ${e}: ${
|
|
120
|
+
`Could not reach npm registry for ${e}: ${n.statusText}`
|
|
68
121
|
);
|
|
69
|
-
const
|
|
122
|
+
const r = await n.json(), o = ((a = r["dist-tags"]) == null ? void 0 : a[t]) ?? ((d = r.versions) != null && d[t] ? t : void 0);
|
|
70
123
|
if (!o)
|
|
71
124
|
throw new Error(
|
|
72
125
|
`${e} has no version or dist-tag "${t}" on the npm registry.`
|
|
73
126
|
);
|
|
74
127
|
return o;
|
|
75
128
|
}
|
|
76
|
-
function
|
|
129
|
+
function ge(e) {
|
|
77
130
|
return `packages/${e.split("/").pop()}`;
|
|
78
131
|
}
|
|
79
|
-
async function
|
|
132
|
+
async function we(e) {
|
|
80
133
|
if (e.type === "local")
|
|
81
|
-
return
|
|
134
|
+
return g(j(e.dir)) ? {
|
|
82
135
|
manifest: b(e.dir),
|
|
83
|
-
async readImage(
|
|
84
|
-
const
|
|
85
|
-
return
|
|
136
|
+
async readImage(c) {
|
|
137
|
+
const u = O(e.dir, c);
|
|
138
|
+
return g(u) ? $(u) : null;
|
|
86
139
|
}
|
|
87
140
|
} : (console.warn(
|
|
88
141
|
`No golden baseline found yet at ${e.dir} — source-of-truth divergence check skipped for this run.`
|
|
89
142
|
), null);
|
|
90
143
|
let t;
|
|
91
144
|
try {
|
|
92
|
-
t = await
|
|
145
|
+
t = await me(
|
|
93
146
|
e.packageName,
|
|
94
147
|
e.versionSpec
|
|
95
148
|
);
|
|
96
|
-
} catch (
|
|
149
|
+
} catch (i) {
|
|
97
150
|
return console.warn(
|
|
98
151
|
`Could not resolve ${e.packageName}@${e.versionSpec} — source-of-truth divergence check skipped for this run.`,
|
|
99
|
-
|
|
152
|
+
i
|
|
100
153
|
), null;
|
|
101
154
|
}
|
|
102
|
-
const
|
|
103
|
-
let
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
106
|
-
|
|
155
|
+
const n = E(e.cacheDir, t), r = `${e.packageName}@${t}`, o = `https://raw.githubusercontent.com/${pe}/${r}/${ge(e.packageName)}/test/golden`;
|
|
156
|
+
let a;
|
|
157
|
+
const d = j(n);
|
|
158
|
+
if (g(d))
|
|
159
|
+
a = b(n);
|
|
107
160
|
else {
|
|
108
|
-
let
|
|
161
|
+
let i;
|
|
109
162
|
try {
|
|
110
|
-
|
|
111
|
-
} catch (
|
|
163
|
+
i = await fetch(`${o}/manifest.json`);
|
|
164
|
+
} catch (f) {
|
|
112
165
|
return console.warn(
|
|
113
|
-
`Could not reach GitHub to fetch ${
|
|
114
|
-
|
|
166
|
+
`Could not reach GitHub to fetch ${r}'s golden baseline — source-of-truth divergence check skipped for this run.`,
|
|
167
|
+
f
|
|
115
168
|
), null;
|
|
116
169
|
}
|
|
117
|
-
if (!
|
|
170
|
+
if (!i.ok)
|
|
118
171
|
return console.warn(
|
|
119
|
-
`No golden baseline published for ${
|
|
172
|
+
`No golden baseline published for ${r} — source-of-truth divergence check skipped for this run.`
|
|
120
173
|
), null;
|
|
121
|
-
const
|
|
122
|
-
|
|
174
|
+
const c = await i.text(), u = JSON.parse(c);
|
|
175
|
+
M(u, `${o}/manifest.json`), x(n, { recursive: !0 }), P(d, c), a = u;
|
|
123
176
|
}
|
|
124
177
|
return {
|
|
125
|
-
manifest:
|
|
126
|
-
async readImage(
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
const
|
|
130
|
-
if (!
|
|
131
|
-
const
|
|
132
|
-
return
|
|
178
|
+
manifest: a,
|
|
179
|
+
async readImage(i) {
|
|
180
|
+
const c = O(n, i);
|
|
181
|
+
if (g(c)) return $(c);
|
|
182
|
+
const u = await fetch(`${o}/${i}.png`);
|
|
183
|
+
if (!u.ok) return null;
|
|
184
|
+
const f = Buffer.from(await u.arrayBuffer());
|
|
185
|
+
return x(n, { recursive: !0 }), P(c, f), f;
|
|
133
186
|
}
|
|
134
187
|
};
|
|
135
188
|
}
|
|
136
|
-
const
|
|
189
|
+
const ye = ["Theme", "Tokens", "Introduction"];
|
|
137
190
|
function D(e, t) {
|
|
138
191
|
return e === t || e.startsWith(t);
|
|
139
192
|
}
|
|
140
|
-
async function
|
|
141
|
-
let
|
|
193
|
+
async function ve(e, t, n) {
|
|
194
|
+
let r;
|
|
142
195
|
try {
|
|
143
196
|
const o = await fetch(`${e.url}/index.json`);
|
|
144
197
|
if (!o.ok)
|
|
145
198
|
throw new Error(
|
|
146
199
|
`Failed to fetch Storybook index: ${o.statusText}`
|
|
147
200
|
);
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
(
|
|
151
|
-
(
|
|
152
|
-
) && !
|
|
153
|
-
),
|
|
201
|
+
const d = (await o.json()).entries || {};
|
|
202
|
+
r = Object.values(d).filter(
|
|
203
|
+
(i) => i.type === "story" && !t.some(
|
|
204
|
+
(c) => i.title === c || i.title.startsWith(`${c}/`)
|
|
205
|
+
) && !n.some((c) => D(i.id, c))
|
|
206
|
+
), r.sort((i, c) => i.id.localeCompare(c.id));
|
|
154
207
|
} catch (o) {
|
|
155
208
|
throw console.error(
|
|
156
209
|
"Failed to load Storybook index from",
|
|
@@ -160,82 +213,115 @@ async function se(e, t, r) {
|
|
|
160
213
|
`Storybook target "${e.name}" is not responsive or index.json is missing. Please ensure its Storybook is running.`
|
|
161
214
|
);
|
|
162
215
|
}
|
|
163
|
-
return
|
|
216
|
+
return r;
|
|
164
217
|
}
|
|
165
|
-
function
|
|
166
|
-
let
|
|
218
|
+
function ke(e, t, n) {
|
|
219
|
+
let r;
|
|
167
220
|
for (const o of Object.keys(t))
|
|
168
|
-
D(e, o) && (!
|
|
169
|
-
return
|
|
221
|
+
D(e, o) && (!r || o.length > r.length) && (r = o);
|
|
222
|
+
return r !== void 0 ? t[r] : n;
|
|
170
223
|
}
|
|
171
|
-
async function
|
|
172
|
-
const t = e.isSourceOfTruthAdapter ? e.targets[0] : e.targets.find((
|
|
224
|
+
async function je(e) {
|
|
225
|
+
const t = e.isSourceOfTruthAdapter ? e.targets[0] : e.targets.find((s) => !s.sourceOfTruth);
|
|
173
226
|
if (!t)
|
|
174
227
|
throw new Error(
|
|
175
228
|
"adapter-tester config has no non-sourceOfTruth target to run the golden check against."
|
|
176
229
|
);
|
|
177
|
-
const
|
|
230
|
+
const n = e.excludeTitlePrefixes ?? ye, r = e.stories ?? {}, o = Object.keys(r).filter(
|
|
231
|
+
(s) => r[s].exclude
|
|
232
|
+
), a = Object.fromEntries(
|
|
233
|
+
Object.entries(r).filter(([, s]) => s.threshold !== void 0).map(([s, y]) => [s, y.threshold])
|
|
234
|
+
), d = e.goldenDir, i = e.goldenMode, c = e.checkMode, u = await ve(
|
|
178
235
|
t,
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
n,
|
|
237
|
+
o
|
|
238
|
+
);
|
|
239
|
+
if (i === "update-golden") {
|
|
240
|
+
const s = await le(
|
|
241
|
+
d,
|
|
242
|
+
new Set(u.map((y) => y.id))
|
|
243
|
+
);
|
|
244
|
+
s.length > 0 && console.warn(
|
|
245
|
+
`Pruned ${s.length} orphaned golden(s) no longer in Storybook: ${s.join(", ")}`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
const f = c !== "divergence" || e.isSourceOfTruthAdapter || !e.sourceOfTruthGolden ? null : await we(e.sourceOfTruthGolden), R = c === "divergence" ? "Source-of-Truth Divergence Check" : "Own-Drift Golden Image Check";
|
|
249
|
+
return {
|
|
250
|
+
ownTargetName: t.name,
|
|
251
|
+
suiteLabel: R,
|
|
252
|
+
stories: u,
|
|
253
|
+
checkStory: async (s, y, h) => {
|
|
254
|
+
const v = await y.newPage();
|
|
255
|
+
await v.setViewportSize({ width: 800, height: 600 }), await v.goto(
|
|
256
|
+
`${t.url}/iframe.html?id=${s.id}&viewMode=story`,
|
|
257
|
+
{ waitUntil: "networkidle" }
|
|
258
|
+
), await v.waitForSelector("#storybook-root"), await v.waitForTimeout(300);
|
|
259
|
+
const A = await v.screenshot(), I = O(d, s.id), l = b(d)[s.id], U = i !== "check" || !l || !g(I);
|
|
260
|
+
let w;
|
|
261
|
+
if (U)
|
|
262
|
+
he(d, s.id, A), w = l != null && l.sourceOfTruthCreatedAt ? {
|
|
263
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
264
|
+
sourceOfTruthCreatedAt: l.sourceOfTruthCreatedAt
|
|
265
|
+
} : { createdAt: (/* @__PURE__ */ new Date()).toISOString() }, l || h.annotations.push({
|
|
266
|
+
type: "golden-created",
|
|
267
|
+
description: `No golden existed yet for "${s.id}" — captured one from this run.`
|
|
268
|
+
});
|
|
269
|
+
else if (w = l, c === "own") {
|
|
270
|
+
const p = $(I), { diffPixels: m, diffImage: k } = N(
|
|
271
|
+
A,
|
|
272
|
+
p
|
|
273
|
+
), T = ke(
|
|
274
|
+
s.id,
|
|
275
|
+
a,
|
|
276
|
+
e.diffThresholdPixels
|
|
277
|
+
);
|
|
278
|
+
m >= T && (await h.attach("expected", {
|
|
279
|
+
body: p,
|
|
280
|
+
contentType: "image/png"
|
|
281
|
+
}), await h.attach("actual", {
|
|
282
|
+
body: A,
|
|
283
|
+
contentType: "image/png"
|
|
284
|
+
}), k && await h.attach("diff", {
|
|
285
|
+
body: k,
|
|
286
|
+
contentType: "image/png"
|
|
287
|
+
})), K.soft(
|
|
288
|
+
m,
|
|
289
|
+
`"${s.id}" has drifted from its own golden image (${m} mismatched pixels, threshold ${T})`
|
|
290
|
+
).toBeLessThan(T);
|
|
291
|
+
}
|
|
292
|
+
if (f) {
|
|
293
|
+
const p = f.manifest[s.id], m = p ? await f.readImage(s.id) : null;
|
|
294
|
+
if (p && m)
|
|
295
|
+
if (i === "approve-divergence")
|
|
296
|
+
w = {
|
|
297
|
+
...w,
|
|
298
|
+
sourceOfTruthCreatedAt: p.createdAt
|
|
299
|
+
};
|
|
300
|
+
else {
|
|
301
|
+
const k = $(I), { diffPixels: T, diffImage: C } = N(
|
|
302
|
+
k,
|
|
303
|
+
m
|
|
304
|
+
), G = w.sourceOfTruthCreatedAt;
|
|
305
|
+
T === 0 || G !== void 0 && G >= p.createdAt || (await h.attach("expected", {
|
|
306
|
+
body: m,
|
|
307
|
+
contentType: "image/png"
|
|
308
|
+
}), await h.attach("actual", {
|
|
309
|
+
body: k,
|
|
310
|
+
contentType: "image/png"
|
|
311
|
+
}), C && await h.attach("diff", {
|
|
312
|
+
body: C,
|
|
313
|
+
contentType: "image/png"
|
|
314
|
+
}), h.annotations.push({
|
|
315
|
+
type: "source-of-truth-divergence",
|
|
316
|
+
description: `"${s.id}" differs from the source of truth's golden and hasn't been reviewed — run with --approve-divergence if this is intentional, or fix the adapter styling.`
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
await _(d, s.id, () => w);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
237
323
|
}
|
|
238
324
|
export {
|
|
239
|
-
|
|
325
|
+
je as resolveVisualRegressionPlan
|
|
240
326
|
};
|
|
241
327
|
//# sourceMappingURL=testing.js.map
|