storybook-addon-vis 0.7.0 → 0.9.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/dist/{chunk-LAWHEQMO.js → chunk-EYGWSOX2.js} +60 -26
- package/dist/chunk-EYGWSOX2.js.map +1 -0
- package/dist/chunk-FLRCYKBG.js +17 -0
- package/dist/chunk-FLRCYKBG.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/preview-C2OcE4hp.d.ts +6 -0
- package/dist/preview.d.ts +2 -2
- package/dist/preview.js +3 -3
- package/dist/preview.js.map +1 -1
- package/dist/{context-BX71asjt.d.ts → types-CqNsMDsD.d.ts} +13 -1
- package/dist/vitest-setup.d.ts +21 -33
- package/dist/vitest-setup.js +62 -32
- package/dist/vitest-setup.js.map +1 -1
- package/package.json +2 -1
- package/readme.md +63 -78
- package/src/@vitest/browser/context.ts +3 -0
- package/src/@vitest/browser/page.has_image_snapshot.ts +1 -5
- package/src/@vitest/browser/page.image_snapshot.ts +3 -7
- package/src/expect.to_match_image_snapshot.spec.ts +15 -4
- package/src/expect.to_match_image_snapshot.stories.tsx +9 -9
- package/src/expect.to_match_image_snapshot.ts +20 -4
- package/src/index.ts +1 -0
- package/src/param.stories.tsx +2 -1
- package/src/per_story.stories.tsx +1 -1
- package/src/preview.ts +2 -2
- package/src/should_take_snapshot.ts +13 -0
- package/src/state.ts +31 -1
- package/src/storybook/preview.ts +12 -4
- package/src/types.ts +11 -0
- package/src/vis.spec.ts +13 -0
- package/src/vis.ts +65 -0
- package/src/vitest-setup.spec.ts +0 -16
- package/src/vitest-setup.ts +4 -54
- package/dist/chunk-GN5INPRD.js +0 -11
- package/dist/chunk-GN5INPRD.js.map +0 -1
- package/dist/chunk-LAWHEQMO.js.map +0 -1
- package/dist/chunk-V67IWJFT.js +0 -12
- package/dist/chunk-V67IWJFT.js.map +0 -1
- package/dist/preview-BsZVLryd.d.ts +0 -5
- package/src/tags.spec.ts +0 -32
- package/src/tags.ts +0 -11
|
@@ -1,17 +1,55 @@
|
|
|
1
|
-
import { state } from './chunk-GN5INPRD.js';
|
|
2
1
|
import { getByAltText, getByRole, getByTestId, getByText, getByTitle, getByPlaceholderText, getByLabelText } from '@storybook/test';
|
|
3
2
|
import { join } from 'pathe';
|
|
3
|
+
import { getCurrentTest } from 'vitest/suite';
|
|
4
4
|
import dedent from 'dedent';
|
|
5
5
|
import pixelmatch from 'pixelmatch';
|
|
6
6
|
import { required } from 'type-plus';
|
|
7
7
|
|
|
8
|
+
// src/@vitest/browser/context.ts
|
|
9
|
+
|
|
8
10
|
// src/@vitest/browser/constants.ts
|
|
9
11
|
var imageSnapshotSymbol = Symbol.for("storybook-addon-vis/imageSnapshot");
|
|
10
12
|
var imageSnapshotStubSymbol = Symbol.for("storybook-addon-vis/imageSnapshotStub");
|
|
13
|
+
|
|
14
|
+
// src/@vitest/browser/image_snapshot.logic.ts
|
|
15
|
+
function isImageSnapshot(subject) {
|
|
16
|
+
return !!subject && subject.type === imageSnapshotSymbol;
|
|
17
|
+
}
|
|
18
|
+
function assertImageSnapshot(subject) {
|
|
19
|
+
if (!isImageSnapshot(subject)) {
|
|
20
|
+
throw new Error("Expected subject to be an image snapshot");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function toSnapshotId(taskName) {
|
|
24
|
+
return `${taskName.replace(/[^a-z0-9]/gi, "-").toLowerCase()}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/state.ts
|
|
28
|
+
var state = {
|
|
29
|
+
name: "",
|
|
30
|
+
testFilepath: "",
|
|
31
|
+
taskName: "",
|
|
32
|
+
snapshot: {},
|
|
33
|
+
getSnapshotFilePaths(options) {
|
|
34
|
+
const test = getCurrentTest();
|
|
35
|
+
state.taskName = test.name;
|
|
36
|
+
const id = state.id = toSnapshotId(state.taskName);
|
|
37
|
+
state.snapshot[state.testFilepath][id] = state.snapshot[state.testFilepath][id] ?? { index: 1 };
|
|
38
|
+
const index = state.snapshot[state.testFilepath][state.id].index;
|
|
39
|
+
const snapshotFilename = options?.customizeSnapshotId ? `${options.customizeSnapshotId(state.id, index)}.png` : `${state.id}-${index}.png`;
|
|
40
|
+
const baselinePath = join(state.baselineDir, snapshotFilename);
|
|
41
|
+
const resultPath = join(state.resultDir, snapshotFilename);
|
|
42
|
+
const diffPath = join(state.diffDir, snapshotFilename);
|
|
43
|
+
return { snapshotFilename, baselinePath, resultPath, diffPath };
|
|
44
|
+
},
|
|
45
|
+
incrementSnapshotIndex() {
|
|
46
|
+
state.snapshot[state.testFilepath][state.id].index++;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/@vitest/browser/page.has_image_snapshot.ts
|
|
11
51
|
async function hasImageSnapshot(options) {
|
|
12
|
-
const
|
|
13
|
-
const snapshotFilename = options?.customizeSnapshotId ? `${options.customizeSnapshotId(state.id, index)}.png` : `${state.id}-${index}.png`;
|
|
14
|
-
const baselinePath = join(state.baselineDir, snapshotFilename);
|
|
52
|
+
const { baselinePath } = state.getSnapshotFilePaths(options);
|
|
15
53
|
return commands.existFile(baselinePath);
|
|
16
54
|
}
|
|
17
55
|
|
|
@@ -52,17 +90,14 @@ async function toDataURL(imageData) {
|
|
|
52
90
|
|
|
53
91
|
// src/@vitest/browser/page.image_snapshot.ts
|
|
54
92
|
async function imageSnapshot(options) {
|
|
55
|
-
const
|
|
56
|
-
const snapshotFilename = options?.customizeSnapshotId ? `${options.customizeSnapshotId(state.id, index)}.png` : `${state.id}-${index}.png`;
|
|
57
|
-
const baselinePath = join(state.baselineDir, snapshotFilename);
|
|
58
|
-
const resultPath = join(state.resultDir, snapshotFilename);
|
|
59
|
-
const diffPath = join(state.diffDir, snapshotFilename);
|
|
93
|
+
const { snapshotFilename, baselinePath, resultPath, diffPath } = state.getSnapshotFilePaths(options);
|
|
60
94
|
const screenshot = await this.screenshot({
|
|
61
95
|
base64: true,
|
|
62
96
|
path: resultPath,
|
|
63
97
|
element: options?.element,
|
|
64
98
|
timeout: options?.timeout ?? 3e3
|
|
65
99
|
});
|
|
100
|
+
state.incrementSnapshotIndex();
|
|
66
101
|
const image = await toImageData(screenshot.base64);
|
|
67
102
|
return {
|
|
68
103
|
type: imageSnapshotSymbol,
|
|
@@ -107,6 +142,9 @@ var page = new Proxy(
|
|
|
107
142
|
if (prop === "imageSnapshot") {
|
|
108
143
|
return { type: imageSnapshotStubSymbol };
|
|
109
144
|
}
|
|
145
|
+
if (prop === "hasImageSnapshot") {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
110
148
|
console.info(`\`page.${prop.toString()}\` does not exist when running in browser`);
|
|
111
149
|
};
|
|
112
150
|
}
|
|
@@ -118,19 +156,6 @@ var server = new Proxy({}, {
|
|
|
118
156
|
}
|
|
119
157
|
});
|
|
120
158
|
|
|
121
|
-
// src/@vitest/browser/image_snapshot.logic.ts
|
|
122
|
-
function isImageSnapshot(subject) {
|
|
123
|
-
return !!subject && subject.type === imageSnapshotSymbol;
|
|
124
|
-
}
|
|
125
|
-
function assertImageSnapshot(subject) {
|
|
126
|
-
if (!isImageSnapshot(subject)) {
|
|
127
|
-
throw new Error("Expected subject to be an image snapshot");
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
function toSnapshotId(taskName) {
|
|
131
|
-
return `${taskName.replace(/[^a-z0-9]/gi, "-").toLowerCase()}`;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
159
|
// src/image_resizer.ts
|
|
135
160
|
var createImageResizer = ({ width, height }) => (image) => {
|
|
136
161
|
if (image.width === width && image.height === height) {
|
|
@@ -160,7 +185,15 @@ var createImageResizer = ({ width, height }) => (image) => {
|
|
|
160
185
|
|
|
161
186
|
// src/expect.to_match_image_snapshot.ts
|
|
162
187
|
async function toMatchImageSnapshot(actual, options) {
|
|
163
|
-
const
|
|
188
|
+
const promise = toMatchImageSnapshotInternal(actual, options);
|
|
189
|
+
const test = getCurrentTest();
|
|
190
|
+
if (!test) return promise;
|
|
191
|
+
test.promises ??= [];
|
|
192
|
+
test.promises.push(promise);
|
|
193
|
+
return promise;
|
|
194
|
+
}
|
|
195
|
+
async function toMatchImageSnapshotInternal(actual, options) {
|
|
196
|
+
let subject = await actual;
|
|
164
197
|
if (subject?.type === imageSnapshotStubSymbol) {
|
|
165
198
|
return success;
|
|
166
199
|
}
|
|
@@ -179,6 +212,7 @@ async function toMatchImageSnapshot(actual, options) {
|
|
|
179
212
|
message: () => `\`toMatchImageSnapshot()\` expects the subject to be an element, locator, or result of \`page.imageSnapshot()\`, but got: \`${subject}\``
|
|
180
213
|
};
|
|
181
214
|
}
|
|
215
|
+
subject = await page.imageSnapshot({ element: subject });
|
|
182
216
|
}
|
|
183
217
|
assertImageSnapshot(subject);
|
|
184
218
|
const baseline = await tryReadSnapshot(subject.baselinePath);
|
|
@@ -258,6 +292,6 @@ function toThresholdUnit({ failureThresholdType, width, height }, pixelDiff) {
|
|
|
258
292
|
}
|
|
259
293
|
}
|
|
260
294
|
|
|
261
|
-
export { cdp, commands, page, server,
|
|
262
|
-
//# sourceMappingURL=chunk-
|
|
263
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
export { cdp, commands, page, server, state, toMatchImageSnapshot };
|
|
296
|
+
//# sourceMappingURL=chunk-EYGWSOX2.js.map
|
|
297
|
+
//# sourceMappingURL=chunk-EYGWSOX2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/@vitest/browser/constants.ts","../src/@vitest/browser/image_snapshot.logic.ts","../src/state.ts","../src/@vitest/browser/page.has_image_snapshot.ts","../src/image_data.ts","../src/@vitest/browser/page.image_snapshot.ts","../src/@vitest/browser/context.ts","../src/image_resizer.ts","../src/expect.to_match_image_snapshot.ts"],"names":["ctx","getCurrentTest"],"mappings":"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","file":"chunk-EYGWSOX2.js","sourcesContent":["export const imageSnapshotSymbol = Symbol.for('storybook-addon-vis/imageSnapshot')\n\nexport const imageSnapshotStubSymbol = Symbol.for('storybook-addon-vis/imageSnapshotStub')\n","import { imageSnapshotSymbol } from './constants.js'\nimport type { ImageSnapshot } from './types.js'\n\nexport function isImageSnapshot(subject: any): subject is ImageSnapshot {\n\treturn !!subject && subject.type === imageSnapshotSymbol\n}\n\nexport function assertImageSnapshot(subject: any): asserts subject is ImageSnapshot {\n\tif (!isImageSnapshot(subject)) {\n\t\tthrow new Error('Expected subject to be an image snapshot')\n\t}\n}\n\nexport function toSnapshotId(taskName: string) {\n\treturn `${taskName.replace(/[^a-z0-9]/gi, '-').toLowerCase()}`\n}\n","import { join } from 'pathe'\nimport { getCurrentTest } from 'vitest/suite'\nimport { toSnapshotId } from './@vitest/browser/image_snapshot.logic'\nimport type { ImageSnapshotOptions } from './@vitest/browser/types'\nimport type { MatchImageSnapshotOptions } from './expect.to_match_image_snapshot'\n\nexport const state = {\n\tname: '',\n\ttestFilepath: '',\n\ttaskName: '',\n\tsnapshot: {},\n\tgetSnapshotFilePaths(options?: ImageSnapshotOptions | undefined) {\n\t\tconst test = getCurrentTest()\n\t\tstate.taskName = test.name\n\t\tconst id = (state.id = toSnapshotId(state.taskName))\n\t\tstate.snapshot[state.testFilepath][id] = state.snapshot[state.testFilepath][id] ?? { index: 1 }\n\n\t\tconst index = state.snapshot[state.testFilepath][state.id]!.index\n\t\tconst snapshotFilename = options?.customizeSnapshotId\n\t\t\t? `${options.customizeSnapshotId(state.id, index)}.png`\n\t\t\t: `${state.id}-${index}.png`\n\t\tconst baselinePath = join(state.baselineDir, snapshotFilename)\n\t\tconst resultPath = join(state.resultDir, snapshotFilename)\n\t\tconst diffPath = join(state.diffDir, snapshotFilename)\n\t\treturn { snapshotFilename, baselinePath, resultPath, diffPath }\n\t},\n\tincrementSnapshotIndex() {\n\t\tstate.snapshot[state.testFilepath][state.id]!.index++\n\t},\n} as unknown as {\n\tid: string\n\tname: string\n\ttestFilepath: string\n\ttestFilename: string\n\tprojectDir: string\n\tbaselineDir: string\n\tresultDir: string\n\tdiffDir: string\n\ttaskName: string\n\tparameters: {\n\t\tsnapshot?: MatchImageSnapshotOptions | undefined\n\t\t[key: string]: any\n\t}\n\ttags: string[]\n\tsnapshot: Record<string, Record<string, { index: number }>>\n\tgetSnapshotFilePaths(options?: ImageSnapshotOptions | undefined): {\n\t\tsnapshotFilename: string\n\t\tbaselinePath: string\n\t\tresultPath: string\n\t\tdiffPath: string\n\t}\n\tincrementSnapshotIndex(): void\n}\n","import type { BrowserPage } from '@vitest/browser/context'\nimport { join } from 'pathe'\nimport { state } from '../../state'\nimport { commands } from './context'\nimport type { CustomizeSnapshotIdOptions } from './types'\n\nexport interface HasImageSnapshotAction {\n\thasImageSnapshot(this: BrowserPage, options?: CustomizeSnapshotIdOptions | undefined): Promise<boolean>\n}\n\n/**\n * Check if the snapshot image exists.\n */\nexport async function hasImageSnapshot(this: BrowserPage, options?: CustomizeSnapshotIdOptions | undefined) {\n\tconst { baselinePath } = state.getSnapshotFilePaths(options)\n\treturn commands.existFile(baselinePath)\n}\n","export function toImageData(base64: string) {\n\treturn new Promise<ImageData>((resolve, reject) => {\n\t\tconst img = new Image()\n\t\timg.src = `data:image/png;base64,${base64}`\n\n\t\timg.onload = () => {\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = img.width\n\t\t\tcanvas.height = img.height\n\t\t\tconst ctx = canvas.getContext('2d')!\n\t\t\tctx.drawImage(img, 0, 0)\n\t\t\tresolve(ctx.getImageData(0, 0, canvas.width, canvas.height))\n\t\t}\n\n\t\timg.onerror = () => {\n\t\t\treject(new Error('Failed to load image'))\n\t\t}\n\t})\n}\n\nexport async function toDataURL(imageData: ImageData) {\n\tconst canvas = document.createElement('canvas')\n\tcanvas.width = imageData.width\n\tcanvas.height = imageData.height\n\tconst ctx = canvas.getContext('2d')!\n\tctx.putImageData(imageData, 0, 0)\n\treturn new Promise<string>((resolve) => {\n\t\tcanvas.toBlob((blob) => {\n\t\t\tconst reader = new FileReader()\n\t\t\treader.onload = () => {\n\t\t\t\tresolve(reader.result as string)\n\t\t\t}\n\t\t\treader.readAsDataURL(blob!)\n\t\t})\n\t})\n}\n","import type { BrowserPage } from '@vitest/browser/context'\nimport { join } from 'pathe'\nimport { getCurrentTest } from 'vitest/suite'\nimport { toImageData } from '../../image_data.js'\nimport { state } from '../../state.js'\nimport { imageSnapshotSymbol } from './constants.js'\nimport type { ImageSnapshot, ImageSnapshotOptions } from './types.js'\n\nexport interface ImageSnapshotAction {\n\timageSnapshot(this: BrowserPage, options?: ImageSnapshotOptions | undefined): Promise<ImageSnapshot>\n}\n\nexport async function imageSnapshot(\n\tthis: BrowserPage,\n\toptions?: ImageSnapshotOptions | undefined,\n): Promise<ImageSnapshot> {\n\tconst { snapshotFilename, baselinePath, resultPath, diffPath } = state.getSnapshotFilePaths(options)\n\tconst screenshot = await this.screenshot({\n\t\tbase64: true,\n\t\tpath: resultPath,\n\t\telement: options?.element,\n\t\ttimeout: options?.timeout ?? 3000,\n\t})\n\tstate.incrementSnapshotIndex()\n\tconst image = await toImageData(screenshot.base64)\n\n\treturn {\n\t\ttype: imageSnapshotSymbol,\n\t\tsnapshotFilename,\n\t\tbaselinePath,\n\t\tresultPath,\n\t\tdiffPath,\n\t\tbase64: screenshot.base64,\n\t\timage,\n\t}\n}\n","import {\n\tgetByAltText,\n\tgetByLabelText,\n\tgetByPlaceholderText,\n\tgetByRole,\n\tgetByTestId,\n\tgetByText,\n\tgetByTitle,\n} from '@storybook/test'\nimport type { BrowserCommands, BrowserPage, CDPSession, Platform } from '@vitest/browser/context'\nimport type { SerializedConfig } from 'vitest'\nimport { imageSnapshotStubSymbol } from './constants'\nimport { hasImageSnapshot } from './page.has_image_snapshot'\nimport { imageSnapshot } from './page.image_snapshot'\n\nlet ctx: Awaited<typeof import('@vitest/browser/context')>\n\nif ((globalThis as any).__vitest_browser__) {\n\timport('@vitest/browser/context').then((m) => {\n\t\tctx = m\n\t\tpage.extend({ imageSnapshot, hasImageSnapshot })\n\t})\n}\n\n// TODO: stub the functions within the `CDPSession`\n// when we better understands the use cases\nexport function cdp(): CDPSession {\n\treturn ctx?.cdp() ?? ({} as any)\n}\n\nexport const commands = new Proxy<BrowserCommands>({} as any, {\n\tget(target, prop) {\n\t\treturn (target as any)[prop] ?? (ctx?.commands as any)[prop]\n\t},\n})\n\nexport const page = new Proxy<BrowserPage>(\n\t{\n\t\tgetByAltText,\n\t\tgetByRole,\n\t\tgetByTestId,\n\t\tgetByText,\n\t\tgetByTitle,\n\t\tgetByPlaceholder: getByPlaceholderText,\n\t\tgetByLabelText,\n\t} as any,\n\t{\n\t\tget(target, prop) {\n\t\t\treturn ((target as any)[prop] ?? ctx?.page)\n\t\t\t\t? (ctx?.page as any)[prop]\n\t\t\t\t: () => {\n\t\t\t\t\t\tif (prop === 'imageSnapshot') {\n\t\t\t\t\t\t\treturn { type: imageSnapshotStubSymbol }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (prop === 'hasImageSnapshot') {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconsole.info(`\\`page.${prop.toString()}\\` does not exist when running in browser`)\n\t\t\t\t\t}\n\t\t},\n\t},\n)\n\nexport const server = new Proxy<{\n\t/**\n\t * Platform the Vitest server is running on.\n\t * The same as calling `process.platform` on the server.\n\t */\n\tplatform: Platform\n\t/**\n\t * Runtime version of the Vitest server.\n\t * The same as calling `process.version` on the server.\n\t */\n\tversion: string\n\t/**\n\t * Name of the browser provider.\n\t */\n\tprovider: string\n\t/**\n\t * Name of the current browser.\n\t */\n\tbrowser: string\n\t/**\n\t * Available commands for the browser.\n\t * @see {@link https://vitest.dev/guide/browser/commands}\n\t */\n\tcommands: BrowserCommands\n\t/**\n\t * Serialized test config.\n\t */\n\tconfig: SerializedConfig\n}>({} as any, {\n\tget(target, prop) {\n\t\treturn (target as any)[prop] ?? (ctx?.server as any)[prop]\n\t},\n})\n","export const createImageResizer =\n\t({ width, height }: { width: number; height: number }) =>\n\t(image: ImageData) => {\n\t\tif (image.width === width && image.height === height) {\n\t\t\treturn image\n\t\t}\n\t\tconst inArea = (x: number, y: number) => y <= image.height && x <= image.width\n\t\tconst result = new ImageData(width, height, { colorSpace: image.colorSpace })\n\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tfor (let x = 0; x < width; x++) {\n\t\t\t\tconst idx = (width * y + x) << 2\n\t\t\t\tif (inArea(x, y)) {\n\t\t\t\t\tconst old = (image.width * y + x) << 2\n\t\t\t\t\tresult.data[idx] = image.data[old]\n\t\t\t\t\tresult.data[idx + 1] = image.data[old + 1]\n\t\t\t\t\tresult.data[idx + 2] = image.data[old + 2]\n\t\t\t\t\tresult.data[idx + 3] = image.data[old + 3]\n\t\t\t\t} else {\n\t\t\t\t\tresult.data[idx] = 0\n\t\t\t\t\tresult.data[idx + 1] = 0\n\t\t\t\t\tresult.data[idx + 2] = 0\n\t\t\t\t\tresult.data[idx + 3] = 64\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n// slower\nexport const createImageResizer2 =\n\t({ width, height }: { width: number; height: number }) =>\n\t(image: ImageData) => {\n\t\tif (image.width === width && image.height === height) {\n\t\t\treturn image\n\t\t}\n\t\tconst inArea = (x: number, y: number) => y <= image.height && x <= image.width\n\t\tconst result = new ImageData(width, height, { colorSpace: image.colorSpace })\n\n\t\tconst copyBytes = image.width * 4\n\t\tfor (let y = 0; y < height; y++) {\n\t\t\tresult.data.set(image.data.slice(y * image.width, copyBytes), y * width * 4)\n\t\t\tfor (let x = image.width; x < width; x++) {\n\t\t\t\tconst idx = (width * y + x) << 2\n\t\t\t\tif (!inArea(x, y)) {\n\t\t\t\t\tresult.data[idx] = 0\n\t\t\t\t\tresult.data[idx + 1] = 0\n\t\t\t\t\tresult.data[idx + 2] = 0\n\t\t\t\t\tresult.data[idx + 3] = 64\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport dedent from 'dedent'\nimport pixelmatch, { type PixelmatchOptions } from 'pixelmatch'\nimport { required } from 'type-plus'\nimport { getCurrentTest } from 'vitest/suite'\nimport { imageSnapshotStubSymbol } from './@vitest/browser/constants.js'\nimport { commands, page, server } from './@vitest/browser/context.js'\nimport { assertImageSnapshot, isImageSnapshot, toSnapshotId } from './@vitest/browser/image_snapshot.logic.js'\nimport { toDataURL, toImageData } from './image_data.js'\nimport { createImageResizer } from './image_resizer.js'\nimport { state } from './state.js'\n\nexport interface ImageSnapshotMatcher {\n\ttoMatchImageSnapshot(options?: MatchImageSnapshotOptions): Promise<void>\n}\n\nexport type MatchImageSnapshotOptions = {\n\t/**\n\t * Custom options passed to 'pixelmatch'\n\t */\n\tdiffOptions?: PixelmatchOptions | undefined\n\t/**\n\t * Failure threshold should measure in `pixel` or `percent`.\n\t *\n\t * Default is `pixel`.\n\t */\n\tfailureThresholdType?: 'pixel' | 'percent' | undefined\n\tfailureThreshold?: number | undefined\n}\n\nexport async function toMatchImageSnapshot(\n\tactual: any,\n\toptions?: MatchImageSnapshotOptions | undefined,\n): AsyncExpectationResult {\n\tconst promise = toMatchImageSnapshotInternal(actual, options)\n\tconst test = getCurrentTest()\n\tif (!test) return promise\n\ttest.promises ??= []\n\ttest.promises.push(promise)\n\treturn promise\n}\n\nasync function toMatchImageSnapshotInternal(\n\tactual: any,\n\toptions?: MatchImageSnapshotOptions | undefined,\n): AsyncExpectationResult {\n\tlet subject = await actual\n\tif (subject?.type === imageSnapshotStubSymbol) {\n\t\treturn success\n\t}\n\tif (!isImageSnapshot(subject)) {\n\t\tif (subject?.path && subject?.base64) {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tactual: subject,\n\t\t\t\tmessage: () =>\n\t\t\t\t\t'`toMatchImageSnapshot()` expects the subject to be the result of `page.imageSnapshot()`, but seems like you are using `page.screenshot()`?',\n\t\t\t}\n\t\t}\n\n\t\tif (typeof subject !== 'object') {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tactual: subject,\n\t\t\t\tmessage: () =>\n\t\t\t\t\t`\\`toMatchImageSnapshot()\\` expects the subject to be an element, locator, or result of \\`page.imageSnapshot()\\`, but got: \\`${subject}\\``,\n\t\t\t}\n\t\t}\n\t\tsubject = await page.imageSnapshot({ element: subject })\n\t}\n\n\tassertImageSnapshot(subject)\n\n\tconst baseline = await tryReadSnapshot(subject.baselinePath)\n\tif (!baseline) {\n\t\tawait commands.copyFile(subject.resultPath, subject.baselinePath)\n\t\treturn success\n\t}\n\n\tconst originalImage = await toImageData(baseline)\n\tconst [resultImage, baselineImage] = alignImagesToSameSize(subject.image, originalImage)\n\n\t// const test = getCurrentTest()\n\t// console.log('test', test)\n\toptions = required(state.parameters?.snapshot, options)\n\tconst { pass, diffAmount, diffImage } = compareImage(baselineImage, resultImage, options)\n\n\tif (!pass) {\n\t\tif (server.config.snapshotOptions.updateSnapshot === 'all') {\n\t\t\tawait writeSnapshot(`${subject.baselinePath}`, resultImage)\n\t\t\treturn success\n\t\t}\n\t\tawait writeSnapshot(`${subject.diffPath}`, diffImage)\n\t\treturn {\n\t\t\tpass: false,\n\t\t\tmessage: () =>\n\t\t\t\tdedent`Snapshot \\`${state.taskName}\\` mismatched\n\n\t\t\t${\n\t\t\t\toptions?.failureThreshold\n\t\t\t\t\t? options?.failureThresholdType === 'percent'\n\t\t\t\t\t\t? `Expected image to match within ${options.failureThreshold}% but was differ by ${diffAmount}%.`\n\t\t\t\t\t\t: `Expected image to match within ${options.failureThreshold} pixels but was differ by ${diffAmount} pixels.`\n\t\t\t\t\t: `Expected image to match but was differ by ${options?.failureThresholdType === 'percent' ? `${diffAmount}%` : `${diffAmount} pixels`}.`\n\t\t\t}\n\n\t\t\tExpected: '${subject.baselinePath}'\n\t\t\tActual: '${subject.resultPath}'\n\t\t\tDifference: '${subject.diffPath}'`,\n\t\t}\n\t}\n\treturn success\n}\n\nconst success = {\n\tpass: true,\n\tmessage: () => '',\n}\n\nfunction tryReadSnapshot(path: string): Promise<string | undefined> {\n\treturn commands.readFile(path, { encoding: 'base64' }).catch(() => undefined)\n}\nasync function writeSnapshot(path: string, image: ImageData) {\n\tconst content = (await toDataURL(image)).split(',')[1]!\n\treturn commands.writeFile(path, content, 'base64url')\n}\n\nfunction alignImagesToSameSize(image1: ImageData, image2: ImageData): [image1: ImageData, image2: ImageData] {\n\tif (isSameSize(image1, image2)) {\n\t\treturn [image1, image2]\n\t}\n\tconst size = getMaxSize(image1, image2)\n\tconst resize = createImageResizer(size)\n\treturn [resize(image1), resize(image2)]\n}\n\nfunction getMaxSize(image1: ImageData, image2: ImageData) {\n\tconst width = Math.max(image1.width, image2.width)\n\tconst height = Math.max(image1.height, image2.height)\n\treturn { width, height }\n}\n\nfunction isSameSize(image1: ImageData, image2: ImageData) {\n\treturn image1.width === image2.width && image1.height === image2.height\n}\n\nfunction compareImage(\n\tbaselineImage: ImageData,\n\tresultImage: ImageData,\n\t{ failureThreshold = 0, failureThresholdType = 'pixel', diffOptions }: MatchImageSnapshotOptions = {},\n) {\n\tconst { width, height } = resultImage\n\tconst diffImage = new ImageData(width, height)\n\n\tconst pixelDiff = pixelmatch(resultImage.data, baselineImage.data, diffImage.data, width, height, diffOptions)\n\tconst diffAmount = toThresholdUnit({ failureThresholdType, width, height }, pixelDiff)\n\n\treturn {\n\t\tpass: diffAmount <= failureThreshold,\n\t\tdiffAmount,\n\t\tdiffImage,\n\t}\n}\n\nfunction toThresholdUnit(\n\t{ failureThresholdType, width, height }: { failureThresholdType: 'pixel' | 'percent'; width: number; height: number },\n\tpixelDiff: number,\n): number {\n\tswitch (failureThresholdType) {\n\t\tcase 'pixel':\n\t\t\treturn pixelDiff\n\t\tcase 'percent':\n\t\t\treturn (pixelDiff / (width * height)) * 100\n\t\tdefault:\n\t\t\tthrow new Error(`Invalid failureThresholdType: ${failureThresholdType}`)\n\t}\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { toMatchImageSnapshot, state } from './chunk-EYGWSOX2.js';
|
|
2
|
+
import { expect } from '@storybook/test';
|
|
3
|
+
|
|
4
|
+
var storybookPreviewVis = defineVisPreview();
|
|
5
|
+
function defineVisPreview() {
|
|
6
|
+
expect.extend({ toMatchImageSnapshot });
|
|
7
|
+
return {
|
|
8
|
+
beforeEach(ctx) {
|
|
9
|
+
state.tags = ctx.tags;
|
|
10
|
+
state.parameters = ctx.parameters;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { defineVisPreview, storybookPreviewVis };
|
|
16
|
+
//# sourceMappingURL=chunk-FLRCYKBG.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-FLRCYKBG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/storybook/preview.ts"],"names":[],"mappings":";;;AAKO,IAAM,sBAAsB,gBAAiB;AAE7C,SAAS,gBAA8D,GAAA;AAC7E,EAAO,MAAA,CAAA,MAAA,CAAO,EAAE,oBAAA,EAAsB,CAAA;AACtC,EAAO,OAAA;AAAA,IACN,WAAW,GAAmB,EAAA;AAC7B,MAAA,KAAA,CAAM,OAAO,GAAI,CAAA,IAAA;AACjB,MAAA,KAAA,CAAM,aAAa,GAAI,CAAA,UAAA;AAAA;AACxB,GACD;AACD","file":"chunk-FLRCYKBG.js","sourcesContent":["import { expect } from '@storybook/test'\nimport type { ProjectAnnotations, Renderer, StoryContext } from 'storybook/internal/types'\nimport { toMatchImageSnapshot } from '../expect.to_match_image_snapshot'\nimport { state } from '../state'\n\nexport const storybookPreviewVis = defineVisPreview()\n\nexport function defineVisPreview<R extends Renderer>(): ProjectAnnotations<R> {\n\texpect.extend({ toMatchImageSnapshot })\n\treturn {\n\t\tbeforeEach(ctx: StoryContext) {\n\t\t\tstate.tags = ctx.tags\n\t\t\tstate.parameters = ctx.parameters\n\t\t},\n\t}\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { M as MatchImageSnapshotOptions } from './
|
|
2
|
-
export { C as CustomizeSnapshotIdOptions, d as ImageSnapshot, I as ImageSnapshotMatcher, b as ImageSnapshotOptions, c as cdp, a as commands, p as page, s as server, t as toMatchImageSnapshot } from './
|
|
3
|
-
export {
|
|
1
|
+
import { M as MatchImageSnapshotOptions } from './types-CqNsMDsD.js';
|
|
2
|
+
export { C as CustomizeSnapshotIdOptions, d as ImageSnapshot, I as ImageSnapshotMatcher, b as ImageSnapshotOptions, V as VisOptions, c as cdp, a as commands, p as page, s as server, t as toMatchImageSnapshot } from './types-CqNsMDsD.js';
|
|
3
|
+
export { d as defineVisPreview, s as storybookPreviewVis } from './preview-C2OcE4hp.js';
|
|
4
4
|
import '@vitest/browser/context';
|
|
5
5
|
import '@vitest/expect';
|
|
6
6
|
import 'pixelmatch';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { cdp, commands, page, server, toMatchImageSnapshot } from './chunk-
|
|
3
|
-
import './chunk-GN5INPRD.js';
|
|
1
|
+
export { defineVisPreview, storybookPreviewVis } from './chunk-FLRCYKBG.js';
|
|
2
|
+
export { cdp, commands, page, server, toMatchImageSnapshot } from './chunk-EYGWSOX2.js';
|
|
4
3
|
|
|
5
4
|
// src/param.ts
|
|
6
5
|
function defineSnapshotParam(snapshot) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/param.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/param.ts"],"names":[],"mappings":";;;;AAEO,SAAS,oBAAoB,QAAqC,EAAA;AACxE,EAAA,OAAO,EAAE,QAAS,EAAA;AACnB","file":"index.js","sourcesContent":["import type { MatchImageSnapshotOptions } from './expect.to_match_image_snapshot'\n\nexport function defineSnapshotParam(snapshot: MatchImageSnapshotOptions) {\n\treturn { snapshot }\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ProjectAnnotations, Renderer } from 'storybook/internal/types';
|
|
2
|
+
|
|
3
|
+
declare const storybookPreviewVis: ProjectAnnotations<Renderer>;
|
|
4
|
+
declare function defineVisPreview<R extends Renderer>(): ProjectAnnotations<R>;
|
|
5
|
+
|
|
6
|
+
export { defineVisPreview as d, storybookPreviewVis as s };
|
package/dist/preview.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { s as storybookPreviewVis } from './preview-C2OcE4hp.js';
|
|
2
2
|
import 'storybook/internal/types';
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
export {
|
|
6
|
+
export { storybookPreviewVis as default };
|
package/dist/preview.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { storybookPreviewVis } from './chunk-FLRCYKBG.js';
|
|
2
|
+
import './chunk-EYGWSOX2.js';
|
|
3
3
|
|
|
4
4
|
// src/preview.ts
|
|
5
|
-
var preview_default =
|
|
5
|
+
var preview_default = storybookPreviewVis;
|
|
6
6
|
|
|
7
7
|
export { preview_default as default };
|
|
8
8
|
//# sourceMappingURL=preview.js.map
|
package/dist/preview.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/preview.ts"],"names":[],"mappings":";;;;AAEA,IAAO,eAAQ,GAAA","file":"preview.js","sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/preview.ts"],"names":[],"mappings":";;;;AAEA,IAAO,eAAQ,GAAA","file":"preview.js","sourcesContent":["import { storybookPreviewVis } from './storybook/preview'\n\nexport default storybookPreviewVis\n"]}
|
|
@@ -129,4 +129,16 @@ declare const server: {
|
|
|
129
129
|
config: SerializedConfig;
|
|
130
130
|
};
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
/**
|
|
133
|
+
* The project parameters for the snapshot.
|
|
134
|
+
*
|
|
135
|
+
* These parameters are set per project in the `.storybook/preview.ts` file.
|
|
136
|
+
*/
|
|
137
|
+
type VisOptions = {
|
|
138
|
+
/**
|
|
139
|
+
* The snapshot folder relative to the root of the project.
|
|
140
|
+
*/
|
|
141
|
+
snapshotPath: string;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export { type CustomizeSnapshotIdOptions as C, type ImageSnapshotMatcher as I, type MatchImageSnapshotOptions as M, type VisOptions as V, commands as a, type ImageSnapshotOptions as b, cdp as c, type ImageSnapshot as d, page as p, server as s, toMatchImageSnapshot as t };
|
package/dist/vitest-setup.d.ts
CHANGED
|
@@ -1,9 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
import { V as VisOptions } from './types-CqNsMDsD.js';
|
|
2
|
+
export { I as ImageSnapshotMatcher, M as MatchImageSnapshotOptions, c as cdp, a as commands, p as page, s as server, t as toMatchImageSnapshot } from './types-CqNsMDsD.js';
|
|
2
3
|
import '@vitest/browser/context';
|
|
3
4
|
import '@vitest/expect';
|
|
4
5
|
import 'pixelmatch';
|
|
5
6
|
import 'vitest';
|
|
6
7
|
|
|
8
|
+
declare function createVisConfig(options?: VisOptions): {
|
|
9
|
+
presets: {
|
|
10
|
+
basic(): void;
|
|
11
|
+
theme(themes: Record<string, () => void | Promise<void>>): void;
|
|
12
|
+
};
|
|
13
|
+
beforeAll(suite: {
|
|
14
|
+
file: {
|
|
15
|
+
filepath: string;
|
|
16
|
+
};
|
|
17
|
+
name: string;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
afterEach: {
|
|
20
|
+
matchImageSnapshot(): Promise<void>;
|
|
21
|
+
matchPerTheme(themes: Record<string, () => Promise<void> | void>): () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
7
25
|
/**
|
|
8
26
|
* Determine should snapshot be taken.
|
|
9
27
|
*
|
|
@@ -11,36 +29,6 @@ import 'vitest';
|
|
|
11
29
|
* no `snapshot` tag: false
|
|
12
30
|
* disabled by `!snapshot` tag: false
|
|
13
31
|
*/
|
|
14
|
-
declare function shouldTakeSnapshot(
|
|
15
|
-
story?: {
|
|
16
|
-
tags: string[];
|
|
17
|
-
};
|
|
18
|
-
}): boolean;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The project parameters for the snapshot.
|
|
22
|
-
*
|
|
23
|
-
* These parameters are set per project in the `.storybook/preview.ts` file.
|
|
24
|
-
*/
|
|
25
|
-
type VisOptions = {
|
|
26
|
-
/**
|
|
27
|
-
* The snapshot folder relative to the root of the project.
|
|
28
|
-
*/
|
|
29
|
-
snapshotPath: string;
|
|
30
|
-
};
|
|
31
|
-
declare function configureSnapshotBeforeAll(suite: {
|
|
32
|
-
file: {
|
|
33
|
-
filepath: string;
|
|
34
|
-
};
|
|
35
|
-
name: string;
|
|
36
|
-
}, options?: VisOptions): Promise<void>;
|
|
37
|
-
declare function configureSnapshotBeforeEach(ctx: {
|
|
38
|
-
task: {
|
|
39
|
-
name: string;
|
|
40
|
-
file: {
|
|
41
|
-
filepath: string;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
}): void;
|
|
32
|
+
declare function shouldTakeSnapshot(): boolean;
|
|
45
33
|
|
|
46
|
-
export {
|
|
34
|
+
export { createVisConfig, shouldTakeSnapshot };
|
package/dist/vitest-setup.js
CHANGED
|
@@ -1,40 +1,70 @@
|
|
|
1
|
-
import { commands,
|
|
2
|
-
export { cdp, commands, page, server, toMatchImageSnapshot } from './chunk-
|
|
3
|
-
import { state } from './chunk-GN5INPRD.js';
|
|
1
|
+
import { state, toMatchImageSnapshot, commands, page } from './chunk-EYGWSOX2.js';
|
|
2
|
+
export { cdp, commands, page, server, toMatchImageSnapshot } from './chunk-EYGWSOX2.js';
|
|
4
3
|
import { basename, join, dirname, relative } from 'pathe';
|
|
4
|
+
import { expect } from 'vitest';
|
|
5
5
|
|
|
6
|
-
// src/
|
|
7
|
-
function shouldTakeSnapshot(
|
|
8
|
-
if (!
|
|
9
|
-
return
|
|
6
|
+
// src/should_take_snapshot.ts
|
|
7
|
+
function shouldTakeSnapshot() {
|
|
8
|
+
if (!state.tags) return false;
|
|
9
|
+
return state.tags.lastIndexOf("!snapshot") < state.tags.lastIndexOf("snapshot");
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
// src/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
12
|
+
// src/vis.ts
|
|
13
|
+
function createVisConfig(options) {
|
|
14
|
+
expect.extend({ toMatchImageSnapshot });
|
|
15
|
+
const h = {
|
|
16
|
+
presets: {
|
|
17
|
+
basic() {
|
|
18
|
+
beforeAll(h.beforeAll);
|
|
19
|
+
afterEach(h.afterEach.matchImageSnapshot);
|
|
20
|
+
},
|
|
21
|
+
theme(themes) {
|
|
22
|
+
beforeAll(h.beforeAll);
|
|
23
|
+
afterEach(h.afterEach.matchPerTheme(themes));
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
async beforeAll(suite) {
|
|
27
|
+
state.name = suite.name;
|
|
28
|
+
state.testFilepath = suite.file.filepath;
|
|
29
|
+
state.testFilename = basename(state.testFilepath);
|
|
30
|
+
state.projectDir = state.testFilepath.slice(0, -state.name.length);
|
|
31
|
+
const snapshotPath = join(
|
|
32
|
+
state.projectDir,
|
|
33
|
+
options?.snapshotPath ?? `__snapshots__/${await commands.getSnapshotPlatform()}`
|
|
34
|
+
);
|
|
35
|
+
const currentDir = dirname(state.testFilepath);
|
|
36
|
+
state.baselineDir = relative(currentDir, join(snapshotPath, state.testFilename));
|
|
37
|
+
state.resultDir = relative(currentDir, join(snapshotPath, "__results__", state.testFilename));
|
|
38
|
+
state.diffDir = relative(currentDir, join(snapshotPath, "__diff_output__", state.testFilename));
|
|
39
|
+
if (!state.snapshot[state.testFilepath]) {
|
|
40
|
+
state.snapshot[state.testFilepath] = {};
|
|
41
|
+
await commands.rmDir(state.resultDir);
|
|
42
|
+
await commands.rmDir(state.diffDir);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
afterEach: {
|
|
46
|
+
async matchImageSnapshot() {
|
|
47
|
+
if (!shouldTakeSnapshot()) return;
|
|
48
|
+
const r = await page.imageSnapshot();
|
|
49
|
+
expect(r).toMatchImageSnapshot();
|
|
50
|
+
},
|
|
51
|
+
matchPerTheme(themes) {
|
|
52
|
+
return async function matchImageSnapshot() {
|
|
53
|
+
if (!shouldTakeSnapshot()) return;
|
|
54
|
+
for (const themeId in themes) {
|
|
55
|
+
await themes[themeId]();
|
|
56
|
+
const r = await page.imageSnapshot({
|
|
57
|
+
customizeSnapshotId: (id) => `${id}-${themeId}`
|
|
58
|
+
});
|
|
59
|
+
await expect(r).toMatchImageSnapshot();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return h;
|
|
36
66
|
}
|
|
37
67
|
|
|
38
|
-
export {
|
|
68
|
+
export { createVisConfig, shouldTakeSnapshot };
|
|
39
69
|
//# sourceMappingURL=vitest-setup.js.map
|
|
40
70
|
//# sourceMappingURL=vitest-setup.js.map
|
package/dist/vitest-setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/should_take_snapshot.ts","../src/vis.ts"],"names":[],"mappings":"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","file":"vitest-setup.js","sourcesContent":["import { state } from './state'\n\n/**\n * Determine should snapshot be taken.\n *\n * not story: false\n * no `snapshot` tag: false\n * disabled by `!snapshot` tag: false\n */\nexport function shouldTakeSnapshot() {\n\tif (!state.tags) return false\n\treturn state.tags.lastIndexOf('!snapshot') < state.tags.lastIndexOf('snapshot')\n}\n","import { basename, dirname, join, relative } from 'pathe'\nimport { expect } from 'vitest'\nimport { commands, page } from './@vitest/browser/context.js'\nimport './augment.js'\nimport { toMatchImageSnapshot } from './expect.to_match_image_snapshot.js'\nimport { shouldTakeSnapshot } from './should_take_snapshot.js'\nimport { state } from './state.js'\nimport type { VisOptions } from './types.js'\n\nexport function createVisConfig(options?: VisOptions) {\n\texpect.extend({ toMatchImageSnapshot })\n\n\tconst h = {\n\t\tpresets: {\n\t\t\tbasic() {\n\t\t\t\tbeforeAll(h.beforeAll)\n\t\t\t\tafterEach(h.afterEach.matchImageSnapshot)\n\t\t\t},\n\t\t\ttheme(themes: Record<string, () => void | Promise<void>>) {\n\t\t\t\tbeforeAll(h.beforeAll)\n\t\t\t\tafterEach(h.afterEach.matchPerTheme(themes))\n\t\t\t},\n\t\t},\n\t\tasync beforeAll(suite: { file: { filepath: string }; name: string }) {\n\t\t\tstate.name = suite.name\n\t\t\tstate.testFilepath = suite.file.filepath\n\t\t\tstate.testFilename = basename(state.testFilepath)\n\t\t\tstate.projectDir = state.testFilepath.slice(0, -state.name.length)\n\t\t\tconst snapshotPath = join(\n\t\t\t\tstate.projectDir,\n\t\t\t\toptions?.snapshotPath ?? `__snapshots__/${await commands.getSnapshotPlatform()}`,\n\t\t\t)\n\t\t\tconst currentDir = dirname(state.testFilepath)\n\t\t\tstate.baselineDir = relative(currentDir, join(snapshotPath, state.testFilename))\n\t\t\tstate.resultDir = relative(currentDir, join(snapshotPath, '__results__', state.testFilename))\n\t\t\tstate.diffDir = relative(currentDir, join(snapshotPath, '__diff_output__', state.testFilename))\n\n\t\t\tif (!state.snapshot[state.testFilepath]) {\n\t\t\t\tstate.snapshot[state.testFilepath] = {}\n\t\t\t\tawait commands.rmDir(state.resultDir)\n\t\t\t\tawait commands.rmDir(state.diffDir)\n\t\t\t}\n\t\t},\n\t\tafterEach: {\n\t\t\tasync matchImageSnapshot() {\n\t\t\t\tif (!shouldTakeSnapshot()) return\n\t\t\t\tconst r = await page.imageSnapshot()\n\t\t\t\texpect(r).toMatchImageSnapshot()\n\t\t\t},\n\t\t\tmatchPerTheme(themes: Record<string, () => Promise<void> | void>) {\n\t\t\t\treturn async function matchImageSnapshot() {\n\t\t\t\t\tif (!shouldTakeSnapshot()) return\n\t\t\t\t\tfor (const themeId in themes) {\n\t\t\t\t\t\tawait themes[themeId]()\n\t\t\t\t\t\tconst r = await page.imageSnapshot({\n\t\t\t\t\t\t\tcustomizeSnapshotId: (id) => `${id}-${themeId}`,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tawait expect(r).toMatchImageSnapshot()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n\treturn h\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storybook-addon-vis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Storybook Vitest Image Snapshot addon",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"image-snapshot",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"@storybook/react": "^8.4.2",
|
|
58
58
|
"@storybook/react-vite": "^8.4.2",
|
|
59
59
|
"@storybook/test": "^8.4.2",
|
|
60
|
+
"@testing-library/react": "^16.0.1",
|
|
60
61
|
"@types/is-ci": "^3.0.4",
|
|
61
62
|
"@types/pixelmatch": "^5.2.6",
|
|
62
63
|
"@types/react": "^18.2.65",
|