storybook-addon-vis 4.2.4 → 4.2.6

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.
@@ -1,4 +1,4 @@
1
- import { i as commands, t as visAnnotations } from "../vis_annotation-CZE4YN-u.mjs";
1
+ import { i as commands, t as visAnnotations } from "../vis_annotation-DrDDbCAb.mjs";
2
2
  import { setAutoSnapshotOptions } from "vitest-plugin-vis";
3
3
  import { createVis } from "vitest-plugin-vis/setup-api";
4
4
 
package/dist/index.d.mts CHANGED
@@ -8,6 +8,7 @@ import { BrowserPage } from "vitest/browser";
8
8
  export * from "vitest-plugin-vis";
9
9
 
10
10
  //#region src/client/vitest_proxy.d.ts
11
+
11
12
  declare const page: BrowserPage;
12
13
  //#endregion
13
14
  //#region src/client/has_image_snapshot.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/client/vitest_proxy.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/client/storybook/tags.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAkBa,MAAI;;;;;;iBCXD,gBAAA,WAA2B,gDAAmC;;;;;;iBCqB9D,kCAAkC,4BACvC,4BAA4B,KAAK;;;;;;;;iBC7B5B,iBAAA;;;cCqBe,kBJH/B,GIKyB;;AJLzB,CAAA,CAAA,EAAa,GIKiE,uBAAA,CAAA,YJG5E,CIHsC,uBAAA,CAAsC,UAAA,CJG5E"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/client/vitest_proxy.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/client/storybook/tags.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;cAwFa,MAAI;;;;;;iBCjFD,gBAAA,WAA2B,gDAAmC;;;;;;iBCqB9D,kCAAkC,4BACvC,4BAA4B,KAAK;;;;;;;;iBC7B5B,iBAAA;;;cCqBe,kBJmE/B,GIjEyB;;AJiEzB,CAAA,CAAA,EAAa,GIjEiE,uBAAA,CAAA,YJiEhD,CIjEU,uBAAA,CAAsC,UAAA,CJiEhD"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as getCurrentTest, i as commands, n as isSnapshotEnabled, o as page, r as toMatchImageSnapshot, s as isVitestBrowser, t as visAnnotations } from "./vis_annotation-CZE4YN-u.mjs";
1
+ import { a as getCurrentTest, c as isVitestBrowser, i as commands, n as isSnapshotEnabled, o as page, r as toMatchImageSnapshot, s as whenVitestProxyReady, t as visAnnotations } from "./vis_annotation-DrDDbCAb.mjs";
2
2
  import { definePreviewAddon } from "storybook/internal/csf";
3
3
  import { expect } from "storybook/test";
4
4
  import { autoSnapshotMatcher, hasImageSnapshotAction, setAutoSnapshotOptions, toTaskId } from "vitest-plugin-vis/client-api";
