vitest-screenshot 1.0.1 → 1.1.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/CHANGELOG.md +3 -5
- package/README.md +13 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/update-policy.d.ts +3 -0
- package/dist/update-policy.d.ts.map +1 -0
- package/dist/update-policy.js +11 -0
- package/dist/update-policy.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +11 -4
- package/src/update-policy.ts +23 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
## [vitest-screenshot-v1.0
|
|
1
|
+
## [vitest-screenshot-v1.1.0](https://github.com/bhouston/vitest-gpu/compare/vitest-screenshot-v1.0.1...vitest-screenshot-v1.1.0) (2026-09-21)
|
|
2
2
|
|
|
3
|
-
###
|
|
3
|
+
### Features
|
|
4
4
|
|
|
5
|
-
* **screenshot:**
|
|
6
|
-
* **screenshot:** reject negated assertions ([0753f31](https://github.com/bhouston/vitest-gpu/commit/0753f317972e73d9e50d7e594d1ed22db6359c4a)), closes [#22](https://github.com/bhouston/vitest-gpu/issues/22)
|
|
7
|
-
* ship sources referenced by package maps ([8db482e](https://github.com/bhouston/vitest-gpu/commit/8db482ed56714f375b53d9a30df3f080a86fb81d)), closes [#23](https://github.com/bhouston/vitest-gpu/issues/23)
|
|
5
|
+
* **screenshot:** follow snapshot update mode ([1af74a4](https://github.com/bhouston/vitest-gpu/commit/1af74a4a94dec9912d5c5d37169adf3ff1259f73)), closes [#27](https://github.com/bhouston/vitest-gpu/issues/27)
|
package/README.md
CHANGED
|
@@ -45,8 +45,11 @@ relative to `baselineDir` unless absolute.
|
|
|
45
45
|
- Any format sharp reads and writes works: png, jpg, gif, webp, avif, tiff. **We recommend png**: it is lossless,
|
|
46
46
|
so a baseline written on the first run matches exactly. jpg and webp are re-encoded lossily on write and gif is
|
|
47
47
|
limited to 256 colours, so loosen the comparator if you use them.
|
|
48
|
-
-
|
|
49
|
-
|
|
48
|
+
- Screenshot baselines follow Vitest's snapshot update mode: missing baselines are created locally, fail in CI,
|
|
49
|
+
and `vitest -u` creates or overwrites them.
|
|
50
|
+
- `UPDATE_SCREENSHOTS=1 vitest` remains an alias for updating all screenshot baselines.
|
|
51
|
+
- Per assertion, `update: true` creates or overwrites a baseline and `update: false` prevents both overwriting and
|
|
52
|
+
creating one. This explicit option takes precedence over Vitest's mode and `UPDATE_SCREENSHOTS`.
|
|
50
53
|
- `.not.toMatchScreenshot()` is unsupported and fails without reading pixels or writing baseline files.
|
|
51
54
|
- On failure `<name>.actual.png` and `<name>.diff.png` are written to `baselineDir` (named after the test when the
|
|
52
55
|
reference is in memory). Gitignore them.
|
|
@@ -147,3 +150,11 @@ await expect(image).toMatchScreenshot('baseline.png', {
|
|
|
147
150
|
```
|
|
148
151
|
|
|
149
152
|
See [`demo/test/screenshots`](../../demo/test/screenshots) for every source, format and comparator combination.
|
|
153
|
+
|
|
154
|
+
## Author
|
|
155
|
+
|
|
156
|
+
Created by [Ben Houston](https://ben3d.ca) and sponsored by [Land of Assets](https://landofassets.com).
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export type ComparatorSelection = {
|
|
|
57
57
|
export type ScreenshotOptions = ComparatorSelection & {
|
|
58
58
|
/** Directory relative reference paths and diff images live in. Default: `__screenshots__` beside the test file. */
|
|
59
59
|
baselineDir?: string;
|
|
60
|
-
/**
|
|
60
|
+
/** Override Vitest's snapshot update mode. `true` creates/overwrites; `false` prevents both. */
|
|
61
61
|
update?: boolean;
|
|
62
62
|
};
|
|
63
63
|
/** Defaults for every assertion plus custom comparators, like `test.browser.expect.toMatchScreenshot` in Vitest config. */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,UAAU,MAAM,YAAY,CAAC;AAGpC,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,UAAU,MAAM,YAAY,CAAC;AAGpC,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAGtE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D,0HAA0H;AAC1H,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAEhG;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT;IAAE,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,GACpC;IAAE,YAAY,IAAI,SAAS,CAAA;CAAE,GAC7B;IAAE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAEhC,qHAAqH;AACrH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7C,+GAA+G;AAC/G,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEjG,mFAAmF;AACnF,MAAM,MAAM,UAAU,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CACzE,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,OAAO,GAAG;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,KACvC,gBAAgB,CAAC;AAEtB,uFAAuF;AACvF,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;IAC9E,mDAAmD;IACnD,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,mHAAmH;IACnH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,uGAAuG;AACvG,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,iBAAiB,CAAC;IAC9B,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,KAAK,cAAc,GAAG,OAAO,CAAC,MAAM,kBAAkB,EAAE,MAAM,CAAC,CAAC;AAChE,KAAK,iBAAiB,CAAC,IAAI,SAAS,cAAc,IAAI,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;AAEhG,kFAAkF;AAClF,MAAM,MAAM,mBAAmB,GAC3B;KACG,IAAI,IAAI,cAAc,GAAG;QACxB,cAAc,EAAE,IAAI,CAAC;QACrB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;KAC7C;CACF,CAAC,cAAc,CAAC,GACjB;IAAE,cAAc,CAAC,EAAE,SAAS,CAAC;IAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAA;CAAE,CAAC;AAE1F,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,GAAG;IACpD,mHAAmH;IACnH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,2HAA2H;AAC3H,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG;IACnD,WAAW,CAAC,EAAE;SAAG,IAAI,IAAI,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;KAAE,CAAC;CAClF,CAAC;AAEF,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,SAAS;QACjB,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACrF;CACF;AA+BD,2FAA2F;AAC3F,eAAO,MAAM,oBAAoB,EAAE,UAAU,CAAC,iBAAiB,CAgB9D,CAAC;AAEF,wBAAgB,cAAc,CAAC,MAAM,GAAE,gBAAqB,GAAG,IAAI,CAwDlE"}
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import pixelmatch from 'pixelmatch';
|
|
|
4
4
|
import sharp from 'sharp';
|
|
5
5
|
import { expect } from 'vitest';
|
|
6
6
|
import { metricsComparator } from './metrics.js';
|
|
7
|
+
import { resolveScreenshotUpdateState } from './update-policy.js';
|
|
7
8
|
const result = (pass, message) => ({ pass, message: () => message });
|
|
8
9
|
const raw = ({ width, height, data }) => sharp(data, { raw: { width, height, channels: 4 } });
|
|
9
10
|
/** Decodes any format sharp reads (png, jpg, gif, webp, ...) into RGBA8. */
|
|
@@ -64,13 +65,14 @@ export function extendMatchers(config = {}) {
|
|
|
64
65
|
if (!extname(reference))
|
|
65
66
|
throw new Error(`reference "${reference}" needs an image extension, e.g. "${reference}.png"`);
|
|
66
67
|
file = isAbsolute(reference) ? reference : join(dir, reference);
|
|
67
|
-
const
|
|
68
|
-
|
|
68
|
+
const exists = existsSync(file);
|
|
69
|
+
const update = resolveScreenshotUpdateState(this.snapshotState, options.update, Boolean(process.env.UPDATE_SCREENSHOTS), Boolean(process.env.CI));
|
|
70
|
+
if (update === 'all' || (update === 'new' && !exists)) {
|
|
69
71
|
await writeImage(file, actual);
|
|
70
72
|
return result(true, `wrote baseline ${file}`);
|
|
71
73
|
}
|
|
72
|
-
if (!
|
|
73
|
-
return result(false, `missing baseline ${file}; run with UPDATE_SCREENSHOTS=1`);
|
|
74
|
+
if (!exists)
|
|
75
|
+
return result(false, `missing baseline ${file}; run with UPDATE_SCREENSHOTS=1 or vitest -u`);
|
|
74
76
|
baseline = await readImage(file);
|
|
75
77
|
}
|
|
76
78
|
else {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAA0B,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAuB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type ScreenshotUpdateState = 'all' | 'new' | 'none';
|
|
2
|
+
export declare const resolveScreenshotUpdateState: (snapshotState: unknown, explicitUpdate: boolean | undefined, environmentUpdate: boolean, isCi: boolean) => ScreenshotUpdateState;
|
|
3
|
+
//# sourceMappingURL=update-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-policy.d.ts","sourceRoot":"","sources":["../src/update-policy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAW3D,eAAO,MAAM,4BAA4B,kBACxB,OAAO,kBACN,OAAO,GAAG,SAAS,qBAChB,OAAO,QACpB,OAAO,KACZ,qBAMF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const isUpdateState = (value) => value === 'all' || value === 'new' || value === 'none';
|
|
2
|
+
export const resolveScreenshotUpdateState = (snapshotState, explicitUpdate, environmentUpdate, isCi) => {
|
|
3
|
+
if (explicitUpdate !== undefined)
|
|
4
|
+
return explicitUpdate ? 'all' : 'none';
|
|
5
|
+
if (environmentUpdate)
|
|
6
|
+
return 'all';
|
|
7
|
+
const compatible = snapshotState;
|
|
8
|
+
const state = compatible?.snapshotUpdateState ?? compatible?._updateSnapshot;
|
|
9
|
+
return isUpdateState(state) ? state : isCi ? 'none' : 'new';
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=update-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-policy.js","sourceRoot":"","sources":["../src/update-policy.ts"],"names":[],"mappings":"AAQA,MAAM,aAAa,GAAG,CAAC,KAAc,EAAkC,EAAE,CACvE,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC;AAEzD,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,aAAsB,EACtB,cAAmC,EACnC,iBAA0B,EAC1B,IAAa,EACU,EAAE;IACzB,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACzE,IAAI,iBAAiB;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,UAAU,GAAG,aAAoD,CAAC;IACxE,MAAM,KAAK,GAAG,UAAU,EAAE,mBAAmB,IAAI,UAAU,EAAE,eAAe,CAAC;IAC7E,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9D,CAAC,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import pixelmatch from 'pixelmatch';
|
|
|
4
4
|
import sharp, { type FormatEnum } from 'sharp';
|
|
5
5
|
import { expect } from 'vitest';
|
|
6
6
|
import { metricsComparator, type MetricsOptions } from './metrics.js';
|
|
7
|
+
import { resolveScreenshotUpdateState } from './update-policy.js';
|
|
7
8
|
|
|
8
9
|
export type { Metric, MetricsOptions } from './metrics.js';
|
|
9
10
|
|
|
@@ -63,7 +64,7 @@ export type ComparatorSelection =
|
|
|
63
64
|
export type ScreenshotOptions = ComparatorSelection & {
|
|
64
65
|
/** Directory relative reference paths and diff images live in. Default: `__screenshots__` beside the test file. */
|
|
65
66
|
baselineDir?: string;
|
|
66
|
-
/**
|
|
67
|
+
/** Override Vitest's snapshot update mode. `true` creates/overwrites; `false` prevents both. */
|
|
67
68
|
update?: boolean;
|
|
68
69
|
};
|
|
69
70
|
|
|
@@ -143,12 +144,18 @@ export function extendMatchers(config: ScreenshotConfig = {}): void {
|
|
|
143
144
|
if (!extname(reference))
|
|
144
145
|
throw new Error(`reference "${reference}" needs an image extension, e.g. "${reference}.png"`);
|
|
145
146
|
file = isAbsolute(reference) ? reference : join(dir, reference);
|
|
146
|
-
const
|
|
147
|
-
|
|
147
|
+
const exists = existsSync(file);
|
|
148
|
+
const update = resolveScreenshotUpdateState(
|
|
149
|
+
this.snapshotState,
|
|
150
|
+
options.update,
|
|
151
|
+
Boolean(process.env.UPDATE_SCREENSHOTS),
|
|
152
|
+
Boolean(process.env.CI),
|
|
153
|
+
);
|
|
154
|
+
if (update === 'all' || (update === 'new' && !exists)) {
|
|
148
155
|
await writeImage(file, actual);
|
|
149
156
|
return result(true, `wrote baseline ${file}`);
|
|
150
157
|
}
|
|
151
|
-
if (!
|
|
158
|
+
if (!exists) return result(false, `missing baseline ${file}; run with UPDATE_SCREENSHOTS=1 or vitest -u`);
|
|
152
159
|
baseline = await readImage(file);
|
|
153
160
|
} else {
|
|
154
161
|
baseline = await toRgba(reference);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ScreenshotUpdateState = 'all' | 'new' | 'none';
|
|
2
|
+
|
|
3
|
+
type CompatibleSnapshotState = {
|
|
4
|
+
readonly snapshotUpdateState?: unknown;
|
|
5
|
+
/** Vitest 3 compatibility; remove when the peer range no longer includes Vitest 3. */
|
|
6
|
+
readonly _updateSnapshot?: unknown;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const isUpdateState = (value: unknown): value is ScreenshotUpdateState =>
|
|
10
|
+
value === 'all' || value === 'new' || value === 'none';
|
|
11
|
+
|
|
12
|
+
export const resolveScreenshotUpdateState = (
|
|
13
|
+
snapshotState: unknown,
|
|
14
|
+
explicitUpdate: boolean | undefined,
|
|
15
|
+
environmentUpdate: boolean,
|
|
16
|
+
isCi: boolean,
|
|
17
|
+
): ScreenshotUpdateState => {
|
|
18
|
+
if (explicitUpdate !== undefined) return explicitUpdate ? 'all' : 'none';
|
|
19
|
+
if (environmentUpdate) return 'all';
|
|
20
|
+
const compatible = snapshotState as CompatibleSnapshotState | undefined;
|
|
21
|
+
const state = compatible?.snapshotUpdateState ?? compatible?._updateSnapshot;
|
|
22
|
+
return isUpdateState(state) ? state : isCi ? 'none' : 'new';
|
|
23
|
+
};
|