@@ -43,6 +43,7 @@ var src_default = (options = { auto: false }) => {
43
43
  tags: options.auto === true ? ["snapshot"] : [],
44
44
  async beforeAll() {
45
45
  if (!isVitestBrowser()) return;
46
+ await whenVitestProxyReady();
46
47
  matcher = autoSnapshotMatcher(commands, expect);
47
48
  const suiteDefaults = options?.createMissingBaseline !== void 0 ? { createMissingBaseline: options.createMissingBaseline } : void 0;
48
49
  if (typeof options?.auto === "function") matcherFn = matcher.createMatcher({ auto: options.auto }, suiteDefaults);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/client/ctx.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/index.ts"],"sourcesContent":["import { getCurrentTest } from './vitest_proxy.ts'\n\nexport const ctx = {\n\tgetCurrentTest,\n\t__test__reset() {\n\t\tctx.getCurrentTest = getCurrentTest\n\t},\n}\n","import { hasImageSnapshotAction, type ImageSnapshotKeyOptions, toTaskId } from 'vitest-plugin-vis/client-api'\nimport { ctx } from './ctx.ts'\nimport { commands } from './vitest_proxy.ts'\n\n/**\n * Check if the snapshot image exists.\n */\nexport function hasImageSnapshot(options?: ImageSnapshotKeyOptions | undefined) {\n\tconst test = ctx.getCurrentTest()\n\tif (!test) return false\n\n\treturn hasImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type {\n\tComparisonMethod,\n\tFailureThresholdOptions,\n\tImageSnapshotCompareOptions,\n\tImageSnapshotKeyOptions,\n\tImageSnapshotSubjectOptions,\n\tImageSnapshotTimeoutOptions,\n\tPixelComparisonOptions,\n\tSsimComparisonOptions,\n\tToMatchImageSnapshotOptions,\n} from 'vitest-plugin-vis/client-api'\n\n// This fix the inferred type cannot be named error\nexport type {\n\tComparisonMethod,\n\tFailureThresholdOptions,\n\tImageSnapshotCompareOptions,\n\tImageSnapshotKeyOptions,\n\tImageSnapshotSubjectOptions,\n\tImageSnapshotTimeoutOptions,\n\tPixelComparisonOptions,\n\tSsimComparisonOptions,\n\tToMatchImageSnapshotOptions,\n}\n\n/**\n * Define snapshot parameter for auto snapshot.\n */\nexport function defineAutoSnapshotParam<M extends ComparisonMethod>(\n\tsnapshot: ToMatchImageSnapshotOptions<M> & ImageSnapshotSubjectOptions,\n) {\n\treturn { snapshot }\n}\n","// `storybook-addon-vis` provides code that can be used in test files.\nimport './shared/global_matcher_augment.ts'\n\nimport { definePreviewAddon } from 'storybook/internal/csf'\nimport { expect } from 'storybook/test'\nimport type { SetupVisOptions } from 'vitest-plugin-vis'\nimport { autoSnapshotMatcher, setAutoSnapshotOptions } from 'vitest-plugin-vis/client-api'\nimport { toMatchImageSnapshot } from './client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from './client/is_vitest_browser.ts'\nimport { commands, page } from './client/vitest_proxy.ts'\nimport { visAnnotations } from './preview/vis_annotation.ts'\n\n// Register at module load time so it's available in Storybook dev mode.\n// (visAnnotations.beforeEach is only wired via vitest's setProjectAnnotations, not in dev mode)\nexpect.extend({ toMatchImageSnapshot })\n\nexport * from 'vitest-plugin-vis'\nexport * from './client/has_image_snapshot.ts'\nexport * from './client/storybook/param.ts'\nexport * from './client/storybook/tags.ts'\n\nexport { page, visAnnotations }\n\nexport default (options: SetupVisOptions<{ tags: string[] }> = { auto: false }) => {\n\tlet matcher: ReturnType<typeof autoSnapshotMatcher>\n\tlet matcherFn: () => Promise<void>\n\treturn definePreviewAddon({\n\t\ttags: options.auto === true ? ['snapshot'] : [],\n\t\tasync beforeAll() {\n\t\t\tif (!isVitestBrowser()) return\n\t\t\tmatcher = autoSnapshotMatcher(commands, expect)\n\t\t\tconst suiteDefaults =\n\t\t\t\toptions?.createMissingBaseline !== undefined\n\t\t\t\t\t? { createMissingBaseline: options.createMissingBaseline }\n\t\t\t\t\t: undefined\n\t\t\tif (typeof options?.auto === 'function') {\n\t\t\t\tmatcherFn = matcher.createMatcher(\n\t\t\t\t\t{\n\t\t\t\t\t\tauto: options.auto,\n\t\t\t\t\t},\n\t\t\t\t\tsuiteDefaults,\n\t\t\t\t)\n\t\t\t} else if (typeof options?.auto === 'object') {\n\t\t\t\tmatcherFn = matcher.createMatcher(options.auto, suiteDefaults)\n\t\t\t} else matcherFn = matcher.createMatcher({ async auto() {} }, suiteDefaults)\n\n\t\t\tawait matcher.setup()\n\t\t\tawait setAutoSnapshotOptions(true)\n\t\t},\n\t\tafterEach() {\n\t\t\tif (matcherFn) {\n\t\t\t\treturn matcherFn()\n\t\t\t}\n\t\t},\n\t\t...visAnnotations,\n\t})\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,MAAM;CAClB;CACA,gBAAgB;AACf,MAAI,iBAAiB;;CAEtB;;;;;;;ACAD,SAAgB,iBAAiB,SAA+C;CAC/E,MAAM,OAAO,IAAI,gBAAgB;AACjC,KAAI,CAAC,KAAM,QAAO;AAElB,QAAO,uBAAuB,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;;;;ACiBjE,SAAgB,wBACf,UACC;AACD,QAAO,EAAE,UAAU;;;;;ACjBpB,OAAO,OAAO,EAAE,sBAAsB,CAAC;AASvC,mBAAgB,UAA+C,EAAE,MAAM,OAAO,KAAK;CAClF,IAAI;CACJ,IAAI;AACJ,QAAO,mBAAmB;EACzB,MAAM,QAAQ,SAAS,OAAO,CAAC,WAAW,GAAG,EAAE;EAC/C,MAAM,YAAY;AACjB,OAAI,CAAC,iBAAiB,CAAE;AACxB,aAAU,oBAAoB,UAAU,OAAO;GAC/C,MAAM,gBACL,SAAS,0BAA0B,SAChC,EAAE,uBAAuB,QAAQ,uBAAuB,GACxD;AACJ,OAAI,OAAO,SAAS,SAAS,WAC5B,aAAY,QAAQ,cACnB,EACC,MAAM,QAAQ,MACd,EACD,cACA;YACS,OAAO,SAAS,SAAS,SACnC,aAAY,QAAQ,cAAc,QAAQ,MAAM,cAAc;OACxD,aAAY,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,EAAE,cAAc;AAE5E,SAAM,QAAQ,OAAO;AACrB,SAAM,uBAAuB,KAAK;;EAEnC,YAAY;AACX,OAAI,UACH,QAAO,WAAW;;EAGpB,GAAG;EACH,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/client/ctx.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/index.ts"],"sourcesContent":["import { getCurrentTest } from './vitest_proxy.ts'\n\nexport const ctx = {\n\tgetCurrentTest,\n\t__test__reset() {\n\t\tctx.getCurrentTest = getCurrentTest\n\t},\n}\n","import { hasImageSnapshotAction, type ImageSnapshotKeyOptions, toTaskId } from 'vitest-plugin-vis/client-api'\nimport { ctx } from './ctx.ts'\nimport { commands } from './vitest_proxy.ts'\n\n/**\n * Check if the snapshot image exists.\n */\nexport function hasImageSnapshot(options?: ImageSnapshotKeyOptions | undefined) {\n\tconst test = ctx.getCurrentTest()\n\tif (!test) return false\n\n\treturn hasImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type {\n\tComparisonMethod,\n\tFailureThresholdOptions,\n\tImageSnapshotCompareOptions,\n\tImageSnapshotKeyOptions,\n\tImageSnapshotSubjectOptions,\n\tImageSnapshotTimeoutOptions,\n\tPixelComparisonOptions,\n\tSsimComparisonOptions,\n\tToMatchImageSnapshotOptions,\n} from 'vitest-plugin-vis/client-api'\n\n// This fix the inferred type cannot be named error\nexport type {\n\tComparisonMethod,\n\tFailureThresholdOptions,\n\tImageSnapshotCompareOptions,\n\tImageSnapshotKeyOptions,\n\tImageSnapshotSubjectOptions,\n\tImageSnapshotTimeoutOptions,\n\tPixelComparisonOptions,\n\tSsimComparisonOptions,\n\tToMatchImageSnapshotOptions,\n}\n\n/**\n * Define snapshot parameter for auto snapshot.\n */\nexport function defineAutoSnapshotParam<M extends ComparisonMethod>(\n\tsnapshot: ToMatchImageSnapshotOptions<M> & ImageSnapshotSubjectOptions,\n) {\n\treturn { snapshot }\n}\n","// `storybook-addon-vis` provides code that can be used in test files.\nimport './shared/global_matcher_augment.ts'\n\nimport { definePreviewAddon } from 'storybook/internal/csf'\nimport { expect } from 'storybook/test'\nimport type { SetupVisOptions } from 'vitest-plugin-vis'\nimport { autoSnapshotMatcher, setAutoSnapshotOptions } from 'vitest-plugin-vis/client-api'\nimport { toMatchImageSnapshot } from './client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from './client/is_vitest_browser.ts'\nimport { commands, page, whenVitestProxyReady } from './client/vitest_proxy.ts'\nimport { visAnnotations } from './preview/vis_annotation.ts'\n\n// Register at module load time so it's available in Storybook dev mode.\n// (visAnnotations.beforeEach is only wired via vitest's setProjectAnnotations, not in dev mode)\nexpect.extend({ toMatchImageSnapshot })\n\nexport * from 'vitest-plugin-vis'\nexport * from './client/has_image_snapshot.ts'\nexport * from './client/storybook/param.ts'\nexport * from './client/storybook/tags.ts'\n\nexport { page, visAnnotations }\n\nexport default (options: SetupVisOptions<{ tags: string[] }> = { auto: false }) => {\n\tlet matcher: ReturnType<typeof autoSnapshotMatcher>\n\tlet matcherFn: () => Promise<void>\n\treturn definePreviewAddon({\n\t\ttags: options.auto === true ? ['snapshot'] : [],\n\t\tasync beforeAll() {\n\t\t\tif (!isVitestBrowser()) return\n\t\t\t// `page` and `getCurrentTest` come from a dynamic import; the hooks that\n\t\t\t// follow read them synchronously, so wait for it here (#835).\n\t\t\tawait whenVitestProxyReady()\n\t\t\tmatcher = autoSnapshotMatcher(commands, expect)\n\t\t\tconst suiteDefaults =\n\t\t\t\toptions?.createMissingBaseline !== undefined\n\t\t\t\t\t? { createMissingBaseline: options.createMissingBaseline }\n\t\t\t\t\t: undefined\n\t\t\tif (typeof options?.auto === 'function') {\n\t\t\t\tmatcherFn = matcher.createMatcher(\n\t\t\t\t\t{\n\t\t\t\t\t\tauto: options.auto,\n\t\t\t\t\t},\n\t\t\t\t\tsuiteDefaults,\n\t\t\t\t)\n\t\t\t} else if (typeof options?.auto === 'object') {\n\t\t\t\tmatcherFn = matcher.createMatcher(options.auto, suiteDefaults)\n\t\t\t} else matcherFn = matcher.createMatcher({ async auto() {} }, suiteDefaults)\n\n\t\t\tawait matcher.setup()\n\t\t\tawait setAutoSnapshotOptions(true)\n\t\t},\n\t\tafterEach() {\n\t\t\tif (matcherFn) {\n\t\t\t\treturn matcherFn()\n\t\t\t}\n\t\t},\n\t\t...visAnnotations,\n\t})\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,MAAM;CAClB;CACA,gBAAgB;AACf,MAAI,iBAAiB;;CAEtB;;;;;;;ACAD,SAAgB,iBAAiB,SAA+C;CAC/E,MAAM,OAAO,IAAI,gBAAgB;AACjC,KAAI,CAAC,KAAM,QAAO;AAElB,QAAO,uBAAuB,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;;;;ACiBjE,SAAgB,wBACf,UACC;AACD,QAAO,EAAE,UAAU;;;;;ACjBpB,OAAO,OAAO,EAAE,sBAAsB,CAAC;AASvC,mBAAgB,UAA+C,EAAE,MAAM,OAAO,KAAK;CAClF,IAAI;CACJ,IAAI;AACJ,QAAO,mBAAmB;EACzB,MAAM,QAAQ,SAAS,OAAO,CAAC,WAAW,GAAG,EAAE;EAC/C,MAAM,YAAY;AACjB,OAAI,CAAC,iBAAiB,CAAE;AAGxB,SAAM,sBAAsB;AAC5B,aAAU,oBAAoB,UAAU,OAAO;GAC/C,MAAM,gBACL,SAAS,0BAA0B,SAChC,EAAE,uBAAuB,QAAQ,uBAAuB,GACxD;AACJ,OAAI,OAAO,SAAS,SAAS,WAC5B,aAAY,QAAQ,cACnB,EACC,MAAM,QAAQ,MACd,EACD,cACA;YACS,OAAO,SAAS,SAAS,SACnC,aAAY,QAAQ,cAAc,QAAQ,MAAM,cAAc;OACxD,aAAY,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,EAAE,cAAc;AAE5E,SAAM,QAAQ,OAAO;AACrB,SAAM,uBAAuB,KAAK;;EAEnC,YAAY;AACX,OAAI,UACH,QAAO,WAAW;;EAGpB,GAAG;EACH,CAAC"}
@@ -28,26 +28,57 @@ function toMatchImageSnapshot$1(options) {
28
28
 
29
29
  //#endregion
30
30
  //#region src/client/vitest_proxy.ts
31
- let browserContext;
32
- let vitest;
33
- if (isVitestBrowser()) {
34
- import("vitest/browser").then((m) => {
31
+ /**
32
+ * Build the `page` / `commands` / `getCurrentTest` proxies over `loaders`.
33
+ *
34
+ * Exported for tests: it is the only way to observe the window between module
35
+ * load and the dynamic imports settling.
36
+ */
37
+ function createVitestProxy(loaders) {
38
+ let browserContext;
39
+ let vitest;
40
+ const browserReady = loaders ? loaders.loadBrowser().then((m) => {
35
41
  m.page.extend({ toMatchImageSnapshot: toMatchImageSnapshot$1 });
36
42
  browserContext = m;
37
- });
38
- import("vitest").then((m) => {
43
+ }) : Promise.resolve();
44
+ const vitestReady = loaders ? loaders.loadVitest().then((m) => {
39
45
  vitest = m;
40
- });
46
+ }) : Promise.resolve();
47
+ const ready = Promise.all([browserReady, vitestReady]).then(() => void 0);
48
+ const page$1 = new Proxy({}, { get(_target, prop) {
49
+ const r = (browserContext?.page)?.[prop];
50
+ if (prop === "toMatchImageSnapshot" && r === void 0) return () => {};
51
+ return r;
52
+ } });
53
+ const commands$1 = new Proxy({}, { get(_target, prop) {
54
+ if (!loaders) return void 0;
55
+ if (browserContext) return browserContext.commands[prop];
56
+ return (...args) => browserReady.then(() => browserContext.commands[prop](...args));
57
+ } });
58
+ const getCurrentTest$1 = () => vitest?.TestRunner.getCurrentTest();
59
+ /**
60
+ * Resolves once the vitest modules behind `page`, `commands`, and
61
+ * `getCurrentTest` are loaded.
62
+ *
63
+ * `page` and `getCurrentTest` are read synchronously, so hooks that depend on
64
+ * them must await this first (#835).
65
+ */
66
+ const whenReady = () => ready;
67
+ return {
68
+ page: page$1,
69
+ commands: commands$1,
70
+ getCurrentTest: getCurrentTest$1,
71
+ whenReady
72
+ };
41
73
  }
42
- const page = new Proxy({}, { get(_target, prop) {
43
- const r = (browserContext?.page)?.[prop];
44
- if (prop === "toMatchImageSnapshot" && r === void 0) return () => {};
45
- return r;
46
- } });
47
- const commands = new Proxy({}, { get(_target, prop) {
48
- return (browserContext?.commands)?.[prop];
49
- } });
50
- const getCurrentTest = () => vitest?.TestRunner.getCurrentTest();
74
+ const proxy = createVitestProxy(isVitestBrowser() ? {
75
+ loadBrowser: () => import("vitest/browser"),
76
+ loadVitest: () => import("vitest")
77
+ } : void 0);
78
+ const page = proxy.page;
79
+ const commands = proxy.commands;
80
+ const getCurrentTest = proxy.getCurrentTest;
81
+ const whenVitestProxyReady = proxy.whenReady;
51
82
 
52
83
  //#endregion
53
84
  //#region src/client/expect/to_match_image_snapshot.ts
@@ -87,5 +118,5 @@ const visAnnotations = { beforeEach(ctx) {
87
118
  } };
88
119
 
89
120
  //#endregion
90
- export { getCurrentTest as a, commands as i, isSnapshotEnabled as n, page as o, toMatchImageSnapshot as r, isVitestBrowser as s, visAnnotations as t };
91
- //# sourceMappingURL=vis_annotation-CZE4YN-u.mjs.map
121
+ export { getCurrentTest as a, isVitestBrowser as c, commands as i, isSnapshotEnabled as n, page as o, toMatchImageSnapshot as r, whenVitestProxyReady as s, visAnnotations as t };
122
+ //# sourceMappingURL=vis_annotation-DrDDbCAb.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_annotation-DrDDbCAb.mjs","names":["toMatchImageSnapshot","page","commands","getCurrentTest"],"sources":["../src/client/is_vitest_browser.ts","../src/client/page/to_match_image_snapshot.ts","../src/client/vitest_proxy.ts","../src/client/expect/to_match_image_snapshot.ts","../src/client/storybook/tags.ts","../src/preview/vis_annotation.ts"],"sourcesContent":["/**\n * Whether the code is running inside a Vitest browser-mode run.\n *\n * This is the signal the addon actually depends on: `commands` and `page` in\n * `vitest_proxy.ts` are only populated when `__vitest_browser__` is set, so any\n * broader \"am I under test\" check (such as one matching a `HeadlessChrome` user\n * agent) lets a plain headless browser reach the snapshot setup and fail on the\n * empty proxy with `commands.setupVisSuite is not a function`.\n */\nexport function isVitestBrowser() {\n\treturn !!(globalThis as any).__vitest_browser__\n}\n","import {\n\ttype ComparisonMethod,\n\tmatchPageImageSnapshotAction,\n\ttype ToMatchPageImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod = 'pixel'>(\n\toptions?: ToMatchPageImageSnapshotOptions<M> | undefined,\n) {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve()\n\t/* v8 ignore end */\n\n\treturn matchPageImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type { BrowserCommands, BrowserPage } from 'vitest/browser'\nimport type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'\nimport { isVitestBrowser } from './is_vitest_browser.ts'\nimport { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'\n\ntype BrowserModule = Awaited<typeof import('vitest/browser')>\ntype VitestModule = Awaited<typeof import('vitest')>\n\n/**\n * How the proxy gets hold of the vitest modules.\n *\n * They are loaded dynamically because this module is also reached from a plain\n * Storybook preview, where `vitest` and `vitest/browser` are not available.\n * Passing `undefined` stands for \"not a vitest browser run\": nothing is loaded\n * and the proxies stay empty.\n */\nexport type VitestProxyLoaders = {\n\tloadBrowser: () => Promise<BrowserModule>\n\tloadVitest: () => Promise<VitestModule>\n}\n\n/**\n * Build the `page` / `commands` / `getCurrentTest` proxies over `loaders`.\n *\n * Exported for tests: it is the only way to observe the window between module\n * load and the dynamic imports settling.\n */\nexport function createVitestProxy(loaders: VitestProxyLoaders | undefined) {\n\tlet browserContext: BrowserModule | undefined\n\tlet vitest: VitestModule | undefined\n\n\tconst browserReady = loaders\n\t\t? loaders.loadBrowser().then((m) => {\n\t\t\t\tm.page.extend({ toMatchImageSnapshot })\n\t\t\t\tbrowserContext = m\n\t\t\t})\n\t\t: Promise.resolve()\n\tconst vitestReady = loaders\n\t\t? loaders.loadVitest().then((m) => {\n\t\t\t\tvitest = m\n\t\t\t})\n\t\t: Promise.resolve()\n\tconst ready = Promise.all([browserReady, vitestReady]).then(() => undefined)\n\n\tconst page = new Proxy<BrowserPage>({} as any, {\n\t\tget(_target, prop) {\n\t\t\tconst r = (browserContext?.page as any)?.[prop]\n\t\t\tif (prop === 'toMatchImageSnapshot' && r === undefined) {\n\t\t\t\treturn () => {}\n\t\t\t}\n\t\t\treturn r\n\t\t},\n\t})\n\n\tconst commands = new Proxy<BrowserCommands>({} as any, {\n\t\tget(_target, prop) {\n\t\t\t// Outside a vitest browser run there is nothing to wait for: keep\n\t\t\t// yielding `undefined` so the addon guards stay in charge (#829).\n\t\t\tif (!loaders) return undefined\n\t\t\tif (browserContext) return (browserContext.commands as any)[prop]\n\t\t\t// The import has not settled yet (#835). Commands are async RPC calls,\n\t\t\t// so hand back a function that waits for the module instead of\n\t\t\t// `undefined`, which fails as `<command> is not a function`.\n\t\t\treturn (...args: unknown[]) => browserReady.then(() => (browserContext!.commands as any)[prop](...args))\n\t\t},\n\t})\n\n\tconst getCurrentTest = () =>\n\t\tvitest?.TestRunner.getCurrentTest() as\n\t\t\t| (ReturnType<VitestModule['TestRunner']['getCurrentTest']> & SnapshotTestMeta)\n\t\t\t| undefined\n\n\t/**\n\t * Resolves once the vitest modules behind `page`, `commands`, and\n\t * `getCurrentTest` are loaded.\n\t *\n\t * `page` and `getCurrentTest` are read synchronously, so hooks that depend on\n\t * them must await this first (#835).\n\t */\n\tconst whenReady = () => ready\n\n\treturn { page, commands, getCurrentTest, whenReady }\n}\n\nconst proxy = createVitestProxy(\n\tisVitestBrowser() ? { loadBrowser: () => import('vitest/browser'), loadVitest: () => import('vitest') } : undefined,\n)\n\nexport const page = proxy.page\nexport const commands = proxy.commands\nexport const getCurrentTest = proxy.getCurrentTest\nexport const whenVitestProxyReady = proxy.whenReady\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport {\n\ttype ComparisonMethod,\n\tmatchImageSnapshotAction,\n\tsuccess,\n\ttype ToMatchImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod>(\n\t/**\n\t * The element or locator to take the snapshot of,\n\t * or the base64 value of the image to compare against.\n\t */\n\tsubject: any,\n\toptions?: ToMatchImageSnapshotOptions<M> | undefined,\n): AsyncExpectationResult {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve(success)\n\t/* v8 ignore end */\n\n\treturn matchImageSnapshotAction(commands, toTaskId(test), subject, options).then(() => success)\n}\n","export function isSnapshotEnabled(tags: string[]) {\n\tconst noSnapshotIndex = tags.lastIndexOf('!snapshot')\n\tconst snapshotIndex = tags.lastIndexOf('snapshot')\n\n\tif (noSnapshotIndex < 0 && snapshotIndex < 0) return false\n\n\treturn noSnapshotIndex < snapshotIndex\n}\n","import type { NamedOrDefaultProjectAnnotations } from 'storybook/internal/types'\nimport { expect } from 'storybook/test'\nimport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { toMatchImageSnapshot } from '../client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from '../client/is_vitest_browser.ts'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nlet extended = false\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\n\t\tif (!isVitestBrowser()) return\n\t\tif (!extended) {\n\t\t\texpect.extend({ toMatchImageSnapshot })\n\t\t\textended = true\n\t\t}\n\t\tconst test = getCurrentTest()\n\n\t\tsetAutoSnapshotOptions({\n\t\t\tenable: isSnapshotEnabled(ctx.tags),\n\t\t\t...ctx.parameters?.snapshot,\n\t\t\ttags: ctx.tags,\n\t\t\t...test?.meta.vis,\n\t\t})\n\t},\n} satisfies NamedOrDefaultProjectAnnotations<any>\n"],"mappings":";;;;;;;;;;;;;;AASA,SAAgB,kBAAkB;AACjC,QAAO,CAAC,CAAE,WAAmB;;;;;ACF9B,SAAgBA,uBACf,SACC;CACD,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,SAAS;;AAGnC,QAAO,6BAA6B,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;;;;;;;ACUvE,SAAgB,kBAAkB,SAAyC;CAC1E,IAAI;CACJ,IAAI;CAEJ,MAAM,eAAe,UAClB,QAAQ,aAAa,CAAC,MAAM,MAAM;AAClC,IAAE,KAAK,OAAO,EAAE,8CAAsB,CAAC;AACvC,mBAAiB;GAChB,GACD,QAAQ,SAAS;CACpB,MAAM,cAAc,UACjB,QAAQ,YAAY,CAAC,MAAM,MAAM;AACjC,WAAS;GACR,GACD,QAAQ,SAAS;CACpB,MAAM,QAAQ,QAAQ,IAAI,CAAC,cAAc,YAAY,CAAC,CAAC,WAAW,OAAU;CAE5E,MAAMC,SAAO,IAAI,MAAmB,EAAE,EAAS,EAC9C,IAAI,SAAS,MAAM;EAClB,MAAM,KAAK,gBAAgB,QAAe;AAC1C,MAAI,SAAS,0BAA0B,MAAM,OAC5C,cAAa;AAEd,SAAO;IAER,CAAC;CAEF,MAAMC,aAAW,IAAI,MAAuB,EAAE,EAAS,EACtD,IAAI,SAAS,MAAM;AAGlB,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,eAAgB,QAAQ,eAAe,SAAiB;AAI5D,UAAQ,GAAG,SAAoB,aAAa,WAAY,eAAgB,SAAiB,MAAM,GAAG,KAAK,CAAC;IAEzG,CAAC;CAEF,MAAMC,yBACL,QAAQ,WAAW,gBAAgB;;;;;;;;CAWpC,MAAM,kBAAkB;AAExB,QAAO;EAAE;EAAM;EAAU;EAAgB;EAAW;;AAGrD,MAAM,QAAQ,kBACb,iBAAiB,GAAG;CAAE,mBAAmB,OAAO;CAAmB,kBAAkB,OAAO;CAAW,GAAG,OAC1G;AAED,MAAa,OAAO,MAAM;AAC1B,MAAa,WAAW,MAAM;AAC9B,MAAa,iBAAiB,MAAM;AACpC,MAAa,uBAAuB,MAAM;;;;ACjF1C,SAAgB,qBAKf,SACA,SACyB;CACzB,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,QAAQ,QAAQ;;AAG1C,QAAO,yBAAyB,UAAU,SAAS,KAAK,EAAE,SAAS,QAAQ,CAAC,WAAW,QAAQ;;;;;ACxBhG,SAAgB,kBAAkB,MAAgB;CACjD,MAAM,kBAAkB,KAAK,YAAY,YAAY;CACrD,MAAM,gBAAgB,KAAK,YAAY,WAAW;AAElD,KAAI,kBAAkB,KAAK,gBAAgB,EAAG,QAAO;AAErD,QAAO,kBAAkB;;;;;ACE1B,IAAI,WAAW;AAEf,MAAa,iBAAiB,EAC7B,WAAW,KAAK;AACf,KAAI,CAAC,iBAAiB,CAAE;AACxB,KAAI,CAAC,UAAU;AACd,SAAO,OAAO,EAAE,sBAAsB,CAAC;AACvC,aAAW;;CAEZ,MAAM,OAAO,gBAAgB;AAE7B,0BAAuB;EACtB,QAAQ,kBAAkB,IAAI,KAAK;EACnC,GAAG,IAAI,YAAY;EACnB,MAAM,IAAI;EACV,GAAG,MAAM,KAAK;EACd,CAAC;GAEH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-addon-vis",
3
- "version": "4.2.4",
3
+ "version": "4.2.6",
4
4
  "description": "Storybook Vitest visual testing addon",
5
5
  "keywords": [
6
6
  "image-snapshot",
@@ -56,48 +56,48 @@
56
56
  "!**/*.{spec,test,unit,accept,integrate,system,perf,stress,stories,study}.*"
57
57
  ],
58
58
  "dependencies": {
59
- "@storybook/icons": "^2.0.0",
60
- "glob": "^13.0.0",
59
+ "@storybook/icons": "^2.1.0",
60
+ "glob": "^13.0.6",
61
61
  "is-ci": "^4.1.0",
62
62
  "memoize": "^11.0.0",
63
63
  "pathe": "^2.0.3",
64
- "type-plus": "8.0.0-beta.8",
65
- "vitest-plugin-vis": "^5.1.1"
64
+ "type-plus": "^7.6.2",
65
+ "vitest-plugin-vis": "^5.1.3"
66
66
  },
67
67
  "devDependencies": {
68
- "@repobuddy/storybook": "^2.28.0",
69
- "@storybook-community/storybook-dark-mode": "^7.1.1",
70
- "@storybook/addon-docs": "^10.4.1",
71
- "@storybook/addon-vitest": "^10.4.1",
72
- "@storybook/react-vite": "^10.4.2",
73
- "@tailwindcss/cli": "^4.1.7",
74
- "@tailwindcss/vite": "^4.1.17",
75
- "@testing-library/react": "^16.0.1",
76
- "@types/react": "^19.2.2",
77
- "@types/react-dom": "^19.2.1",
78
- "@vitejs/plugin-react": "^6.0.0",
79
- "@vitest/browser": "^4.1.4",
80
- "@vitest/browser-playwright": "^4.1.4",
81
- "@vitest/browser-webdriverio": "^4.1.4",
82
- "@vitest/coverage-istanbul": "^4.1.4",
83
- "@vitest/expect": "^4.1.4",
68
+ "@repobuddy/storybook": "^2.32.0",
69
+ "@storybook-community/storybook-dark-mode": "^7.1.3",
70
+ "@storybook/addon-docs": "^10.5.10",
71
+ "@storybook/addon-vitest": "^10.5.10",
72
+ "@storybook/react-vite": "^10.5.10",
73
+ "@tailwindcss/cli": "^4.3.3",
74
+ "@tailwindcss/vite": "^4.3.3",
75
+ "@testing-library/react": "^16.3.2",
76
+ "@types/react": "^19.2.18",
77
+ "@types/react-dom": "^19.2.5",
78
+ "@vitejs/plugin-react": "^6.1.0",
79
+ "@vitest/browser": "^4.1.11",
80
+ "@vitest/browser-playwright": "^4.1.11",
81
+ "@vitest/browser-webdriverio": "^4.1.11",
82
+ "@vitest/coverage-istanbul": "^4.1.11",
83
+ "@vitest/expect": "^4.1.11",
84
84
  "boxen": "^8.0.1",
85
- "cross-env": "^10.0.0",
86
- "dedent": "^1.5.1",
87
- "npm-run-all2": "^9.0.1",
85
+ "cross-env": "^10.1.0",
86
+ "dedent": "^1.7.2",
87
+ "npm-run-all2": "^9.0.3",
88
88
  "playwright": "latest",
89
- "react": "^19.0.0",
90
- "react-dom": "^19.0.0",
91
- "storybook": "^10.4.2",
89
+ "react": "^19.2.8",
90
+ "react-dom": "^19.2.8",
91
+ "storybook": "^10.5.10",
92
92
  "storybook-addon-tag-badges": "^3.1.0",
93
- "tailwindcss": "^4.1.14",
93
+ "tailwindcss": "^4.3.3",
94
94
  "tsdown": "^0.19.0",
95
- "typescript": "^6.0.0",
96
- "vite": "^8.0.0",
97
- "vitest": "^4.1.4",
98
- "vitest-browser-react": "^2.0.2",
95
+ "typescript": "^6.0.3",
96
+ "vite": "^8.2.2",
97
+ "vitest": "^4.1.11",
98
+ "vitest-browser-react": "^2.2.0",
99
99
  "webdriverio": "latest",
100
- "zx": "^8.0.0"
100
+ "zx": "^8.8.5"
101
101
  },
102
102
  "peerDependencies": {
103
103
  "@storybook/addon-vitest": "^10.1.10",
@@ -3,36 +3,90 @@ import type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'
3
3
  import { isVitestBrowser } from './is_vitest_browser.ts'
4
4
  import { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'
5
5
 
6
- let browserContext: Awaited<typeof import('vitest/browser')>
7
- let vitest: Awaited<typeof import('vitest')>
6
+ type BrowserModule = Awaited<typeof import('vitest/browser')>
7
+ type VitestModule = Awaited<typeof import('vitest')>
8
8
 
9
- if (isVitestBrowser()) {
10
- import('vitest/browser').then((m) => {
11
- m.page.extend({ toMatchImageSnapshot })
12
- browserContext = m
9
+ /**
10
+ * How the proxy gets hold of the vitest modules.
11
+ *
12
+ * They are loaded dynamically because this module is also reached from a plain
13
+ * Storybook preview, where `vitest` and `vitest/browser` are not available.
14
+ * Passing `undefined` stands for "not a vitest browser run": nothing is loaded
15
+ * and the proxies stay empty.
16
+ */
17
+ export type VitestProxyLoaders = {
18
+ loadBrowser: () => Promise<BrowserModule>
19
+ loadVitest: () => Promise<VitestModule>
20
+ }
21
+
22
+ /**
23
+ * Build the `page` / `commands` / `getCurrentTest` proxies over `loaders`.
24
+ *
25
+ * Exported for tests: it is the only way to observe the window between module
26
+ * load and the dynamic imports settling.
27
+ */
28
+ export function createVitestProxy(loaders: VitestProxyLoaders | undefined) {
29
+ let browserContext: BrowserModule | undefined
30
+ let vitest: VitestModule | undefined
31
+
32
+ const browserReady = loaders
33
+ ? loaders.loadBrowser().then((m) => {
34
+ m.page.extend({ toMatchImageSnapshot })
35
+ browserContext = m
36
+ })
37
+ : Promise.resolve()
38
+ const vitestReady = loaders
39
+ ? loaders.loadVitest().then((m) => {
40
+ vitest = m
41
+ })
42
+ : Promise.resolve()
43
+ const ready = Promise.all([browserReady, vitestReady]).then(() => undefined)
44
+
45
+ const page = new Proxy<BrowserPage>({} as any, {
46
+ get(_target, prop) {
47
+ const r = (browserContext?.page as any)?.[prop]
48
+ if (prop === 'toMatchImageSnapshot' && r === undefined) {
49
+ return () => {}
50
+ }
51
+ return r
52
+ },
13
53
  })
14
- import('vitest').then((m) => {
15
- vitest = m
54
+
55
+ const commands = new Proxy<BrowserCommands>({} as any, {
56
+ get(_target, prop) {
57
+ // Outside a vitest browser run there is nothing to wait for: keep
58
+ // yielding `undefined` so the addon guards stay in charge (#829).
59
+ if (!loaders) return undefined
60
+ if (browserContext) return (browserContext.commands as any)[prop]
61
+ // The import has not settled yet (#835). Commands are async RPC calls,
62
+ // so hand back a function that waits for the module instead of
63
+ // `undefined`, which fails as `<command> is not a function`.
64
+ return (...args: unknown[]) => browserReady.then(() => (browserContext!.commands as any)[prop](...args))
65
+ },
16
66
  })
67
+
68
+ const getCurrentTest = () =>
69
+ vitest?.TestRunner.getCurrentTest() as
70
+ | (ReturnType<VitestModule['TestRunner']['getCurrentTest']> & SnapshotTestMeta)
71
+ | undefined
72
+
73
+ /**
74
+ * Resolves once the vitest modules behind `page`, `commands`, and
75
+ * `getCurrentTest` are loaded.
76
+ *
77
+ * `page` and `getCurrentTest` are read synchronously, so hooks that depend on
78
+ * them must await this first (#835).
79
+ */
80
+ const whenReady = () => ready
81
+
82
+ return { page, commands, getCurrentTest, whenReady }
17
83
  }
18
84
 
19
- export const page = new Proxy<BrowserPage>({} as any, {
20
- get(_target, prop) {
21
- const r = (browserContext?.page as any)?.[prop]
22
- if (prop === 'toMatchImageSnapshot' && r === undefined) {
23
- return () => {}
24
- }
25
- return r
26
- },
27
- })
28
-
29
- export const commands = new Proxy<BrowserCommands>({} as any, {
30
- get(_target, prop) {
31
- return (browserContext?.commands as any)?.[prop]
32
- },
33
- })
34
-
35
- export const getCurrentTest = () =>
36
- vitest?.TestRunner.getCurrentTest() as
37
- | (ReturnType<typeof vitest.TestRunner.getCurrentTest> & SnapshotTestMeta)
38
- | undefined
85
+ const proxy = createVitestProxy(
86
+ isVitestBrowser() ? { loadBrowser: () => import('vitest/browser'), loadVitest: () => import('vitest') } : undefined,
87
+ )
88
+
89
+ export const page = proxy.page
90
+ export const commands = proxy.commands
91
+ export const getCurrentTest = proxy.getCurrentTest
92
+ export const whenVitestProxyReady = proxy.whenReady
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ import type { SetupVisOptions } from 'vitest-plugin-vis'
7
7
  import { autoSnapshotMatcher, setAutoSnapshotOptions } from 'vitest-plugin-vis/client-api'
8
8
  import { toMatchImageSnapshot } from './client/expect/to_match_image_snapshot.ts'
9
9
  import { isVitestBrowser } from './client/is_vitest_browser.ts'
10
- import { commands, page } from './client/vitest_proxy.ts'
10
+ import { commands, page, whenVitestProxyReady } from './client/vitest_proxy.ts'
11
11
  import { visAnnotations } from './preview/vis_annotation.ts'
12
12
 
13
13
  // Register at module load time so it's available in Storybook dev mode.
@@ -28,6 +28,9 @@ export default (options: SetupVisOptions<{ tags: string[] }> = { auto: false })
28
28
  tags: options.auto === true ? ['snapshot'] : [],
29
29
  async beforeAll() {
30
30
  if (!isVitestBrowser()) return
31
+ // `page` and `getCurrentTest` come from a dynamic import; the hooks that
32
+ // follow read them synchronously, so wait for it here (#835).
33
+ await whenVitestProxyReady()
31
34
  matcher = autoSnapshotMatcher(commands, expect)
32
35
  const suiteDefaults =
33
36
  options?.createMissingBaseline !== undefined
@@ -1 +0,0 @@
1
- {"version":3,"file":"vis_annotation-CZE4YN-u.mjs","names":["toMatchImageSnapshot"],"sources":["../src/client/is_vitest_browser.ts","../src/client/page/to_match_image_snapshot.ts","../src/client/vitest_proxy.ts","../src/client/expect/to_match_image_snapshot.ts","../src/client/storybook/tags.ts","../src/preview/vis_annotation.ts"],"sourcesContent":["/**\n * Whether the code is running inside a Vitest browser-mode run.\n *\n * This is the signal the addon actually depends on: `commands` and `page` in\n * `vitest_proxy.ts` are only populated when `__vitest_browser__` is set, so any\n * broader \"am I under test\" check (such as one matching a `HeadlessChrome` user\n * agent) lets a plain headless browser reach the snapshot setup and fail on the\n * empty proxy with `commands.setupVisSuite is not a function`.\n */\nexport function isVitestBrowser() {\n\treturn !!(globalThis as any).__vitest_browser__\n}\n","import {\n\ttype ComparisonMethod,\n\tmatchPageImageSnapshotAction,\n\ttype ToMatchPageImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod = 'pixel'>(\n\toptions?: ToMatchPageImageSnapshotOptions<M> | undefined,\n) {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve()\n\t/* v8 ignore end */\n\n\treturn matchPageImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type { BrowserCommands, BrowserPage } from 'vitest/browser'\nimport type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'\nimport { isVitestBrowser } from './is_vitest_browser.ts'\nimport { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'\n\nlet browserContext: Awaited<typeof import('vitest/browser')>\nlet vitest: Awaited<typeof import('vitest')>\n\nif (isVitestBrowser()) {\n\timport('vitest/browser').then((m) => {\n\t\tm.page.extend({ toMatchImageSnapshot })\n\t\tbrowserContext = m\n\t})\n\timport('vitest').then((m) => {\n\t\tvitest = m\n\t})\n}\n\nexport const page = new Proxy<BrowserPage>({} as any, {\n\tget(_target, prop) {\n\t\tconst r = (browserContext?.page as any)?.[prop]\n\t\tif (prop === 'toMatchImageSnapshot' && r === undefined) {\n\t\t\treturn () => {}\n\t\t}\n\t\treturn r\n\t},\n})\n\nexport const commands = new Proxy<BrowserCommands>({} as any, {\n\tget(_target, prop) {\n\t\treturn (browserContext?.commands as any)?.[prop]\n\t},\n})\n\nexport const getCurrentTest = () =>\n\tvitest?.TestRunner.getCurrentTest() as\n\t\t| (ReturnType<typeof vitest.TestRunner.getCurrentTest> & SnapshotTestMeta)\n\t\t| undefined\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport {\n\ttype ComparisonMethod,\n\tmatchImageSnapshotAction,\n\tsuccess,\n\ttype ToMatchImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod>(\n\t/**\n\t * The element or locator to take the snapshot of,\n\t * or the base64 value of the image to compare against.\n\t */\n\tsubject: any,\n\toptions?: ToMatchImageSnapshotOptions<M> | undefined,\n): AsyncExpectationResult {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve(success)\n\t/* v8 ignore end */\n\n\treturn matchImageSnapshotAction(commands, toTaskId(test), subject, options).then(() => success)\n}\n","export function isSnapshotEnabled(tags: string[]) {\n\tconst noSnapshotIndex = tags.lastIndexOf('!snapshot')\n\tconst snapshotIndex = tags.lastIndexOf('snapshot')\n\n\tif (noSnapshotIndex < 0 && snapshotIndex < 0) return false\n\n\treturn noSnapshotIndex < snapshotIndex\n}\n","import type { NamedOrDefaultProjectAnnotations } from 'storybook/internal/types'\nimport { expect } from 'storybook/test'\nimport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { toMatchImageSnapshot } from '../client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from '../client/is_vitest_browser.ts'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nlet extended = false\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\n\t\tif (!isVitestBrowser()) return\n\t\tif (!extended) {\n\t\t\texpect.extend({ toMatchImageSnapshot })\n\t\t\textended = true\n\t\t}\n\t\tconst test = getCurrentTest()\n\n\t\tsetAutoSnapshotOptions({\n\t\t\tenable: isSnapshotEnabled(ctx.tags),\n\t\t\t...ctx.parameters?.snapshot,\n\t\t\ttags: ctx.tags,\n\t\t\t...test?.meta.vis,\n\t\t})\n\t},\n} satisfies NamedOrDefaultProjectAnnotations<any>\n"],"mappings":";;;;;;;;;;;;;;AASA,SAAgB,kBAAkB;AACjC,QAAO,CAAC,CAAE,WAAmB;;;;;ACF9B,SAAgBA,uBACf,SACC;CACD,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,SAAS;;AAGnC,QAAO,6BAA6B,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;ACZvE,IAAI;AACJ,IAAI;AAEJ,IAAI,iBAAiB,EAAE;AACtB,QAAO,kBAAkB,MAAM,MAAM;AACpC,IAAE,KAAK,OAAO,EAAE,8CAAsB,CAAC;AACvC,mBAAiB;GAChB;AACF,QAAO,UAAU,MAAM,MAAM;AAC5B,WAAS;GACR;;AAGH,MAAa,OAAO,IAAI,MAAmB,EAAE,EAAS,EACrD,IAAI,SAAS,MAAM;CAClB,MAAM,KAAK,gBAAgB,QAAe;AAC1C,KAAI,SAAS,0BAA0B,MAAM,OAC5C,cAAa;AAEd,QAAO;GAER,CAAC;AAEF,MAAa,WAAW,IAAI,MAAuB,EAAE,EAAS,EAC7D,IAAI,SAAS,MAAM;AAClB,SAAQ,gBAAgB,YAAmB;GAE5C,CAAC;AAEF,MAAa,uBACZ,QAAQ,WAAW,gBAAgB;;;;ACzBpC,SAAgB,qBAKf,SACA,SACyB;CACzB,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,QAAQ,QAAQ;;AAG1C,QAAO,yBAAyB,UAAU,SAAS,KAAK,EAAE,SAAS,QAAQ,CAAC,WAAW,QAAQ;;;;;ACxBhG,SAAgB,kBAAkB,MAAgB;CACjD,MAAM,kBAAkB,KAAK,YAAY,YAAY;CACrD,MAAM,gBAAgB,KAAK,YAAY,WAAW;AAElD,KAAI,kBAAkB,KAAK,gBAAgB,EAAG,QAAO;AAErD,QAAO,kBAAkB;;;;;ACE1B,IAAI,WAAW;AAEf,MAAa,iBAAiB,EAC7B,WAAW,KAAK;AACf,KAAI,CAAC,iBAAiB,CAAE;AACxB,KAAI,CAAC,UAAU;AACd,SAAO,OAAO,EAAE,sBAAsB,CAAC;AACvC,aAAW;;CAEZ,MAAM,OAAO,gBAAgB;AAE7B,0BAAuB;EACtB,QAAQ,kBAAkB,IAAI,KAAK;EACnC,GAAG,IAAI,YAAY;EACnB,MAAM,IAAI;EACV,GAAG,MAAM,KAAK;EACd,CAAC;GAEH"}