storybook-addon-vis 3.1.5 → 4.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.
Files changed (69) hide show
  1. package/dist/{contants-DcocjING.mjs → exports/constants-D_WcloLE.mjs} +2 -2
  2. package/dist/exports/constants-D_WcloLE.mjs.map +1 -0
  3. package/dist/exports/matcher.d.mts +1 -0
  4. package/dist/{node.d.mts → exports/node.d.mts} +1 -1
  5. package/dist/exports/node.d.mts.map +1 -0
  6. package/dist/exports/node.mjs.map +1 -0
  7. package/dist/{preset.d.mts → exports/preset.d.mts} +2 -2
  8. package/dist/exports/preset.d.mts.map +1 -0
  9. package/dist/{preset.mjs → exports/preset.mjs} +14 -8
  10. package/dist/exports/preset.mjs.map +1 -0
  11. package/dist/{types-BG2k_RS_.d.mts → exports/types-CuNXsk6J.d.mts} +8 -1
  12. package/dist/exports/types-CuNXsk6J.d.mts.map +1 -0
  13. package/dist/exports/vitest-plugin.d.mts.map +1 -0
  14. package/dist/{vitest-plugin.mjs → exports/vitest-plugin.mjs} +2 -2
  15. package/dist/exports/vitest-plugin.mjs.map +1 -0
  16. package/dist/{vitest-setup.d.ts → exports/vitest-setup.d.mts} +3 -3
  17. package/dist/exports/vitest-setup.d.mts.map +1 -0
  18. package/dist/{vitest-setup.js → exports/vitest-setup.mjs} +3 -3
  19. package/dist/exports/vitest-setup.mjs.map +1 -0
  20. package/dist/{global_matcher_augment-CYxLwns2.d.ts → global_matcher_augment-B1plNA_9.d.mts} +1 -1
  21. package/dist/global_matcher_augment-B1plNA_9.d.mts.map +1 -0
  22. package/dist/{index.d.ts → index.d.mts} +4 -3
  23. package/dist/index.d.mts.map +1 -0
  24. package/dist/{index.js → index.mjs} +6 -5
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/manager.js +10 -7
  27. package/dist/manager.js.map +1 -1
  28. package/dist/{vis_annotation-DqZTkmEN.js → vis_annotation-B5Jl50Wp.mjs} +5 -5
  29. package/dist/vis_annotation-B5Jl50Wp.mjs.map +1 -0
  30. package/manager.js +2 -1
  31. package/package.json +30 -40
  32. package/preset.js +2 -1
  33. package/readme.md +2 -0
  34. package/src/client/vitest_proxy.ts +6 -4
  35. package/src/components/vis_panel.tsx +15 -12
  36. package/src/{manager.tsx → exports/manager.tsx} +3 -3
  37. package/src/exports/matcher.ts +1 -0
  38. package/src/exports/node.ts +2 -0
  39. package/src/{preset.ts → exports/preset.ts} +4 -4
  40. package/src/exports/vitest-plugin.ts +2 -0
  41. package/src/{vitest-setup.ts → exports/vitest-setup.ts} +4 -4
  42. package/src/index.ts +12 -5
  43. package/src/overview.mdx +22 -1
  44. package/src/server/create_storybook_vis_server.ts +8 -1
  45. package/src/server/types.ts +7 -0
  46. package/src/vitest-plugin/storybook_vis.ts +2 -2
  47. package/dist/contants-DcocjING.mjs.map +0 -1
  48. package/dist/global_matcher_augment-CYxLwns2.d.ts.map +0 -1
  49. package/dist/index.d.ts.map +0 -1
  50. package/dist/index.js.map +0 -1
  51. package/dist/matcher.d.ts +0 -1
  52. package/dist/node.d.mts.map +0 -1
  53. package/dist/node.mjs.map +0 -1
  54. package/dist/preset.d.mts.map +0 -1
  55. package/dist/preset.mjs.map +0 -1
  56. package/dist/types-BG2k_RS_.d.mts.map +0 -1
  57. package/dist/vis_annotation-DqZTkmEN.js.map +0 -1
  58. package/dist/vitest-plugin.d.mts.map +0 -1
  59. package/dist/vitest-plugin.mjs.map +0 -1
  60. package/dist/vitest-setup.d.ts.map +0 -1
  61. package/dist/vitest-setup.js.map +0 -1
  62. package/src/matcher.ts +0 -1
  63. package/src/node.ts +0 -2
  64. package/src/testing.ts +0 -1
  65. package/src/vitest-plugin.ts +0 -2
  66. /package/dist/{matcher.js → exports/matcher.mjs} +0 -0
  67. /package/dist/{node.mjs → exports/node.mjs} +0 -0
  68. /package/dist/{vitest-plugin.d.mts → exports/vitest-plugin.d.mts} +0 -0
  69. /package/src/shared/{contants.ts → constants.ts} +0 -0
@@ -1,7 +1,7 @@
1
- //#region src/shared/contants.ts
1
+ //#region src/shared/constants.ts
2
2
  const NAME = "storybook-addon-vis";
3
3
  const VIS_PANEL_ID = `${NAME}/vis_panel`;
4
4
 
5
5
  //#endregion
6
6
  export { NAME as t };
7
- //# sourceMappingURL=contants-DcocjING.mjs.map
7
+ //# sourceMappingURL=constants-D_WcloLE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants-D_WcloLE.mjs","names":[],"sources":["../../src/shared/constants.ts"],"sourcesContent":["export const NAME = 'storybook-addon-vis'\nexport const VIS_PANEL_ID = `${NAME}/vis_panel`\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,eAAe,GAAG,KAAK"}
@@ -0,0 +1 @@
1
+ import "../global_matcher_augment-B1plNA_9.mjs";
@@ -1,4 +1,4 @@
1
- import { t as StorybookVisOptions } from "./types-BG2k_RS_.mjs";
1
+ import { t as StorybookVisOptions } from "./types-CuNXsk6J.mjs";
2
2
 
3
3
  //#region src/node/define_storybook_vis.d.ts
4
4
 
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.mts","names":[],"sources":["../../src/node/define_storybook_vis.ts","../../src/node/define_storybook_vis_options.ts"],"sourcesContent":[],"mappings":";;;;;;AA+BA;AAgCA;;;;AC1DA;;;;;;;;;;;;;;;;;;;;;iBD0BgB,kBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCA,kBAAA,UAA4B;;WAA+C;;;;;;AAhC3F;AAgCgB,iBC1DA,yBAAA,CD0D4B,OAA+C,EC1DxC,mBD0D2D,CAAA,EC1DxC,mBD0DwC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.mjs","names":[],"sources":["../../src/node/define_storybook_vis.ts","../../src/node/define_storybook_vis_options.ts"],"sourcesContent":["import { dirname } from 'node:path'\nimport type { StorybookVisOptions } from '../server/types.ts'\n\n/**\n * Defines the Storybook Visual Testing addon configuration.\n *\n * When called without options, returns the package directory name as a string.\n * When called with options, returns an object containing both the package name and the provided options.\n *\n * @returns When called without options, returns the package directory path as a string.\n *\n * @example\n * ```ts\n * // Without options - returns just the package name\n * const addonName = defineStorybookVis()\n * // Returns: string (package directory path)\n * ```\n *\n * @example\n * ```ts\n * // With options - returns object with name and options\n * const addonConfig = defineStorybookVis({\n * visProjects: [\n * {\n * snapshotRootDir: '__vis__/linux',\n * },\n * ],\n * })\n * // Returns: { name: string, options: StorybookVisOptions }\n * ```\n */\nexport function defineStorybookVis(): string\n/**\n * Defines the Storybook Visual Testing addon configuration with options.\n *\n * @param options - Configuration options for visual testing suites in Storybook.\n * @param options.visProjects - Array of visual testing project configurations.\n * @param options.visProjects[].snapshotRootDir - Root directory for storing snapshots. Can be a string path or a function that returns a path based on CI and platform context.\n * @param options.visProjects[].snapshotSubpath - Optional function to customize the snapshot subdirectory path.\n *\n * @returns An object containing the package name and the provided options.\n *\n * @example\n * ```ts\n * // In .storybook/main.ts\n * import { defineStorybookVis } from 'storybook-addon-vis/node'\n *\n * export default {\n * addons: [\n * defineStorybookVis({\n * visProjects: [\n * {\n * snapshotRootDir: '__vis__/linux',\n * },\n * {\n * snapshotRootDir: '__vis__/local',\n * },\n * ],\n * }),\n * ],\n * }\n * ```\n */\nexport function defineStorybookVis(options: StorybookVisOptions): { name: string; options: StorybookVisOptions }\nexport function defineStorybookVis(options?: StorybookVisOptions | undefined) {\n\tconst name = dirname(import.meta.resolve('storybook-addon-vis', 'package.json'))\n\treturn !options ? name : { name, options }\n}\n","import type { StorybookVisOptions } from '../server/types.ts'\n\n/**\n * Define options for Storybook Visual Testing addon.\n */\nexport function defineStorybookVisOptions(options: StorybookVisOptions) {\n\treturn options\n}\n"],"mappings":";;;AAgEA,SAAgB,mBAAmB,SAA2C;CAC7E,MAAM,OAAO,QAAQ,OAAO,KAAK,QAAQ,uBAAuB,eAAe,CAAC;AAChF,QAAO,CAAC,UAAU,OAAO;EAAE;EAAM;EAAS;;;;;;;;AC7D3C,SAAgB,0BAA0B,SAA8B;AACvE,QAAO"}
@@ -1,7 +1,7 @@
1
- import { t as StorybookVisOptions } from "./types-BG2k_RS_.mjs";
1
+ import { t as StorybookVisOptions } from "./types-CuNXsk6J.mjs";
2
2
  import { Channel } from "storybook/internal/channels";
3
3
 
4
- //#region src/preset.d.ts
4
+ //#region src/exports/preset.d.ts
5
5
  declare const experimental_serverChannel: (channel: Channel, options: StorybookVisOptions) => Promise<Channel>;
6
6
  //#endregion
7
7
  export { experimental_serverChannel };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.d.mts","names":[],"sources":["../../src/exports/preset.ts"],"sourcesContent":[],"mappings":";;;;cAMa,sCAA6C,kBAAkB,wBAAmB,QAAA"}
@@ -1,11 +1,11 @@
1
- import { t as NAME } from "./contants-DcocjING.mjs";
1
+ import { t as NAME } from "./constants-D_WcloLE.mjs";
2
2
  import { globSync } from "glob";
3
3
  import ci from "is-ci";
4
4
  import memoize from "memoize";
5
5
  import { readFileSync } from "node:fs";
6
6
  import { platform } from "node:process";
7
7
  import { basename, resolve } from "pathe";
8
- import { BASELINE_DIR, DIFF_DIR, SNAPSHOT_ROOT_DIR, getSnapshotRootDir, trimCommonFolder } from "vitest-plugin-vis/server-utils";
8
+ import { BASELINE_DIR, DIFF_DIR, SNAPSHOT_ROOT_DIR, getSnapshotRootDir, resolveSnapshotSubpathWithinLimits, trimCommonFolder } from "vitest-plugin-vis/server-utils";
9
9
 
10
10
  //#region src/server/create_storybook_vis_server.ts
11
11
  function createStorybookVisServer(options) {
@@ -14,12 +14,18 @@ function createStorybookVisServer(options) {
14
14
  options,
15
15
  async getImageSnapshotResults(name, importPath) {
16
16
  return visSuites.map((suite) => {
17
+ const snapshotRootDir = typeof suite.snapshotRootDir === "string" ? suite.snapshotRootDir : typeof suite.snapshotRootDir === "function" ? memoize(suite.snapshotRootDir)({
18
+ ci,
19
+ platform
20
+ }) : memoize(getSnapshotRootDir)(SNAPSHOT_ROOT_DIR);
21
+ const snapshotSubpathRaw = (typeof suite.snapshotSubpath === "function" ? memoize(suite.snapshotSubpath) : memoize(({ subpath }) => trimCommonFolder(subpath.startsWith("./") ? subpath.slice(2) : subpath)))({ subpath: importPath });
17
22
  return {
18
- snapshotRootDir: typeof suite.snapshotRootDir === "string" ? suite.snapshotRootDir : typeof suite.snapshotRootDir === "function" ? memoize(suite.snapshotRootDir)({
19
- ci,
20
- platform
21
- }) : memoize(getSnapshotRootDir)(SNAPSHOT_ROOT_DIR),
22
- snapshotSubpath: (typeof suite.snapshotSubpath === "function" ? memoize(suite.snapshotSubpath) : memoize(({ subpath }) => trimCommonFolder(subpath.startsWith("./") ? subpath.slice(2) : subpath)))({ subpath: importPath })
23
+ snapshotRootDir,
24
+ snapshotSubpath: resolveSnapshotSubpathWithinLimits({
25
+ snapshotBaselineRootAbs: resolve(snapshotRootDir, BASELINE_DIR),
26
+ rawSnapshotSubpath: snapshotSubpathRaw,
27
+ shortenLongSnapshotPaths: suite.shortenLongSnapshotPaths === true
28
+ })
23
29
  };
24
30
  }).flatMap(({ snapshotRootDir, snapshotSubpath }) => {
25
31
  const taskId = name.replace(/[^a-z0-9]/gi, "-").toLowerCase();
@@ -50,7 +56,7 @@ const IMAGE_SNAPSHOT_RESULTS_REQUEST = "IMAGE_SNAPSHOT_RESULTS_REQUEST";
50
56
  const IMAGE_SNAPSHOT_RESULTS_RESPONSE = "IMAGE_SNAPSHOT_RESULTS_RESPONSE";
51
57
 
52
58
  //#endregion
53
- //#region src/preset.ts
59
+ //#region src/exports/preset.ts
54
60
  const experimental_serverChannel = async (channel, options) => {
55
61
  const server = createStorybookVisServer(options);
56
62
  channel.on(NAME, async (event) => {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.mjs","names":[],"sources":["../../src/server/create_storybook_vis_server.ts","../../src/shared/events.ts","../../src/exports/preset.ts"],"sourcesContent":["import { globSync } from 'glob'\nimport ci from 'is-ci'\nimport memoize from 'memoize'\nimport { readFileSync } from 'node:fs'\nimport { platform } from 'node:process'\nimport { basename, resolve } from 'pathe'\nimport {\n\tBASELINE_DIR,\n\tDIFF_DIR,\n\tgetSnapshotRootDir,\n\tresolveSnapshotSubpathWithinLimits,\n\tSNAPSHOT_ROOT_DIR,\n\ttrimCommonFolder,\n} from 'vitest-plugin-vis/server-utils'\nimport type { StorybookVisOptions } from './types.ts'\n\nexport function createStorybookVisServer(options: StorybookVisOptions) {\n\tconst visSuites = options.visProjects ?? [{}]\n\treturn {\n\t\toptions,\n\t\tasync getImageSnapshotResults(name: string, importPath: string) {\n\t\t\treturn visSuites\n\t\t\t\t.map((suite) => {\n\t\t\t\t\tconst snapshotRootDir =\n\t\t\t\t\t\ttypeof suite.snapshotRootDir === 'string'\n\t\t\t\t\t\t\t? suite.snapshotRootDir\n\t\t\t\t\t\t\t: typeof suite.snapshotRootDir === 'function'\n\t\t\t\t\t\t\t\t? memoize(suite.snapshotRootDir)({\n\t\t\t\t\t\t\t\t\t\tci,\n\t\t\t\t\t\t\t\t\t\tplatform,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: memoize(getSnapshotRootDir)(SNAPSHOT_ROOT_DIR)\n\n\t\t\t\t\tconst snapshotSubpathFn =\n\t\t\t\t\t\ttypeof suite.snapshotSubpath === 'function'\n\t\t\t\t\t\t\t? memoize(suite.snapshotSubpath)\n\t\t\t\t\t\t\t: memoize(({ subpath }: { subpath: string }) =>\n\t\t\t\t\t\t\t\t\ttrimCommonFolder(subpath.startsWith('./') ? subpath.slice(2) : subpath),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\tconst snapshotSubpathRaw = snapshotSubpathFn({ subpath: importPath })\n\t\t\t\t\tconst snapshotBaselineRootAbs = resolve(snapshotRootDir, BASELINE_DIR)\n\t\t\t\t\tconst snapshotSubpath = resolveSnapshotSubpathWithinLimits({\n\t\t\t\t\t\tsnapshotBaselineRootAbs,\n\t\t\t\t\t\trawSnapshotSubpath: snapshotSubpathRaw,\n\t\t\t\t\t\tshortenLongSnapshotPaths: suite.shortenLongSnapshotPaths === true,\n\t\t\t\t\t})\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsnapshotRootDir,\n\t\t\t\t\t\tsnapshotSubpath,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.flatMap(({ snapshotRootDir, snapshotSubpath }) => {\n\t\t\t\t\tconst taskId = name.replace(/[^a-z0-9]/gi, '-').toLowerCase()\n\t\t\t\t\tconst taskGlob = `${taskId}-*.png`\n\t\t\t\t\tconst baselineGlob = resolve(snapshotRootDir, BASELINE_DIR, snapshotSubpath, taskGlob)\n\t\t\t\t\tconst diffGlob = resolve(snapshotRootDir, DIFF_DIR, snapshotSubpath, taskGlob)\n\n\t\t\t\t\tconst taskIdRegex = new RegExp(`${taskId}-[^-]*.png$`)\n\t\t\t\t\tconst baselineFiles = globSync(baselineGlob).filter((filePath) => taskIdRegex.test(filePath))\n\t\t\t\t\tconst diffFiles = globSync(diffGlob).filter((filePath) => taskIdRegex.test(filePath))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...baselineFiles.map((filePath) => mapFileToResult(filePath, snapshotRootDir, 'baseline')),\n\t\t\t\t\t\t...diffFiles.map((filePath) => mapFileToResult(filePath, snapshotRootDir, 'diff')),\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t},\n\t}\n}\n\nfunction mapFileToResult(filePath: string, snapshotRootDir: string, type: 'baseline' | 'diff') {\n\treturn {\n\t\tfilePath,\n\t\tfileName: basename(filePath),\n\t\tsnapshotRootDir,\n\t\ttype,\n\t\tbase64: readFileSync(filePath, 'base64'),\n\t}\n}\n","export type VisEvent = ImageSnapshotResultsRequest | ImageSnapshotResultsResponse\n\nexport const IMAGE_SNAPSHOT_RESULTS_REQUEST = 'IMAGE_SNAPSHOT_RESULTS_REQUEST'\nexport const IMAGE_SNAPSHOT_RESULTS_RESPONSE = 'IMAGE_SNAPSHOT_RESULTS_RESPONSE'\n\nexport function requestImageSnapshotResults({ name, importPath }: { name: string; importPath: string }) {\n\treturn {\n\t\ttype: IMAGE_SNAPSHOT_RESULTS_REQUEST,\n\t\tname,\n\t\timportPath,\n\t}\n}\n\nexport type ImageSnapshotResultsRequest = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_REQUEST\n\tname: string\n\timportPath: string\n}\n\nexport type ImageSnapshotResultsResponse = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_RESPONSE\n\tname: string\n\timportPath: string\n\tresults: ImageSnapshotResults[]\n}\n\nexport type ImageSnapshotResults = {\n\tfilePath: string\n\tfileName: string\n\tsnapshotRootDir: string\n\ttype: 'baseline' | 'diff' | 'result'\n\tbase64: string\n}\n","import type { Channel } from 'storybook/internal/channels'\nimport { createStorybookVisServer } from '../server/create_storybook_vis_server.ts'\nimport type { StorybookVisOptions } from '../server/types.ts'\nimport { NAME } from '../shared/constants.ts'\nimport { IMAGE_SNAPSHOT_RESULTS_REQUEST, IMAGE_SNAPSHOT_RESULTS_RESPONSE, type VisEvent } from '../shared/events.ts'\n\nexport const experimental_serverChannel = async (channel: Channel, options: StorybookVisOptions) => {\n\tconst server = createStorybookVisServer(options)\n\n\tchannel.on(NAME, async (event: VisEvent) => {\n\t\tif (event.type === IMAGE_SNAPSHOT_RESULTS_REQUEST) {\n\t\t\tconst results = await server.getImageSnapshotResults(event.name, event.importPath)\n\t\t\tchannel.emit(NAME, {\n\t\t\t\ttype: IMAGE_SNAPSHOT_RESULTS_RESPONSE,\n\t\t\t\tname: event.name,\n\t\t\t\timportPath: event.importPath,\n\t\t\t\tresults,\n\t\t\t})\n\t\t}\n\t})\n\n\treturn channel\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAgB,yBAAyB,SAA8B;CACtE,MAAM,YAAY,QAAQ,eAAe,CAAC,EAAE,CAAC;AAC7C,QAAO;EACN;EACA,MAAM,wBAAwB,MAAc,YAAoB;AAC/D,UAAO,UACL,KAAK,UAAU;IACf,MAAM,kBACL,OAAO,MAAM,oBAAoB,WAC9B,MAAM,kBACN,OAAO,MAAM,oBAAoB,aAChC,QAAQ,MAAM,gBAAgB,CAAC;KAC/B;KACA;KACA,CAAC,GACD,QAAQ,mBAAmB,CAAC,kBAAkB;IAQnD,MAAM,sBALL,OAAO,MAAM,oBAAoB,aAC9B,QAAQ,MAAM,gBAAgB,GAC9B,SAAS,EAAE,cACX,iBAAiB,QAAQ,WAAW,KAAK,GAAG,QAAQ,MAAM,EAAE,GAAG,QAAQ,CACvE,EACyC,EAAE,SAAS,YAAY,CAAC;AAOrE,WAAO;KACN;KACA,iBAPuB,mCAAmC;MAC1D,yBAF+B,QAAQ,iBAAiB,aAAa;MAGrE,oBAAoB;MACpB,0BAA0B,MAAM,6BAA6B;MAC7D,CAAC;KAID;KACA,CACD,SAAS,EAAE,iBAAiB,sBAAsB;IAClD,MAAM,SAAS,KAAK,QAAQ,eAAe,IAAI,CAAC,aAAa;IAC7D,MAAM,WAAW,GAAG,OAAO;IAC3B,MAAM,eAAe,QAAQ,iBAAiB,cAAc,iBAAiB,SAAS;IACtF,MAAM,WAAW,QAAQ,iBAAiB,UAAU,iBAAiB,SAAS;IAE9E,MAAM,8BAAc,IAAI,OAAO,GAAG,OAAO,aAAa;IACtD,MAAM,gBAAgB,SAAS,aAAa,CAAC,QAAQ,aAAa,YAAY,KAAK,SAAS,CAAC;IAC7F,MAAM,YAAY,SAAS,SAAS,CAAC,QAAQ,aAAa,YAAY,KAAK,SAAS,CAAC;AACrF,WAAO,CACN,GAAG,cAAc,KAAK,aAAa,gBAAgB,UAAU,iBAAiB,WAAW,CAAC,EAC1F,GAAG,UAAU,KAAK,aAAa,gBAAgB,UAAU,iBAAiB,OAAO,CAAC,CAClF;KACA;;EAEJ;;AAGF,SAAS,gBAAgB,UAAkB,iBAAyB,MAA2B;AAC9F,QAAO;EACN;EACA,UAAU,SAAS,SAAS;EAC5B;EACA;EACA,QAAQ,aAAa,UAAU,SAAS;EACxC;;;;;AC1EF,MAAa,iCAAiC;AAC9C,MAAa,kCAAkC;;;;ACG/C,MAAa,6BAA6B,OAAO,SAAkB,YAAiC;CACnG,MAAM,SAAS,yBAAyB,QAAQ;AAEhD,SAAQ,GAAG,MAAM,OAAO,UAAoB;AAC3C,MAAI,MAAM,SAAS,gCAAgC;GAClD,MAAM,UAAU,MAAM,OAAO,wBAAwB,MAAM,MAAM,MAAM,WAAW;AAClF,WAAQ,KAAK,MAAM;IAClB,MAAM;IACN,MAAM,MAAM;IACZ,YAAY,MAAM;IAClB;IACA,CAAC;;GAEF;AAEF,QAAO"}
@@ -15,8 +15,15 @@ type StorybookVisOptions = {
15
15
  snapshotSubpath?: ((options: {
16
16
  subpath: string;
17
17
  }) => string) | undefined;
18
+ /**
19
+ * Match Vitest `vis({ shortenLongSnapshotPaths })`. When true, uses the same path rules as
20
+ * the `vitest-plugin-vis`: paths are shortened when their absolute path would exceed safe limits).
21
+ *
22
+ * @default false
23
+ */
24
+ shortenLongSnapshotPaths?: boolean | undefined;
18
25
  }>;
19
26
  };
20
27
  //#endregion
21
28
  export { StorybookVisOptions as t };
22
- //# sourceMappingURL=types-BG2k_RS_.d.mts.map
29
+ //# sourceMappingURL=types-CuNXsk6J.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-CuNXsk6J.d.mts","names":[],"sources":["../../src/server/types.ts"],"sourcesContent":[],"mappings":";;AAOA;;;;;;KAAY,mBAAA;eACE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-plugin.d.mts","names":[],"sources":["../../src/vitest-plugin/storybook_vis.ts"],"sourcesContent":[],"mappings":";;;;;AAOuC,iBAAvB,YAAuB,CAAA,UAAA,gBAAA,CAAA,CAAA,OAAA,CAAA,EAA4B,IAA5B,CAAiC,UAAjC,CAA4C,CAA5C,CAAA,EAAA,QAAA,CAAA,GAAA,SAAA,CAAA,EAAA,GAAA"}
@@ -1,4 +1,4 @@
1
- import { t as NAME } from "./contants-DcocjING.mjs";
1
+ import { t as NAME } from "./constants-D_WcloLE.mjs";
2
2
  import { trimCommonFolder, vis } from "vitest-plugin-vis/config";
3
3
 
4
4
  //#region src/vitest-plugin/storybook_vis.ts
@@ -6,7 +6,7 @@ function storybookVis(options) {
6
6
  return {
7
7
  ...vis({
8
8
  ...options,
9
- preset: "none"
9
+ preset: "custom"
10
10
  }),
11
11
  name: NAME
12
12
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-plugin.mjs","names":[],"sources":["../../src/vitest-plugin/storybook_vis.ts"],"sourcesContent":["/**\n * Return type is `any` to support different Vitest and Vite versions.\n */\nimport type { Omit } from 'type-plus'\nimport { type ComparisonMethod, type VisOptions, vis } from 'vitest-plugin-vis/config'\nimport { NAME } from '../shared/constants.ts'\n\nexport function storybookVis<M extends ComparisonMethod>(options?: Omit<VisOptions<M>, 'preset'> | undefined): any {\n\treturn {\n\t\t...vis({\n\t\t\t...options,\n\t\t\tpreset: 'custom',\n\t\t}),\n\t\tname: NAME,\n\t}\n}\n"],"mappings":";;;;AAOA,SAAgB,aAAyC,SAA0D;AAClH,QAAO;EACN,GAAG,IAAI;GACN,GAAG;GACH,QAAQ;GACR,CAAC;EACF,MAAM;EACN"}
@@ -1,4 +1,4 @@
1
- import "./global_matcher_augment-CYxLwns2.js";
1
+ import "../global_matcher_augment-B1plNA_9.mjs";
2
2
  import * as storybook_internal_csf1 from "storybook/internal/csf";
3
3
  import { setAutoSnapshotOptions } from "vitest-plugin-vis";
4
4
  import * as vitest_plugin_vis_setup_api0 from "vitest-plugin-vis/setup-api";
@@ -8,10 +8,10 @@ declare const visAnnotations: {
8
8
  beforeEach(ctx: storybook_internal_csf1.StoryContext<any, storybook_internal_csf1.Args>): void;
9
9
  };
10
10
  //#endregion
11
- //#region src/vitest-setup.d.ts
11
+ //#region src/exports/vitest-setup.d.ts
12
12
  declare const vis: vitest_plugin_vis_setup_api0.VisClientConfigurator<{
13
13
  tags: string[];
14
14
  }>;
15
15
  //#endregion
16
16
  export { setAutoSnapshotOptions, vis, visAnnotations };
17
- //# sourceMappingURL=vitest-setup.d.ts.map
17
+ //# sourceMappingURL=vitest-setup.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-setup.d.mts","names":[],"sources":["../../src/preview/vis_annotation.ts","../../src/exports/vitest-setup.ts"],"sourcesContent":[],"mappings":";;;;;;cAKa;kBAWoC,uBAAA,CAAA,kBAAA,uBAAA,CAAA,IAAA;;;;cCTpC,KAA6C,4BAAA,CAA1C"}
@@ -1,10 +1,10 @@
1
- import { r as commands, t as visAnnotations } from "./vis_annotation-DqZTkmEN.js";
1
+ import { r as commands, t as visAnnotations } from "../vis_annotation-B5Jl50Wp.mjs";
2
2
  import { setAutoSnapshotOptions } from "vitest-plugin-vis";
3
3
  import { createVis } from "vitest-plugin-vis/setup-api";
4
4
 
5
- //#region src/vitest-setup.ts
5
+ //#region src/exports/vitest-setup.ts
6
6
  const vis = createVis(commands);
7
7
 
8
8
  //#endregion
9
9
  export { setAutoSnapshotOptions, vis, visAnnotations };
10
- //# sourceMappingURL=vitest-setup.js.map
10
+ //# sourceMappingURL=vitest-setup.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-setup.mjs","names":[],"sources":["../../src/exports/vitest-setup.ts"],"sourcesContent":["// `storybook-addon-vis/vitest-setup` provides code needed in `vitest.setup.ts`.\nimport '../client/storybook/expect_extend.ts'\nimport '../shared/global_matcher_augment.ts'\n\nimport { createVis } from 'vitest-plugin-vis/setup-api'\nimport { commands } from '../client/vitest_proxy.ts'\n\nexport const vis = createVis<{ tags: string[] }>(commands)\nexport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nexport { visAnnotations } from '../preview/vis_annotation.ts'\n"],"mappings":";;;;;AAOA,MAAa,MAAM,UAA8B,SAAS"}
@@ -7,4 +7,4 @@ declare global {
7
7
  }
8
8
  }
9
9
  //# sourceMappingURL=global_matcher_augment.d.ts.map
10
- //# sourceMappingURL=global_matcher_augment-CYxLwns2.d.ts.map
10
+ //# sourceMappingURL=global_matcher_augment-B1plNA_9.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global_matcher_augment-B1plNA_9.d.mts","names":[],"sources":["../src/shared/global_matcher_augment.ts"],"sourcesContent":[],"mappings":";;;;;IAEwE,UAAA,QAAA,CAAA,CAAA,EAAA,CAAA,CAAA,SAIrC,oBAJqC,CAAA,CAAA;EAAA"}
@@ -1,9 +1,9 @@
1
- import "./global_matcher_augment-CYxLwns2.js";
1
+ import "./global_matcher_augment-B1plNA_9.mjs";
2
2
  import { ComparisonMethod, FailureThresholdOptions, ImageSnapshotCompareOptions, ImageSnapshotKeyOptions, ImageSnapshotKeyOptions as ImageSnapshotKeyOptions$1, ImageSnapshotSubjectOptions, ImageSnapshotTimeoutOptions, PixelComparisonOptions, SsimComparisonOptions, ToMatchImageSnapshotOptions } from "vitest-plugin-vis/client-api";
3
3
  import * as storybook_internal_csf0 from "storybook/internal/csf";
4
4
  import { SetupVisOptions } from "vitest-plugin-vis";
5
+ import "vitest";
5
6
  import { BrowserPage } from "vitest/browser";
6
- import "vitest/suite";
7
7
  export * from "vitest-plugin-vis";
8
8
 
9
9
  //#region src/client/vitest_proxy.d.ts
@@ -22,6 +22,7 @@ declare function hasImageSnapshot(options?: ImageSnapshotKeyOptions$1 | undefine
22
22
  declare function defineAutoSnapshotParam<M extends ComparisonMethod>(snapshot: ToMatchImageSnapshotOptions<M> & ImageSnapshotSubjectOptions): {
23
23
  snapshot: ImageSnapshotTimeoutOptions & ImageSnapshotKeyOptions & (M extends "ssim" ? SsimComparisonOptions<M> : PixelComparisonOptions<M>) & FailureThresholdOptions & {
24
24
  expectToFail?: boolean | undefined;
25
+ createMissingBaseline?: boolean | undefined;
25
26
  } & ImageSnapshotSubjectOptions;
26
27
  };
27
28
  //#endregion
@@ -32,4 +33,4 @@ declare function isSnapshotEnabled(tags: string[]): boolean;
32
33
  declare const _default: (options?: SetupVisOptions) => storybook_internal_csf0.PreviewAddon<storybook_internal_csf0.AddonTypes>;
33
34
  //#endregion
34
35
  export { type ComparisonMethod, type FailureThresholdOptions, type ImageSnapshotCompareOptions, type ImageSnapshotKeyOptions, type ImageSnapshotSubjectOptions, type ImageSnapshotTimeoutOptions, type PixelComparisonOptions, type SsimComparisonOptions, type ToMatchImageSnapshotOptions, _default as default, defineAutoSnapshotParam, hasImageSnapshot, isSnapshotEnabled, page };
35
- //# sourceMappingURL=index.d.ts.map
36
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +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":";;;;;;;;;cAiBa,MAAI;;;;;;iBCVD,gBAAA,WAA2B,gDAAmC;;;;;;iBCqB9D,kCAAkC,4BACvC,4BAA4B,KAAK;;;;;AFZ5C,CAAA;;;iBGjBgB,iBAAA;;;cCgBD,qBAEU,oBAAiC,uBAAA,CAAA,aAAA,uBAAA,CAAA,UAAA"}
@@ -1,4 +1,4 @@
1
- import { a as page, i as getCurrentTest, n as isSnapshotEnabled, r as commands, t as visAnnotations } from "./vis_annotation-DqZTkmEN.js";
1
+ import { a as page, i as getCurrentTest, n as isSnapshotEnabled, r as commands, t as visAnnotations } from "./vis_annotation-B5Jl50Wp.mjs";
2
2
  import { expect } from "storybook/test";
3
3
  import { autoSnapshotMatcher, hasImageSnapshotAction, setAutoSnapshotOptions, toTaskId } from "vitest-plugin-vis/client-api";
4
4
  import { definePreviewAddon } from "storybook/internal/csf";
@@ -42,9 +42,10 @@ var src_default = (options = { auto: false }) => {
42
42
  tags: options.auto ? ["snapshot"] : [],
43
43
  async beforeAll() {
44
44
  matcher = autoSnapshotMatcher(commands, expect);
45
- if (typeof options?.auto === "function") matcherFn = matcher.createMatcher({ auto: options.auto });
46
- else if (typeof options?.auto === "object") matcherFn = matcher.createMatcher(options.auto);
47
- else matcherFn = matcher.createMatcher({ async auto() {} });
45
+ const suiteDefaults = options?.createMissingBaseline !== void 0 ? { createMissingBaseline: options.createMissingBaseline } : void 0;
46
+ if (typeof options?.auto === "function") matcherFn = matcher.createMatcher({ auto: options.auto }, suiteDefaults);
47
+ else if (typeof options?.auto === "object") matcherFn = matcher.createMatcher(options.auto, suiteDefaults);
48
+ else matcherFn = matcher.createMatcher({ async auto() {} }, suiteDefaults);
48
49
  await matcher.setup();
49
50
  await setAutoSnapshotOptions(true);
50
51
  },
@@ -57,4 +58,4 @@ var src_default = (options = { auto: false }) => {
57
58
 
58
59
  //#endregion
59
60
  export { src_default as default, defineAutoSnapshotParam, hasImageSnapshot, isSnapshotEnabled, page };
60
- //# sourceMappingURL=index.js.map
61
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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, toTaskId, type ImageSnapshotKeyOptions } 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 './client/storybook/expect_extend.ts'\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 { commands, page } from './client/vitest_proxy.ts'\nimport { visAnnotations } from './preview/vis_annotation.ts'\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 }\n\nexport default (options: SetupVisOptions = { auto: false }) => {\n\tlet matcher: ReturnType<typeof autoSnapshotMatcher>\n\tlet matcherFn: () => Promise<void>\n\treturn definePreviewAddon({\n\t\ttags: options.auto ? ['snapshot'] : [],\n\t\tasync beforeAll() {\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;;;;;ACbpB,mBAAgB,UAA2B,EAAE,MAAM,OAAO,KAAK;CAC9D,IAAI;CACJ,IAAI;AACJ,QAAO,mBAAmB;EACzB,MAAM,QAAQ,OAAO,CAAC,WAAW,GAAG,EAAE;EACtC,MAAM,YAAY;AACjB,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"}
package/dist/manager.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import React, { memo, useEffect, useState } from "react";
2
2
  import { addons, types } from "storybook/manager-api";
3
3
  import { RefreshIcon } from "@storybook/icons";
4
- import { AddonPanel, IconButton, Placeholder, ScrollArea } from "storybook/internal/components";
4
+ import { AddonPanel, Button, Placeholder, ScrollArea } from "storybook/internal/components";
5
5
  import { styled } from "storybook/theming";
6
6
  import { SNAPSHOT_ROOT_DIR } from "vitest-plugin-vis/client-api";
7
7
 
@@ -20,10 +20,13 @@ const VisPanel = memo(function VisPanel$1({ active, getSnapshotResults, onRefres
20
20
  key: result.filePath,
21
21
  src: `data:image/png;base64,${result.base64}`,
22
22
  alt: result.fileName
23
- }))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SnapshotRow, null, /* @__PURE__ */ React.createElement("span", null, key), /* @__PURE__ */ React.createElement(IconButton, { onClick: () => {
24
- onRefresh();
25
- getSnapshotResults().then(setSnapshotResults);
26
- } }, /* @__PURE__ */ React.createElement(RefreshIcon, null))), /* @__PURE__ */ React.createElement("img", {
23
+ }))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SnapshotRow, null, /* @__PURE__ */ React.createElement("span", null, key), /* @__PURE__ */ React.createElement(Button, {
24
+ "aria-label": "Reload snapshot",
25
+ onClick: () => {
26
+ onRefresh();
27
+ getSnapshotResults().then(setSnapshotResults);
28
+ }
29
+ }, /* @__PURE__ */ React.createElement(RefreshIcon, null))), /* @__PURE__ */ React.createElement("img", {
27
30
  key: results[0].filePath,
28
31
  src: `data:image/png;base64,${results[0].base64}`,
29
32
  alt: results[0].fileName
@@ -40,7 +43,7 @@ const SnapshotRow = styled.div(({ theme, failed }) => ({
40
43
  }));
41
44
 
42
45
  //#endregion
43
- //#region src/shared/contants.ts
46
+ //#region src/shared/constants.ts
44
47
  const NAME = "storybook-addon-vis";
45
48
  const VIS_PANEL_ID = `${NAME}/vis_panel`;
46
49
 
@@ -57,7 +60,7 @@ function requestImageSnapshotResults({ name, importPath }) {
57
60
  }
58
61
 
59
62
  //#endregion
60
- //#region src/manager.tsx
63
+ //#region src/exports/manager.tsx
61
64
  addons.register(NAME, (api) => {
62
65
  if (globalThis.CONFIG_TYPE === "DEVELOPMENT") addons.add(VIS_PANEL_ID, {
63
66
  type: types.PANEL,
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","names":["VisPanel"],"sources":["../src/components/vis_panel.tsx","../src/shared/contants.ts","../src/shared/events.ts","../src/manager.tsx"],"sourcesContent":["import { RefreshIcon } from '@storybook/icons'\nimport React, { memo, useEffect, useState } from 'react'\nimport { AddonPanel, IconButton, Placeholder, ScrollArea } from 'storybook/internal/components'\nimport { styled } from 'storybook/theming'\nimport { SNAPSHOT_ROOT_DIR } from 'vitest-plugin-vis/client-api'\nimport type { ImageSnapshotResults } from '../shared/events.ts'\n\ninterface PanelProps {\n\tactive: boolean\n\tgetSnapshotResults: () => Promise<ImageSnapshotResults[]>\n\tonRefresh: () => void\n}\n\nexport const VisPanel = memo(function VisPanel({ active, getSnapshotResults, onRefresh }: PanelProps) {\n\tconst [snapshotResults, setSnapshotResults] = useState<ImageSnapshotResults[]>([])\n\n\tuseEffect(() => {\n\t\tgetSnapshotResults().then(setSnapshotResults)\n\t}, [getSnapshotResults])\n\n\tconst groupedResults = snapshotResults.reduce(\n\t\t(acc, result) => {\n\t\t\tconst suiteName = result.snapshotRootDir.slice(SNAPSHOT_ROOT_DIR.length + 1)\n\t\t\tconst key = `(${suiteName}) ${result.fileName}`\n\t\t\tacc[key] = [...(acc[key] ?? []), result]\n\t\t\treturn acc\n\t\t},\n\t\t{} as Record<string, ImageSnapshotResults[]>,\n\t)\n\treturn (\n\t\t<AddonPanel active={active}>\n\t\t\t{snapshotResults.length > 0 ? (\n\t\t\t\t<ScrollArea vertical>\n\t\t\t\t\t{Object.entries(groupedResults).map(([key, results]) => (\n\t\t\t\t\t\t<div key={key}>\n\t\t\t\t\t\t\t{results.some((result) => result.type === 'diff') ? (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<SnapshotRow failed>{key}</SnapshotRow>\n\t\t\t\t\t\t\t\t\t{results.map((result) => (\n\t\t\t\t\t\t\t\t\t\t<img key={result.filePath} src={`data:image/png;base64,${result.base64}`} alt={result.fileName} />\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<SnapshotRow>\n\t\t\t\t\t\t\t\t\t\t<span>{key}</span>\n\t\t\t\t\t\t\t\t\t\t<IconButton\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonRefresh()\n\t\t\t\t\t\t\t\t\t\t\t\tgetSnapshotResults().then(setSnapshotResults)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<RefreshIcon />\n\t\t\t\t\t\t\t\t\t\t</IconButton>\n\t\t\t\t\t\t\t\t\t</SnapshotRow>\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tkey={results[0].filePath}\n\t\t\t\t\t\t\t\t\t\tsrc={`data:image/png;base64,${results[0].base64}`}\n\t\t\t\t\t\t\t\t\t\talt={results[0].fileName}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</ScrollArea>\n\t\t\t) : (\n\t\t\t\t<Placeholder>There is no snapshots for this story</Placeholder>\n\t\t\t)}\n\t\t</AddonPanel>\n\t)\n})\n\nconst SnapshotRow = styled.div<{ failed?: boolean }>(({ theme, failed }) => ({\n\tdisplay: 'flex',\n\talignItems: 'center',\n\tgap: '0.5rem',\n\tpaddingBlock: '0.5rem',\n\tpaddingInline: '0.2rem',\n\tbackgroundColor: failed ? theme.background.negative : theme.background.positive,\n\tcolor: theme.barTextColor,\n}))\n","export const NAME = 'storybook-addon-vis'\nexport const VIS_PANEL_ID = `${NAME}/vis_panel`\n","export type VisEvent = ImageSnapshotResultsRequest | ImageSnapshotResultsResponse\n\nexport const IMAGE_SNAPSHOT_RESULTS_REQUEST = 'IMAGE_SNAPSHOT_RESULTS_REQUEST'\nexport const IMAGE_SNAPSHOT_RESULTS_RESPONSE = 'IMAGE_SNAPSHOT_RESULTS_RESPONSE'\n\nexport function requestImageSnapshotResults({ name, importPath }: { name: string; importPath: string }) {\n\treturn {\n\t\ttype: IMAGE_SNAPSHOT_RESULTS_REQUEST,\n\t\tname,\n\t\timportPath,\n\t}\n}\n\nexport type ImageSnapshotResultsRequest = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_REQUEST\n\tname: string\n\timportPath: string\n}\n\nexport type ImageSnapshotResultsResponse = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_RESPONSE\n\tname: string\n\timportPath: string\n\tresults: ImageSnapshotResults[]\n}\n\nexport type ImageSnapshotResults = {\n\tfilePath: string\n\tfileName: string\n\tsnapshotRootDir: string\n\ttype: 'baseline' | 'diff' | 'result'\n\tbase64: string\n}\n","import React from 'react'\nimport { addons, types } from 'storybook/manager-api'\nimport { VisPanel } from './components/vis_panel.tsx'\nimport { NAME, VIS_PANEL_ID } from './shared/contants.ts'\nimport {\n\tIMAGE_SNAPSHOT_RESULTS_RESPONSE,\n\trequestImageSnapshotResults,\n\ttype ImageSnapshotResults,\n\ttype VisEvent,\n} from './shared/events.ts'\n\n// Register the addon\naddons.register(NAME, (api) => {\n\t// Register the tool\n\tif ((globalThis as any).CONFIG_TYPE === 'DEVELOPMENT') {\n\t\taddons.add(VIS_PANEL_ID, {\n\t\t\ttype: types.PANEL,\n\t\t\ttitle: 'Vis',\n\t\t\tmatch: ({ tabId, viewMode }) => !tabId && viewMode === 'story',\n\t\t\trender({ active }) {\n\t\t\t\tif (!active) return null\n\t\t\t\tconst storyData = api.getCurrentStoryData()\n\t\t\t\tif (!storyData) return null\n\t\t\t\tapi.emit(NAME, requestImageSnapshotResults(storyData))\n\t\t\t\tasync function getSnapshotResults() {\n\t\t\t\t\treturn new Promise<ImageSnapshotResults[]>((resolve) => {\n\t\t\t\t\t\tapi.once(NAME, (event: VisEvent) => {\n\t\t\t\t\t\t\tif (event.name !== storyData.name) return\n\t\t\t\t\t\t\tif (event.importPath !== storyData.importPath) return\n\t\t\t\t\t\t\tif (event.type === IMAGE_SNAPSHOT_RESULTS_RESPONSE) {\n\t\t\t\t\t\t\t\tresolve(event.results)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<VisPanel\n\t\t\t\t\t\tactive={active}\n\t\t\t\t\t\tgetSnapshotResults={getSnapshotResults}\n\t\t\t\t\t\tonRefresh={() => {\n\t\t\t\t\t\t\tif (storyData) api.emit(NAME, requestImageSnapshotResults(storyData))\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t},\n\t\t})\n\t}\n})\n"],"mappings":";;;;;;;;AAaA,MAAa,WAAW,KAAK,SAASA,WAAS,EAAE,QAAQ,oBAAoB,aAAyB;CACrG,MAAM,CAAC,iBAAiB,sBAAsB,SAAiC,EAAE,CAAC;AAElF,iBAAgB;AACf,sBAAoB,CAAC,KAAK,mBAAmB;IAC3C,CAAC,mBAAmB,CAAC;CAExB,MAAM,iBAAiB,gBAAgB,QACrC,KAAK,WAAW;EAEhB,MAAM,MAAM,IADM,OAAO,gBAAgB,MAAM,kBAAkB,SAAS,EAAE,CAClD,IAAI,OAAO;AACrC,MAAI,OAAO,CAAC,GAAI,IAAI,QAAQ,EAAE,EAAG,OAAO;AACxC,SAAO;IAER,EAAE,CACF;AACD,QACC,oCAAC,cAAmB,UAClB,gBAAgB,SAAS,IACzB,oCAAC,cAAW,kBACV,OAAO,QAAQ,eAAe,CAAC,KAAK,CAAC,KAAK,aAC1C,oCAAC,SAAS,OACR,QAAQ,MAAM,WAAW,OAAO,SAAS,OAAO,GAChD,0DACC,oCAAC,eAAY,gBAAQ,IAAkB,EACtC,QAAQ,KAAK,WACb,oCAAC;EAAI,KAAK,OAAO;EAAU,KAAK,yBAAyB,OAAO;EAAU,KAAK,OAAO;GAAY,CACjG,CACA,GAEH,0DACC,oCAAC,mBACA,oCAAC,cAAM,IAAW,EAClB,oCAAC,cACA,eAAe;AACd,aAAW;AACX,sBAAoB,CAAC,KAAK,mBAAmB;MAG9C,oCAAC,kBAAc,CACH,CACA,EACd,oCAAC;EACA,KAAK,QAAQ,GAAG;EAChB,KAAK,yBAAyB,QAAQ,GAAG;EACzC,KAAK,QAAQ,GAAG;GACf,CACA,CAEC,CACL,CACU,GAEb,oCAAC,mBAAY,uCAAkD,CAEpD;EAEb;AAEF,MAAM,cAAc,OAAO,KAA2B,EAAE,OAAO,cAAc;CAC5E,SAAS;CACT,YAAY;CACZ,KAAK;CACL,cAAc;CACd,eAAe;CACf,iBAAiB,SAAS,MAAM,WAAW,WAAW,MAAM,WAAW;CACvE,OAAO,MAAM;CACb,EAAE;;;;AChFH,MAAa,OAAO;AACpB,MAAa,eAAe,GAAG,KAAK;;;;ACCpC,MAAa,iCAAiC;AAC9C,MAAa,kCAAkC;AAE/C,SAAgB,4BAA4B,EAAE,MAAM,cAAoD;AACvG,QAAO;EACN,MAAM;EACN;EACA;EACA;;;;;ACEF,OAAO,SAAS,OAAO,QAAQ;AAE9B,KAAK,WAAmB,gBAAgB,cACvC,QAAO,IAAI,cAAc;EACxB,MAAM,MAAM;EACZ,OAAO;EACP,QAAQ,EAAE,OAAO,eAAe,CAAC,SAAS,aAAa;EACvD,OAAO,EAAE,UAAU;AAClB,OAAI,CAAC,OAAQ,QAAO;GACpB,MAAM,YAAY,IAAI,qBAAqB;AAC3C,OAAI,CAAC,UAAW,QAAO;AACvB,OAAI,KAAK,MAAM,4BAA4B,UAAU,CAAC;GACtD,eAAe,qBAAqB;AACnC,WAAO,IAAI,SAAiC,YAAY;AACvD,SAAI,KAAK,OAAO,UAAoB;AACnC,UAAI,MAAM,SAAS,UAAU,KAAM;AACnC,UAAI,MAAM,eAAe,UAAU,WAAY;AAC/C,UAAI,MAAM,SAAS,gCAClB,SAAQ,MAAM,QAAQ;OAEtB;MACD;;AAEH,UACC,oCAAC;IACQ;IACY;IACpB,iBAAiB;AAChB,SAAI,UAAW,KAAI,KAAK,MAAM,4BAA4B,UAAU,CAAC;;KAErE;;EAGJ,CAAC;EAEF"}
1
+ {"version":3,"file":"manager.js","names":["VisPanel"],"sources":["../src/components/vis_panel.tsx","../src/shared/constants.ts","../src/shared/events.ts","../src/exports/manager.tsx"],"sourcesContent":["import { RefreshIcon } from '@storybook/icons'\nimport React, { memo, useEffect, useState } from 'react'\nimport { AddonPanel, Button, Placeholder, ScrollArea } from 'storybook/internal/components'\nimport { styled } from 'storybook/theming'\nimport { SNAPSHOT_ROOT_DIR } from 'vitest-plugin-vis/client-api'\nimport type { ImageSnapshotResults } from '../shared/events.ts'\n\ninterface PanelProps {\n\tactive: boolean\n\tgetSnapshotResults: () => Promise<ImageSnapshotResults[]>\n\tonRefresh: () => void\n}\n\nexport const VisPanel = memo(function VisPanel({ active, getSnapshotResults, onRefresh }: PanelProps) {\n\tconst [snapshotResults, setSnapshotResults] = useState<ImageSnapshotResults[]>([])\n\n\tuseEffect(() => {\n\t\tgetSnapshotResults().then(setSnapshotResults)\n\t}, [getSnapshotResults])\n\n\tconst groupedResults = snapshotResults.reduce(\n\t\t(acc, result) => {\n\t\t\tconst suiteName = result.snapshotRootDir.slice(SNAPSHOT_ROOT_DIR.length + 1)\n\t\t\tconst key = `(${suiteName}) ${result.fileName}`\n\t\t\tacc[key] = [...(acc[key] ?? []), result]\n\t\t\treturn acc\n\t\t},\n\t\t{} as Record<string, ImageSnapshotResults[]>,\n\t)\n\treturn (\n\t\t<AddonPanel active={active}>\n\t\t\t{snapshotResults.length > 0 ? (\n\t\t\t\t<ScrollArea vertical>\n\t\t\t\t\t{Object.entries(groupedResults).map(([key, results]) => (\n\t\t\t\t\t\t<div key={key}>\n\t\t\t\t\t\t\t{results.some((result) => result.type === 'diff') ? (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<SnapshotRow failed>{key}</SnapshotRow>\n\t\t\t\t\t\t\t\t\t{results.map((result) => (\n\t\t\t\t\t\t\t\t\t\t<img key={result.filePath} src={`data:image/png;base64,${result.base64}`} alt={result.fileName} />\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<SnapshotRow>\n\t\t\t\t\t\t\t\t\t\t<span>{key}</span>\n\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Reload snapshot\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonRefresh()\n\t\t\t\t\t\t\t\t\t\t\t\tgetSnapshotResults().then(setSnapshotResults)\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<RefreshIcon />\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t</SnapshotRow>\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\tkey={results[0].filePath}\n\t\t\t\t\t\t\t\t\t\tsrc={`data:image/png;base64,${results[0].base64}`}\n\t\t\t\t\t\t\t\t\t\talt={results[0].fileName}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</ScrollArea>\n\t\t\t) : (\n\t\t\t\t<Placeholder>There is no snapshots for this story</Placeholder>\n\t\t\t)}\n\t\t</AddonPanel>\n\t)\n})\n\nconst SnapshotRow = styled.div<{ failed?: boolean }>(\n\t({ theme, failed }: { theme: any; failed?: boolean | undefined }) => ({\n\t\tdisplay: 'flex',\n\t\talignItems: 'center',\n\t\tgap: '0.5rem',\n\t\tpaddingBlock: '0.5rem',\n\t\tpaddingInline: '0.2rem',\n\t\tbackgroundColor: failed ? theme.background.negative : theme.background.positive,\n\t\tcolor: theme.barTextColor,\n\t}),\n)\n","export const NAME = 'storybook-addon-vis'\nexport const VIS_PANEL_ID = `${NAME}/vis_panel`\n","export type VisEvent = ImageSnapshotResultsRequest | ImageSnapshotResultsResponse\n\nexport const IMAGE_SNAPSHOT_RESULTS_REQUEST = 'IMAGE_SNAPSHOT_RESULTS_REQUEST'\nexport const IMAGE_SNAPSHOT_RESULTS_RESPONSE = 'IMAGE_SNAPSHOT_RESULTS_RESPONSE'\n\nexport function requestImageSnapshotResults({ name, importPath }: { name: string; importPath: string }) {\n\treturn {\n\t\ttype: IMAGE_SNAPSHOT_RESULTS_REQUEST,\n\t\tname,\n\t\timportPath,\n\t}\n}\n\nexport type ImageSnapshotResultsRequest = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_REQUEST\n\tname: string\n\timportPath: string\n}\n\nexport type ImageSnapshotResultsResponse = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_RESPONSE\n\tname: string\n\timportPath: string\n\tresults: ImageSnapshotResults[]\n}\n\nexport type ImageSnapshotResults = {\n\tfilePath: string\n\tfileName: string\n\tsnapshotRootDir: string\n\ttype: 'baseline' | 'diff' | 'result'\n\tbase64: string\n}\n","import React from 'react'\nimport { addons, types } from 'storybook/manager-api'\nimport { VisPanel } from '../components/vis_panel.tsx'\nimport { NAME, VIS_PANEL_ID } from '../shared/constants.ts'\nimport {\n\tIMAGE_SNAPSHOT_RESULTS_RESPONSE,\n\trequestImageSnapshotResults,\n\ttype ImageSnapshotResults,\n\ttype VisEvent,\n} from '../shared/events.ts'\n\n// Register the addon\naddons.register(NAME, (api) => {\n\t// Register the tool\n\tif ((globalThis as any).CONFIG_TYPE === 'DEVELOPMENT') {\n\t\taddons.add(VIS_PANEL_ID, {\n\t\t\ttype: types.PANEL,\n\t\t\ttitle: 'Vis',\n\t\t\tmatch: ({ tabId, viewMode }) => !tabId && viewMode === 'story',\n\t\t\trender({ active }) {\n\t\t\t\tif (!active) return null\n\t\t\t\tconst storyData = api.getCurrentStoryData()\n\t\t\t\tif (!storyData) return null\n\t\t\t\tapi.emit(NAME, requestImageSnapshotResults(storyData))\n\t\t\t\tasync function getSnapshotResults() {\n\t\t\t\t\treturn new Promise<ImageSnapshotResults[]>((resolve) => {\n\t\t\t\t\t\tapi.once(NAME, (event: VisEvent) => {\n\t\t\t\t\t\t\tif (event.name !== storyData.name) return\n\t\t\t\t\t\t\tif (event.importPath !== storyData.importPath) return\n\t\t\t\t\t\t\tif (event.type === IMAGE_SNAPSHOT_RESULTS_RESPONSE) {\n\t\t\t\t\t\t\t\tresolve(event.results)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<VisPanel\n\t\t\t\t\t\tactive={active}\n\t\t\t\t\t\tgetSnapshotResults={getSnapshotResults}\n\t\t\t\t\t\tonRefresh={() => {\n\t\t\t\t\t\t\tif (storyData) api.emit(NAME, requestImageSnapshotResults(storyData))\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)\n\t\t\t},\n\t\t})\n\t}\n})\n"],"mappings":";;;;;;;;AAaA,MAAa,WAAW,KAAK,SAASA,WAAS,EAAE,QAAQ,oBAAoB,aAAyB;CACrG,MAAM,CAAC,iBAAiB,sBAAsB,SAAiC,EAAE,CAAC;AAElF,iBAAgB;AACf,sBAAoB,CAAC,KAAK,mBAAmB;IAC3C,CAAC,mBAAmB,CAAC;CAExB,MAAM,iBAAiB,gBAAgB,QACrC,KAAK,WAAW;EAEhB,MAAM,MAAM,IADM,OAAO,gBAAgB,MAAM,kBAAkB,SAAS,EAAE,CAClD,IAAI,OAAO;AACrC,MAAI,OAAO,CAAC,GAAI,IAAI,QAAQ,EAAE,EAAG,OAAO;AACxC,SAAO;IAER,EAAE,CACF;AACD,QACC,oCAAC,cAAmB,UAClB,gBAAgB,SAAS,IACzB,oCAAC,cAAW,kBACV,OAAO,QAAQ,eAAe,CAAC,KAAK,CAAC,KAAK,aAC1C,oCAAC,SAAS,OACR,QAAQ,MAAM,WAAW,OAAO,SAAS,OAAO,GAChD,0DACC,oCAAC,eAAY,gBAAQ,IAAkB,EACtC,QAAQ,KAAK,WACb,oCAAC;EAAI,KAAK,OAAO;EAAU,KAAK,yBAAyB,OAAO;EAAU,KAAK,OAAO;GAAY,CACjG,CACA,GAEH,0DACC,oCAAC,mBACA,oCAAC,cAAM,IAAW,EAClB,oCAAC;EACA,cAAW;EACX,eAAe;AACd,cAAW;AACX,uBAAoB,CAAC,KAAK,mBAAmB;;IAG9C,oCAAC,kBAAc,CACP,CACI,EACd,oCAAC;EACA,KAAK,QAAQ,GAAG;EAChB,KAAK,yBAAyB,QAAQ,GAAG;EACzC,KAAK,QAAQ,GAAG;GACf,CACA,CAEC,CACL,CACU,GAEb,oCAAC,mBAAY,uCAAkD,CAEpD;EAEb;AAEF,MAAM,cAAc,OAAO,KACzB,EAAE,OAAO,cAA4D;CACrE,SAAS;CACT,YAAY;CACZ,KAAK;CACL,cAAc;CACd,eAAe;CACf,iBAAiB,SAAS,MAAM,WAAW,WAAW,MAAM,WAAW;CACvE,OAAO,MAAM;CACb,EACD;;;;ACnFD,MAAa,OAAO;AACpB,MAAa,eAAe,GAAG,KAAK;;;;ACCpC,MAAa,iCAAiC;AAC9C,MAAa,kCAAkC;AAE/C,SAAgB,4BAA4B,EAAE,MAAM,cAAoD;AACvG,QAAO;EACN,MAAM;EACN;EACA;EACA;;;;;ACEF,OAAO,SAAS,OAAO,QAAQ;AAE9B,KAAK,WAAmB,gBAAgB,cACvC,QAAO,IAAI,cAAc;EACxB,MAAM,MAAM;EACZ,OAAO;EACP,QAAQ,EAAE,OAAO,eAAe,CAAC,SAAS,aAAa;EACvD,OAAO,EAAE,UAAU;AAClB,OAAI,CAAC,OAAQ,QAAO;GACpB,MAAM,YAAY,IAAI,qBAAqB;AAC3C,OAAI,CAAC,UAAW,QAAO;AACvB,OAAI,KAAK,MAAM,4BAA4B,UAAU,CAAC;GACtD,eAAe,qBAAqB;AACnC,WAAO,IAAI,SAAiC,YAAY;AACvD,SAAI,KAAK,OAAO,UAAoB;AACnC,UAAI,MAAM,SAAS,UAAU,KAAM;AACnC,UAAI,MAAM,eAAe,UAAU,WAAY;AAC/C,UAAI,MAAM,SAAS,gCAClB,SAAQ,MAAM,QAAQ;OAEtB;MACD;;AAEH,UACC,oCAAC;IACQ;IACY;IACpB,iBAAiB;AAChB,SAAI,UAAW,KAAI,KAAK,MAAM,4BAA4B,UAAU,CAAC;;KAErE;;EAGJ,CAAC;EAEF"}
@@ -14,14 +14,14 @@ function toMatchImageSnapshot$1(options) {
14
14
  //#endregion
15
15
  //#region src/client/vitest_proxy.ts
16
16
  let browserContext;
17
- let vitestSuite;
17
+ let vitest;
18
18
  if (globalThis.__vitest_browser__) {
19
19
  import("vitest/browser").then((m) => {
20
20
  m.page.extend({ toMatchImageSnapshot: toMatchImageSnapshot$1 });
21
21
  browserContext = m;
22
22
  });
23
- import("vitest/suite").then((m) => {
24
- vitestSuite = m;
23
+ import("vitest").then((m) => {
24
+ vitest = m;
25
25
  });
26
26
  }
27
27
  const page = new Proxy({}, { get(_target, prop) {
@@ -32,7 +32,7 @@ const page = new Proxy({}, { get(_target, prop) {
32
32
  const commands = new Proxy({}, { get(_target, prop) {
33
33
  return (browserContext?.commands)?.[prop];
34
34
  } });
35
- const getCurrentTest = () => vitestSuite?.getCurrentTest();
35
+ const getCurrentTest = () => vitest?.TestRunner.getCurrentTest();
36
36
 
37
37
  //#endregion
38
38
  //#region src/client/expect/to_match_image_snapshot.ts
@@ -71,4 +71,4 @@ const visAnnotations = { beforeEach(ctx) {
71
71
 
72
72
  //#endregion
73
73
  export { page as a, getCurrentTest as i, isSnapshotEnabled as n, commands as r, visAnnotations as t };
74
- //# sourceMappingURL=vis_annotation-DqZTkmEN.js.map
74
+ //# sourceMappingURL=vis_annotation-B5Jl50Wp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vis_annotation-B5Jl50Wp.mjs","names":["toMatchImageSnapshot"],"sources":["../src/client/page/to_match_image_snapshot.ts","../src/client/vitest_proxy.ts","../src/client/expect/to_match_image_snapshot.ts","../src/client/storybook/expect_extend.ts","../src/client/storybook/tags.ts","../src/preview/vis_annotation.ts"],"sourcesContent":["import {\n\ttype ComparisonMethod,\n\ttype ToMatchPageImageSnapshotOptions,\n\tmatchPageImageSnapshotAction,\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 { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'\nimport type { BrowserCommands, BrowserPage } from 'vitest/browser'\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 ((globalThis as any).__vitest_browser__) {\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\ttype ToMatchImageSnapshotOptions,\n\tmatchImageSnapshotAction,\n\tsuccess,\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","import { expect } from 'storybook/test'\nimport { toMatchImageSnapshot } from '../expect/to_match_image_snapshot.ts'\n\nexpect.extend({ toMatchImageSnapshot })\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 { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\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":";;;;;AAQA,SAAgBA,uBACf,SACC;CACD,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,SAAS;;AAGnC,QAAO,6BAA6B,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;ACbvE,IAAI;AACJ,IAAI;AAEJ,IAAK,WAAmB,oBAAoB;AAC3C,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;;;;ACxBpC,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;;;;;ACrBhG,OAAO,OAAO,EAAE,sBAAsB,CAAC;;;;ACHvC,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;;;;;ACD1B,MAAa,iBAAiB,EAC7B,WAAW,KAAK;CACf,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/manager.js CHANGED
@@ -1 +1,2 @@
1
- import './dist/manager.js'
1
+ import './dist/exports/manager.js';
2
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-addon-vis",
3
- "version": "3.1.5",
3
+ "version": "4.1.0",
4
4
  "description": "Storybook Vitest visual testing addon",
5
5
  "keywords": [
6
6
  "image-snapshot",
@@ -24,35 +24,25 @@
24
24
  },
25
25
  "type": "module",
26
26
  "imports": {
27
- "#storybook-addon-vis/node": "./src/node.ts",
28
- "#storybook-addon-vis/vitest-plugin": "./src/vitest-plugin.ts"
27
+ "#storybook-addon-vis": "./src/index.ts",
28
+ "#storybook-addon-vis/node": "./src/exports/node.ts",
29
+ "#storybook-addon-vis/vitest-plugin": "./src/exports/vitest-plugin.ts",
30
+ "#storybook-addon-vis/vitest-setup": "./src/exports/vitest-setup.ts"
29
31
  },
30
32
  "exports": {
31
33
  ".": {
32
- "types": "./dist/index.d.ts",
33
- "import": "./dist/index.js"
34
+ "source": "./src/index.ts",
35
+ "types": "./dist/index.d.mts",
36
+ "default": "./dist/index.mjs"
34
37
  },
35
- "./manager": "./dist/manager.js",
36
- "./matcher": {
37
- "types": "./dist/matcher.d.ts",
38
- "import": "./dist/matcher.js"
39
- },
40
- "./node": {
41
- "types": "./dist/node.d.mts",
42
- "import": "./dist/node.mjs"
43
- },
44
- "./preset": "./dist/preset.mjs",
45
- "./vitest-setup": {
46
- "types": "./dist/vitest-setup.d.ts",
47
- "import": "./dist/vitest-setup.js"
48
- },
49
- "./vitest-plugin": {
50
- "types": "./dist/vitest-plugin.d.mts",
51
- "import": "./dist/vitest-plugin.mjs"
38
+ "./*": {
39
+ "source": "./src/exports/*.ts",
40
+ "types": "./dist/exports/*.d.mts",
41
+ "default": "./dist/exports/*.mjs"
52
42
  },
53
43
  "./package.json": "./package.json"
54
44
  },
55
- "types": "./dist/index.d.ts",
45
+ "types": "./dist/index.d.mts",
56
46
  "files": [
57
47
  "dist",
58
48
  "src",
@@ -67,7 +57,7 @@
67
57
  "memoize": "^11.0.0",
68
58
  "pathe": "^2.0.3",
69
59
  "type-plus": "8.0.0-beta.8",
70
- "vitest-plugin-vis": "^4.2.2"
60
+ "vitest-plugin-vis": "^5.1.0"
71
61
  },
72
62
  "devDependencies": {
73
63
  "@repobuddy/storybook": "^2.28.0",
@@ -80,12 +70,12 @@
80
70
  "@testing-library/react": "^16.0.1",
81
71
  "@types/react": "^19.2.2",
82
72
  "@types/react-dom": "^19.2.1",
83
- "@vitejs/plugin-react": "^5.1.2",
84
- "@vitest/browser": "^4.0.16",
85
- "@vitest/browser-playwright": "^4.0.16",
86
- "@vitest/browser-webdriverio": "^4.0.16",
87
- "@vitest/coverage-istanbul": "^4.0.16",
88
- "@vitest/expect": "^4.0.16",
73
+ "@vitejs/plugin-react": "^6.0.0",
74
+ "@vitest/browser": "^4.1.4",
75
+ "@vitest/browser-playwright": "^4.1.4",
76
+ "@vitest/browser-webdriverio": "^4.1.4",
77
+ "@vitest/coverage-istanbul": "^4.1.4",
78
+ "@vitest/expect": "^4.1.4",
89
79
  "boxen": "^8.0.1",
90
80
  "cross-env": "^10.0.0",
91
81
  "dedent": "^1.5.1",
@@ -97,9 +87,9 @@
97
87
  "storybook-addon-tag-badges": "^3.1.0",
98
88
  "tailwindcss": "^4.1.14",
99
89
  "tsdown": "^0.19.0",
100
- "typescript": "^5.9.3",
101
- "vite": "^7.3.0",
102
- "vitest": "^4.0.16",
90
+ "typescript": "^6.0.0",
91
+ "vite": "^8.0.0",
92
+ "vitest": "^4.1.4",
103
93
  "vitest-browser-react": "^2.0.2",
104
94
  "webdriverio": "latest",
105
95
  "zx": "^8.0.0"
@@ -115,17 +105,17 @@
115
105
  },
116
106
  "bundler": {
117
107
  "exportEntries": [
118
- "src/index.ts",
119
- "src/matcher.ts",
120
- "src/vitest-setup.ts"
108
+ "./src/index.ts",
109
+ "./src/exports/matcher.ts",
110
+ "./src/exports/vitest-setup.ts"
121
111
  ],
122
112
  "managerEntries": [
123
- "src/manager.tsx"
113
+ "./src/exports/manager.tsx"
124
114
  ],
125
115
  "nodeEntries": [
126
- "./src/node.ts",
127
- "./src/preset.ts",
128
- "./src/vitest-plugin.ts"
116
+ "./src/exports/node.ts",
117
+ "./src/exports/preset.ts",
118
+ "./src/exports/vitest-plugin.ts"
129
119
  ]
130
120
  },
131
121
  "storybook": {
package/preset.js CHANGED
@@ -1 +1,2 @@
1
- export * from './dist/preset.mjs'
1
+ export * from './dist/exports/preset.mjs';
2
+
package/readme.md CHANGED
@@ -31,6 +31,8 @@ and controls how the auto image snapshot(s) are taken.
31
31
  > [storybook-addon-vis] 2.0.0 supports Storybook 9.
32
32
  >
33
33
  > For Storybook 8, please use 1.x.
34
+ >
35
+ > With **Storybook 10.3+**, `@storybook/addon-vitest` often applies project annotations for you. If you are **not** on CSF Next, you may need to **remove** `visAnnotations` from `setProjectAnnotations([...])` in `vitest.setup.ts` and register the same hooks from **`.storybook/preview.ts`** instead (for example via `definePreview({ addons: [addonVis(...)] })` or `export default { ...visAnnotations, ... }`). See the [Overview docs](https://repobuddy.github.io/visual-testing/?path=/docs/overview--docs#storybook-103-and-vitest-project-annotations) section **Storybook 10.3+ and Vitest project annotations**.
34
36
 
35
37
  ## Install
36
38
 
@@ -3,15 +3,15 @@ import type { BrowserCommands, BrowserPage } from 'vitest/browser'
3
3
  import { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'
4
4
 
5
5
  let browserContext: Awaited<typeof import('vitest/browser')>
6
- let vitestSuite: Awaited<typeof import('vitest/suite')>
6
+ let vitest: Awaited<typeof import('vitest')>
7
7
 
8
8
  if ((globalThis as any).__vitest_browser__) {
9
9
  import('vitest/browser').then((m) => {
10
10
  m.page.extend({ toMatchImageSnapshot })
11
11
  browserContext = m
12
12
  })
13
- import('vitest/suite').then((m) => {
14
- vitestSuite = m
13
+ import('vitest').then((m) => {
14
+ vitest = m
15
15
  })
16
16
  }
17
17
 
@@ -32,4 +32,6 @@ export const commands = new Proxy<BrowserCommands>({} as any, {
32
32
  })
33
33
 
34
34
  export const getCurrentTest = () =>
35
- vitestSuite?.getCurrentTest() as (ReturnType<typeof vitestSuite.getCurrentTest> & SnapshotTestMeta) | undefined
35
+ vitest?.TestRunner.getCurrentTest() as
36
+ | (ReturnType<typeof vitest.TestRunner.getCurrentTest> & SnapshotTestMeta)
37
+ | undefined
@@ -1,6 +1,6 @@
1
1
  import { RefreshIcon } from '@storybook/icons'
2
2
  import React, { memo, useEffect, useState } from 'react'
3
- import { AddonPanel, IconButton, Placeholder, ScrollArea } from 'storybook/internal/components'
3
+ import { AddonPanel, Button, Placeholder, ScrollArea } from 'storybook/internal/components'
4
4
  import { styled } from 'storybook/theming'
5
5
  import { SNAPSHOT_ROOT_DIR } from 'vitest-plugin-vis/client-api'
6
6
  import type { ImageSnapshotResults } from '../shared/events.ts'
@@ -44,14 +44,15 @@ export const VisPanel = memo(function VisPanel({ active, getSnapshotResults, onR
44
44
  <>
45
45
  <SnapshotRow>
46
46
  <span>{key}</span>
47
- <IconButton
47
+ <Button
48
+ aria-label="Reload snapshot"
48
49
  onClick={() => {
49
50
  onRefresh()
50
51
  getSnapshotResults().then(setSnapshotResults)
51
52
  }}
52
53
  >
53
54
  <RefreshIcon />
54
- </IconButton>
55
+ </Button>
55
56
  </SnapshotRow>
56
57
  <img
57
58
  key={results[0].filePath}
@@ -70,12 +71,14 @@ export const VisPanel = memo(function VisPanel({ active, getSnapshotResults, onR
70
71
  )
71
72
  })
72
73
 
73
- const SnapshotRow = styled.div<{ failed?: boolean }>(({ theme, failed }) => ({
74
- display: 'flex',
75
- alignItems: 'center',
76
- gap: '0.5rem',
77
- paddingBlock: '0.5rem',
78
- paddingInline: '0.2rem',
79
- backgroundColor: failed ? theme.background.negative : theme.background.positive,
80
- color: theme.barTextColor,
81
- }))
74
+ const SnapshotRow = styled.div<{ failed?: boolean }>(
75
+ ({ theme, failed }: { theme: any; failed?: boolean | undefined }) => ({
76
+ display: 'flex',
77
+ alignItems: 'center',
78
+ gap: '0.5rem',
79
+ paddingBlock: '0.5rem',
80
+ paddingInline: '0.2rem',
81
+ backgroundColor: failed ? theme.background.negative : theme.background.positive,
82
+ color: theme.barTextColor,
83
+ }),
84
+ )
@@ -1,13 +1,13 @@
1
1
  import React from 'react'
2
2
  import { addons, types } from 'storybook/manager-api'
3
- import { VisPanel } from './components/vis_panel.tsx'
4
- import { NAME, VIS_PANEL_ID } from './shared/contants.ts'
3
+ import { VisPanel } from '../components/vis_panel.tsx'
4
+ import { NAME, VIS_PANEL_ID } from '../shared/constants.ts'
5
5
  import {
6
6
  IMAGE_SNAPSHOT_RESULTS_RESPONSE,
7
7
  requestImageSnapshotResults,
8
8
  type ImageSnapshotResults,
9
9
  type VisEvent,
10
- } from './shared/events.ts'
10
+ } from '../shared/events.ts'
11
11
 
12
12
  // Register the addon
13
13
  addons.register(NAME, (api) => {
@@ -0,0 +1 @@
1
+ import '../shared/global_matcher_augment.ts'
@@ -0,0 +1,2 @@
1
+ export * from '../node/define_storybook_vis.ts'
2
+ export * from '../node/define_storybook_vis_options.ts'
@@ -1,8 +1,8 @@
1
1
  import type { Channel } from 'storybook/internal/channels'
2
- import { createStorybookVisServer } from './server/create_storybook_vis_server.ts'
3
- import type { StorybookVisOptions } from './server/types.ts'
4
- import { NAME } from './shared/contants.ts'
5
- import { IMAGE_SNAPSHOT_RESULTS_REQUEST, IMAGE_SNAPSHOT_RESULTS_RESPONSE, type VisEvent } from './shared/events.ts'
2
+ import { createStorybookVisServer } from '../server/create_storybook_vis_server.ts'
3
+ import type { StorybookVisOptions } from '../server/types.ts'
4
+ import { NAME } from '../shared/constants.ts'
5
+ import { IMAGE_SNAPSHOT_RESULTS_REQUEST, IMAGE_SNAPSHOT_RESULTS_RESPONSE, type VisEvent } from '../shared/events.ts'
6
6
 
7
7
  export const experimental_serverChannel = async (channel: Channel, options: StorybookVisOptions) => {
8
8
  const server = createStorybookVisServer(options)
@@ -0,0 +1,2 @@
1
+ export { trimCommonFolder } from 'vitest-plugin-vis/config'
2
+ export { storybookVis } from '../vitest-plugin/storybook_vis.ts'
@@ -1,10 +1,10 @@
1
1
  // `storybook-addon-vis/vitest-setup` provides code needed in `vitest.setup.ts`.
2
- import './client/storybook/expect_extend.ts'
3
- import './shared/global_matcher_augment.ts'
2
+ import '../client/storybook/expect_extend.ts'
3
+ import '../shared/global_matcher_augment.ts'
4
4
 
5
5
  import { createVis } from 'vitest-plugin-vis/setup-api'
6
- import { commands } from './client/vitest_proxy.ts'
6
+ import { commands } from '../client/vitest_proxy.ts'
7
7
 
8
8
  export const vis = createVis<{ tags: string[] }>(commands)
9
9
  export { setAutoSnapshotOptions } from 'vitest-plugin-vis'
10
- export { visAnnotations } from './preview/vis_annotation.ts'
10
+ export { visAnnotations } from '../preview/vis_annotation.ts'
package/src/index.ts CHANGED
@@ -23,13 +23,20 @@ export default (options: SetupVisOptions = { auto: false }) => {
23
23
  tags: options.auto ? ['snapshot'] : [],
24
24
  async beforeAll() {
25
25
  matcher = autoSnapshotMatcher(commands, expect)
26
+ const suiteDefaults =
27
+ options?.createMissingBaseline !== undefined
28
+ ? { createMissingBaseline: options.createMissingBaseline }
29
+ : undefined
26
30
  if (typeof options?.auto === 'function') {
27
- matcherFn = matcher.createMatcher({
28
- auto: options.auto,
29
- })
31
+ matcherFn = matcher.createMatcher(
32
+ {
33
+ auto: options.auto,
34
+ },
35
+ suiteDefaults,
36
+ )
30
37
  } else if (typeof options?.auto === 'object') {
31
- matcherFn = matcher.createMatcher(options.auto)
32
- } else matcherFn = matcher.createMatcher({ async auto() {} })
38
+ matcherFn = matcher.createMatcher(options.auto, suiteDefaults)
39
+ } else matcherFn = matcher.createMatcher({ async auto() {} }, suiteDefaults)
33
40
 
34
41
  await matcher.setup()
35
42
  await setAutoSnapshotOptions(true)
package/src/overview.mdx CHANGED
@@ -36,7 +36,7 @@ Please refer to its documentation for installation and setup instructions.
36
36
  To setup [storybook-addon-vis][storybook-addon-vis], you need to do the following:
37
37
 
38
38
  - Add the `storybookVis` plugin in [Vitest] along with the `storybookTest` plugin.
39
- - Configure visual testing in `vitest.setup.ts` (and `.storybook/preview.ts` if you are writing your stories in CSF Next).
39
+ - Configure visual testing in `vitest.setup.ts` and/or `.storybook/preview.ts` (see [Storybook 10.3+ and Vitest project annotations](#storybook-103-and-vitest-project-annotations); with CSF Next, prefer preview-only setup as in [Basic Setup for CSF Next](#basic-setup-for-csf-next)).
40
40
  - Add [storybook-addon-vis][storybook-addon-vis] addon to your [Storybook] configuration in `.storybook/main.ts`.
41
41
  - Ignore snapshot folders in your `.gitignore` file.
42
42
 
@@ -102,6 +102,21 @@ beforeAll(annotations.beforeAll)
102
102
  vis.setup()
103
103
  ```
104
104
 
105
+ <a id="storybook-103-and-vitest-project-annotations" />
106
+
107
+ ### Storybook 10.3+ and Vitest project annotations
108
+
109
+ From **Storybook 10.3** onward, [`@storybook/addon-vitest`][storybook-vitest-addon] often injects project annotations for you (for example via `setProjectAnnotations(getProjectAnnotations())`), so you may not need a hand-maintained `vitest.setup.ts` in every project. See the [Storybook Vitest integration docs][storybook-vitest-addon] for the current recommendation.
110
+
111
+ **If you are not using CSF Next** (or have not moved your preview config to `definePreview`), you may still need to adjust your setup: **do not** rely only on merging `visAnnotations` inside `setProjectAnnotations([...])` in `vitest.setup.ts`. Put the same lifecycle hooks in **`.storybook/preview.ts`** instead, so `getProjectAnnotations()` includes them when the Vitest addon builds annotations from your preview stack.
112
+
113
+ You can do that in either of these ways:
114
+
115
+ 1. **Recommended:** use `definePreview({ addons: [addonVis({ auto: true })] })` in `preview.ts` even while your stories stay CSF 3—the pattern is the same as in [Basic Setup for CSF Next](#basic-setup-for-csf-next).
116
+ 2. **Minimal migration:** import `visAnnotations` from `storybook-addon-vis/vitest-setup` and spread them into a classic preview export, for example `export default { ...visAnnotations, tags: ['snapshot'] }`, if you are not ready for `definePreview`.
117
+
118
+ You may still need `vis.setup()` and the `storybookVis()` Vitest plugin depending on your project; this note is only about **where** `visAnnotations` is merged (preview vs Vitest setup).
119
+
105
120
  For [Storybook], you need to add the addon to your `.storybook/main.ts`:
106
121
  ```ts
107
122
  // .storybook/main.ts
@@ -169,6 +184,12 @@ Note that the `__vis__/*/__baselines__` should not be ignored,
169
184
  as it is used to store the baseline images.
170
185
  They should be committed to your repository.
171
186
 
187
+ ### First-run baselines (`createMissingBaseline` vs `updateSnapshot`)
188
+
189
+ In **vitest-plugin-vis** (and when using the same client APIs outside Storybook’s Vitest bridge), `createMissingBaseline: true` on `toMatchImageSnapshot` / `page.toMatchImageSnapshot`, or `vis.setup({ createMissingBaseline: true, ... })`, can create a missing baseline without passing `-u`.
190
+
191
+ When running **Storybook + Vitest browser mode** through this addon, matcher options are serialized over RPC; custom fields such as `createMissingBaseline` may not reach the server. In that setup, use Vitest’s snapshot update mode instead (for example temporarily set `server.config.snapshotOptions.updateSnapshot = 'all'` around the first run, or run with `-u`) to write new baselines—the same mechanism as a normal snapshot update.
192
+
172
193
  ### TypeScript Configuration
173
194
 
174
195
  If you want to do manual snapshot testing, you need to tell TypeScript about the matcher.
@@ -8,6 +8,7 @@ import {
8
8
  BASELINE_DIR,
9
9
  DIFF_DIR,
10
10
  getSnapshotRootDir,
11
+ resolveSnapshotSubpathWithinLimits,
11
12
  SNAPSHOT_ROOT_DIR,
12
13
  trimCommonFolder,
13
14
  } from 'vitest-plugin-vis/server-utils'
@@ -36,7 +37,13 @@ export function createStorybookVisServer(options: StorybookVisOptions) {
36
37
  : memoize(({ subpath }: { subpath: string }) =>
37
38
  trimCommonFolder(subpath.startsWith('./') ? subpath.slice(2) : subpath),
38
39
  )
39
- const snapshotSubpath = snapshotSubpathFn({ subpath: importPath })
40
+ const snapshotSubpathRaw = snapshotSubpathFn({ subpath: importPath })
41
+ const snapshotBaselineRootAbs = resolve(snapshotRootDir, BASELINE_DIR)
42
+ const snapshotSubpath = resolveSnapshotSubpathWithinLimits({
43
+ snapshotBaselineRootAbs,
44
+ rawSnapshotSubpath: snapshotSubpathRaw,
45
+ shortenLongSnapshotPaths: suite.shortenLongSnapshotPaths === true,
46
+ })
40
47
  return {
41
48
  snapshotRootDir,
42
49
  snapshotSubpath,
@@ -9,5 +9,12 @@ export type StorybookVisOptions = {
9
9
  visProjects: Array<{
10
10
  snapshotRootDir: string | ((context: { ci: boolean; platform: string }) => string) | undefined
11
11
  snapshotSubpath?: ((options: { subpath: string }) => string) | undefined
12
+ /**
13
+ * Match Vitest `vis({ shortenLongSnapshotPaths })`. When true, uses the same path rules as
14
+ * the `vitest-plugin-vis`: paths are shortened when their absolute path would exceed safe limits).
15
+ *
16
+ * @default false
17
+ */
18
+ shortenLongSnapshotPaths?: boolean | undefined
12
19
  }>
13
20
  }
@@ -3,13 +3,13 @@
3
3
  */
4
4
  import type { Omit } from 'type-plus'
5
5
  import { type ComparisonMethod, type VisOptions, vis } from 'vitest-plugin-vis/config'
6
- import { NAME } from '../shared/contants.ts'
6
+ import { NAME } from '../shared/constants.ts'
7
7
 
8
8
  export function storybookVis<M extends ComparisonMethod>(options?: Omit<VisOptions<M>, 'preset'> | undefined): any {
9
9
  return {
10
10
  ...vis({
11
11
  ...options,
12
- preset: 'none',
12
+ preset: 'custom',
13
13
  }),
14
14
  name: NAME,
15
15
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"contants-DcocjING.mjs","names":[],"sources":["../src/shared/contants.ts"],"sourcesContent":["export const NAME = 'storybook-addon-vis'\nexport const VIS_PANEL_ID = `${NAME}/vis_panel`\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,eAAe,GAAG,KAAK"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"global_matcher_augment-CYxLwns2.d.ts","names":[],"sources":["../src/shared/global_matcher_augment.ts"],"sourcesContent":[],"mappings":";;;;;IAEwE,UAAA,QAAA,CAAA,CAAA,EAAA,CAAA,CAAA,SAIrC,oBAJqC,CAAA,CAAA;EAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","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":";;;;;;;;;cAiBa,MAAI;;;;;;iBCVD,gBAAA,WAA2B,gDAAmC;;;;;;iBCqB9D,kCAAkC,4BACvC,4BAA4B,KAAK;;;;;;;iBC7B5B,iBAAA;;;cCgBD,qBAEU,oBAAiC,uBAAA,CAAA,aAAA,uBAAA,CAAA,UAAA"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","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, toTaskId, type ImageSnapshotKeyOptions } 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 './client/storybook/expect_extend.ts'\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 { commands, page } from './client/vitest_proxy.ts'\nimport { visAnnotations } from './preview/vis_annotation.ts'\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 }\n\nexport default (options: SetupVisOptions = { auto: false }) => {\n\tlet matcher: ReturnType<typeof autoSnapshotMatcher>\n\tlet matcherFn: () => Promise<void>\n\treturn definePreviewAddon({\n\t\ttags: options.auto ? ['snapshot'] : [],\n\t\tasync beforeAll() {\n\t\t\tmatcher = autoSnapshotMatcher(commands, expect)\n\t\t\tif (typeof options?.auto === 'function') {\n\t\t\t\tmatcherFn = matcher.createMatcher({\n\t\t\t\t\tauto: options.auto,\n\t\t\t\t})\n\t\t\t} else if (typeof options?.auto === 'object') {\n\t\t\t\tmatcherFn = matcher.createMatcher(options.auto)\n\t\t\t} else matcherFn = matcher.createMatcher({ async auto() {} })\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;;;;;ACbpB,mBAAgB,UAA2B,EAAE,MAAM,OAAO,KAAK;CAC9D,IAAI;CACJ,IAAI;AACJ,QAAO,mBAAmB;EACzB,MAAM,QAAQ,OAAO,CAAC,WAAW,GAAG,EAAE;EACtC,MAAM,YAAY;AACjB,aAAU,oBAAoB,UAAU,OAAO;AAC/C,OAAI,OAAO,SAAS,SAAS,WAC5B,aAAY,QAAQ,cAAc,EACjC,MAAM,QAAQ,MACd,CAAC;YACQ,OAAO,SAAS,SAAS,SACnC,aAAY,QAAQ,cAAc,QAAQ,KAAK;OACzC,aAAY,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,CAAC;AAE7D,SAAM,QAAQ,OAAO;AACrB,SAAM,uBAAuB,KAAK;;EAEnC,YAAY;AACX,OAAI,UACH,QAAO,WAAW;;EAGpB,GAAG;EACH,CAAC"}
package/dist/matcher.d.ts DELETED
@@ -1 +0,0 @@
1
- import "./global_matcher_augment-CYxLwns2.js";
@@ -1 +0,0 @@
1
- {"version":3,"file":"node.d.mts","names":[],"sources":["../src/node/define_storybook_vis.ts","../src/node/define_storybook_vis_options.ts"],"sourcesContent":[],"mappings":";;;;;;AA+BA;AAgCA;;;;AC1DA;;;;;;;;;;;;;;;;;;;;;iBD0BgB,kBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCA,kBAAA,UAA4B;;WAA+C;;;;;;AAhC3F;AAgCgB,iBC1DA,yBAAA,CD0D4B,OAA+C,EC1DxC,mBD0D2D,CAAA,EC1DxC,mBD0DwC"}
package/dist/node.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"node.mjs","names":[],"sources":["../src/node/define_storybook_vis.ts","../src/node/define_storybook_vis_options.ts"],"sourcesContent":["import { dirname } from 'node:path'\nimport type { StorybookVisOptions } from '../server/types.ts'\n\n/**\n * Defines the Storybook Visual Testing addon configuration.\n *\n * When called without options, returns the package directory name as a string.\n * When called with options, returns an object containing both the package name and the provided options.\n *\n * @returns When called without options, returns the package directory path as a string.\n *\n * @example\n * ```ts\n * // Without options - returns just the package name\n * const addonName = defineStorybookVis()\n * // Returns: string (package directory path)\n * ```\n *\n * @example\n * ```ts\n * // With options - returns object with name and options\n * const addonConfig = defineStorybookVis({\n * visProjects: [\n * {\n * snapshotRootDir: '__vis__/linux',\n * },\n * ],\n * })\n * // Returns: { name: string, options: StorybookVisOptions }\n * ```\n */\nexport function defineStorybookVis(): string\n/**\n * Defines the Storybook Visual Testing addon configuration with options.\n *\n * @param options - Configuration options for visual testing suites in Storybook.\n * @param options.visProjects - Array of visual testing project configurations.\n * @param options.visProjects[].snapshotRootDir - Root directory for storing snapshots. Can be a string path or a function that returns a path based on CI and platform context.\n * @param options.visProjects[].snapshotSubpath - Optional function to customize the snapshot subdirectory path.\n *\n * @returns An object containing the package name and the provided options.\n *\n * @example\n * ```ts\n * // In .storybook/main.ts\n * import { defineStorybookVis } from 'storybook-addon-vis/node'\n *\n * export default {\n * addons: [\n * defineStorybookVis({\n * visProjects: [\n * {\n * snapshotRootDir: '__vis__/linux',\n * },\n * {\n * snapshotRootDir: '__vis__/local',\n * },\n * ],\n * }),\n * ],\n * }\n * ```\n */\nexport function defineStorybookVis(options: StorybookVisOptions): { name: string; options: StorybookVisOptions }\nexport function defineStorybookVis(options?: StorybookVisOptions | undefined) {\n\tconst name = dirname(import.meta.resolve('storybook-addon-vis', 'package.json'))\n\treturn !options ? name : { name, options }\n}\n","import type { StorybookVisOptions } from '../server/types.ts'\n\n/**\n * Define options for Storybook Visual Testing addon.\n */\nexport function defineStorybookVisOptions(options: StorybookVisOptions) {\n\treturn options\n}\n"],"mappings":";;;AAgEA,SAAgB,mBAAmB,SAA2C;CAC7E,MAAM,OAAO,QAAQ,OAAO,KAAK,QAAQ,uBAAuB,eAAe,CAAC;AAChF,QAAO,CAAC,UAAU,OAAO;EAAE;EAAM;EAAS;;;;;;;;AC7D3C,SAAgB,0BAA0B,SAA8B;AACvE,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"preset.d.mts","names":[],"sources":["../src/preset.ts"],"sourcesContent":[],"mappings":";;;;cAMa,sCAA6C,kBAAkB,wBAAmB,QAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"preset.mjs","names":[],"sources":["../src/server/create_storybook_vis_server.ts","../src/shared/events.ts","../src/preset.ts"],"sourcesContent":["import { globSync } from 'glob'\nimport ci from 'is-ci'\nimport memoize from 'memoize'\nimport { readFileSync } from 'node:fs'\nimport { platform } from 'node:process'\nimport { basename, resolve } from 'pathe'\nimport {\n\tBASELINE_DIR,\n\tDIFF_DIR,\n\tgetSnapshotRootDir,\n\tSNAPSHOT_ROOT_DIR,\n\ttrimCommonFolder,\n} from 'vitest-plugin-vis/server-utils'\nimport type { StorybookVisOptions } from './types.ts'\n\nexport function createStorybookVisServer(options: StorybookVisOptions) {\n\tconst visSuites = options.visProjects ?? [{}]\n\treturn {\n\t\toptions,\n\t\tasync getImageSnapshotResults(name: string, importPath: string) {\n\t\t\treturn visSuites\n\t\t\t\t.map((suite) => {\n\t\t\t\t\tconst snapshotRootDir =\n\t\t\t\t\t\ttypeof suite.snapshotRootDir === 'string'\n\t\t\t\t\t\t\t? suite.snapshotRootDir\n\t\t\t\t\t\t\t: typeof suite.snapshotRootDir === 'function'\n\t\t\t\t\t\t\t\t? memoize(suite.snapshotRootDir)({\n\t\t\t\t\t\t\t\t\t\tci,\n\t\t\t\t\t\t\t\t\t\tplatform,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: memoize(getSnapshotRootDir)(SNAPSHOT_ROOT_DIR)\n\n\t\t\t\t\tconst snapshotSubpathFn =\n\t\t\t\t\t\ttypeof suite.snapshotSubpath === 'function'\n\t\t\t\t\t\t\t? memoize(suite.snapshotSubpath)\n\t\t\t\t\t\t\t: memoize(({ subpath }: { subpath: string }) =>\n\t\t\t\t\t\t\t\t\ttrimCommonFolder(subpath.startsWith('./') ? subpath.slice(2) : subpath),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\tconst snapshotSubpath = snapshotSubpathFn({ subpath: importPath })\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsnapshotRootDir,\n\t\t\t\t\t\tsnapshotSubpath,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.flatMap(({ snapshotRootDir, snapshotSubpath }) => {\n\t\t\t\t\tconst taskId = name.replace(/[^a-z0-9]/gi, '-').toLowerCase()\n\t\t\t\t\tconst taskGlob = `${taskId}-*.png`\n\t\t\t\t\tconst baselineGlob = resolve(snapshotRootDir, BASELINE_DIR, snapshotSubpath, taskGlob)\n\t\t\t\t\tconst diffGlob = resolve(snapshotRootDir, DIFF_DIR, snapshotSubpath, taskGlob)\n\n\t\t\t\t\tconst taskIdRegex = new RegExp(`${taskId}-[^-]*.png$`)\n\t\t\t\t\tconst baselineFiles = globSync(baselineGlob).filter((filePath) => taskIdRegex.test(filePath))\n\t\t\t\t\tconst diffFiles = globSync(diffGlob).filter((filePath) => taskIdRegex.test(filePath))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...baselineFiles.map((filePath) => mapFileToResult(filePath, snapshotRootDir, 'baseline')),\n\t\t\t\t\t\t...diffFiles.map((filePath) => mapFileToResult(filePath, snapshotRootDir, 'diff')),\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t},\n\t}\n}\n\nfunction mapFileToResult(filePath: string, snapshotRootDir: string, type: 'baseline' | 'diff') {\n\treturn {\n\t\tfilePath,\n\t\tfileName: basename(filePath),\n\t\tsnapshotRootDir,\n\t\ttype,\n\t\tbase64: readFileSync(filePath, 'base64'),\n\t}\n}\n","export type VisEvent = ImageSnapshotResultsRequest | ImageSnapshotResultsResponse\n\nexport const IMAGE_SNAPSHOT_RESULTS_REQUEST = 'IMAGE_SNAPSHOT_RESULTS_REQUEST'\nexport const IMAGE_SNAPSHOT_RESULTS_RESPONSE = 'IMAGE_SNAPSHOT_RESULTS_RESPONSE'\n\nexport function requestImageSnapshotResults({ name, importPath }: { name: string; importPath: string }) {\n\treturn {\n\t\ttype: IMAGE_SNAPSHOT_RESULTS_REQUEST,\n\t\tname,\n\t\timportPath,\n\t}\n}\n\nexport type ImageSnapshotResultsRequest = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_REQUEST\n\tname: string\n\timportPath: string\n}\n\nexport type ImageSnapshotResultsResponse = {\n\ttype: typeof IMAGE_SNAPSHOT_RESULTS_RESPONSE\n\tname: string\n\timportPath: string\n\tresults: ImageSnapshotResults[]\n}\n\nexport type ImageSnapshotResults = {\n\tfilePath: string\n\tfileName: string\n\tsnapshotRootDir: string\n\ttype: 'baseline' | 'diff' | 'result'\n\tbase64: string\n}\n","import type { Channel } from 'storybook/internal/channels'\nimport { createStorybookVisServer } from './server/create_storybook_vis_server.ts'\nimport type { StorybookVisOptions } from './server/types.ts'\nimport { NAME } from './shared/contants.ts'\nimport { IMAGE_SNAPSHOT_RESULTS_REQUEST, IMAGE_SNAPSHOT_RESULTS_RESPONSE, type VisEvent } from './shared/events.ts'\n\nexport const experimental_serverChannel = async (channel: Channel, options: StorybookVisOptions) => {\n\tconst server = createStorybookVisServer(options)\n\n\tchannel.on(NAME, async (event: VisEvent) => {\n\t\tif (event.type === IMAGE_SNAPSHOT_RESULTS_REQUEST) {\n\t\t\tconst results = await server.getImageSnapshotResults(event.name, event.importPath)\n\t\t\tchannel.emit(NAME, {\n\t\t\t\ttype: IMAGE_SNAPSHOT_RESULTS_RESPONSE,\n\t\t\t\tname: event.name,\n\t\t\t\timportPath: event.importPath,\n\t\t\t\tresults,\n\t\t\t})\n\t\t}\n\t})\n\n\treturn channel\n}\n"],"mappings":";;;;;;;;;;AAeA,SAAgB,yBAAyB,SAA8B;CACtE,MAAM,YAAY,QAAQ,eAAe,CAAC,EAAE,CAAC;AAC7C,QAAO;EACN;EACA,MAAM,wBAAwB,MAAc,YAAoB;AAC/D,UAAO,UACL,KAAK,UAAU;AAkBf,WAAO;KACN,iBAjBA,OAAO,MAAM,oBAAoB,WAC9B,MAAM,kBACN,OAAO,MAAM,oBAAoB,aAChC,QAAQ,MAAM,gBAAgB,CAAC;MAC/B;MACA;MACA,CAAC,GACD,QAAQ,mBAAmB,CAAC,kBAAkB;KAWlD,kBARA,OAAO,MAAM,oBAAoB,aAC9B,QAAQ,MAAM,gBAAgB,GAC9B,SAAS,EAAE,cACX,iBAAiB,QAAQ,WAAW,KAAK,GAAG,QAAQ,MAAM,EAAE,GAAG,QAAQ,CACvE,EACsC,EAAE,SAAS,YAAY,CAAC;KAIjE;KACA,CACD,SAAS,EAAE,iBAAiB,sBAAsB;IAClD,MAAM,SAAS,KAAK,QAAQ,eAAe,IAAI,CAAC,aAAa;IAC7D,MAAM,WAAW,GAAG,OAAO;IAC3B,MAAM,eAAe,QAAQ,iBAAiB,cAAc,iBAAiB,SAAS;IACtF,MAAM,WAAW,QAAQ,iBAAiB,UAAU,iBAAiB,SAAS;IAE9E,MAAM,8BAAc,IAAI,OAAO,GAAG,OAAO,aAAa;IACtD,MAAM,gBAAgB,SAAS,aAAa,CAAC,QAAQ,aAAa,YAAY,KAAK,SAAS,CAAC;IAC7F,MAAM,YAAY,SAAS,SAAS,CAAC,QAAQ,aAAa,YAAY,KAAK,SAAS,CAAC;AACrF,WAAO,CACN,GAAG,cAAc,KAAK,aAAa,gBAAgB,UAAU,iBAAiB,WAAW,CAAC,EAC1F,GAAG,UAAU,KAAK,aAAa,gBAAgB,UAAU,iBAAiB,OAAO,CAAC,CAClF;KACA;;EAEJ;;AAGF,SAAS,gBAAgB,UAAkB,iBAAyB,MAA2B;AAC9F,QAAO;EACN;EACA,UAAU,SAAS,SAAS;EAC5B;EACA;EACA,QAAQ,aAAa,UAAU,SAAS;EACxC;;;;;ACnEF,MAAa,iCAAiC;AAC9C,MAAa,kCAAkC;;;;ACG/C,MAAa,6BAA6B,OAAO,SAAkB,YAAiC;CACnG,MAAM,SAAS,yBAAyB,QAAQ;AAEhD,SAAQ,GAAG,MAAM,OAAO,UAAoB;AAC3C,MAAI,MAAM,SAAS,gCAAgC;GAClD,MAAM,UAAU,MAAM,OAAO,wBAAwB,MAAM,MAAM,MAAM,WAAW;AAClF,WAAQ,KAAK,MAAM;IAClB,MAAM;IACN,MAAM,MAAM;IACZ,YAAY,MAAM;IAClB;IACA,CAAC;;GAEF;AAEF,QAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-BG2k_RS_.d.mts","names":[],"sources":["../src/server/types.ts"],"sourcesContent":[],"mappings":";;AAOA;;;;;;KAAY,mBAAA;eACE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"vis_annotation-DqZTkmEN.js","names":["toMatchImageSnapshot"],"sources":["../src/client/page/to_match_image_snapshot.ts","../src/client/vitest_proxy.ts","../src/client/expect/to_match_image_snapshot.ts","../src/client/storybook/expect_extend.ts","../src/client/storybook/tags.ts","../src/preview/vis_annotation.ts"],"sourcesContent":["import {\n\ttype ComparisonMethod,\n\ttype ToMatchPageImageSnapshotOptions,\n\tmatchPageImageSnapshotAction,\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 { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'\nimport type { BrowserCommands, BrowserPage } from 'vitest/browser'\nimport { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'\n\nlet browserContext: Awaited<typeof import('vitest/browser')>\nlet vitestSuite: Awaited<typeof import('vitest/suite')>\n\nif ((globalThis as any).__vitest_browser__) {\n\timport('vitest/browser').then((m) => {\n\t\tm.page.extend({ toMatchImageSnapshot })\n\t\tbrowserContext = m\n\t})\n\timport('vitest/suite').then((m) => {\n\t\tvitestSuite = 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\tvitestSuite?.getCurrentTest() as (ReturnType<typeof vitestSuite.getCurrentTest> & SnapshotTestMeta) | undefined\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport {\n\ttype ComparisonMethod,\n\ttype ToMatchImageSnapshotOptions,\n\tmatchImageSnapshotAction,\n\tsuccess,\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","import { expect } from 'storybook/test'\nimport { toMatchImageSnapshot } from '../expect/to_match_image_snapshot.ts'\n\nexpect.extend({ toMatchImageSnapshot })\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 { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\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":";;;;;AAQA,SAAgBA,uBACf,SACC;CACD,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,SAAS;;AAGnC,QAAO,6BAA6B,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;ACbvE,IAAI;AACJ,IAAI;AAEJ,IAAK,WAAmB,oBAAoB;AAC3C,QAAO,kBAAkB,MAAM,MAAM;AACpC,IAAE,KAAK,OAAO,EAAE,8CAAsB,CAAC;AACvC,mBAAiB;GAChB;AACF,QAAO,gBAAgB,MAAM,MAAM;AAClC,gBAAc;GACb;;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,aAAa,gBAAgB;;;;ACxB9B,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;;;;;ACrBhG,OAAO,OAAO,EAAE,sBAAsB,CAAC;;;;ACHvC,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;;;;;ACD1B,MAAa,iBAAiB,EAC7B,WAAW,KAAK;CACf,MAAM,OAAO,gBAAgB;AAE7B,0BAAuB;EACtB,QAAQ,kBAAkB,IAAI,KAAK;EACnC,GAAG,IAAI,YAAY;EACnB,MAAM,IAAI;EACV,GAAG,MAAM,KAAK;EACd,CAAC;GAEH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"vitest-plugin.d.mts","names":[],"sources":["../src/vitest-plugin/storybook_vis.ts"],"sourcesContent":[],"mappings":";;;;;AAOuC,iBAAvB,YAAuB,CAAA,UAAA,gBAAA,CAAA,CAAA,OAAA,CAAA,EAA4B,IAA5B,CAAiC,UAAjC,CAA4C,CAA5C,CAAA,EAAA,QAAA,CAAA,GAAA,SAAA,CAAA,EAAA,GAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"vitest-plugin.mjs","names":[],"sources":["../src/vitest-plugin/storybook_vis.ts"],"sourcesContent":["/**\n * Return type is `any` to support different Vitest and Vite versions.\n */\nimport type { Omit } from 'type-plus'\nimport { type ComparisonMethod, type VisOptions, vis } from 'vitest-plugin-vis/config'\nimport { NAME } from '../shared/contants.ts'\n\nexport function storybookVis<M extends ComparisonMethod>(options?: Omit<VisOptions<M>, 'preset'> | undefined): any {\n\treturn {\n\t\t...vis({\n\t\t\t...options,\n\t\t\tpreset: 'none',\n\t\t}),\n\t\tname: NAME,\n\t}\n}\n"],"mappings":";;;;AAOA,SAAgB,aAAyC,SAA0D;AAClH,QAAO;EACN,GAAG,IAAI;GACN,GAAG;GACH,QAAQ;GACR,CAAC;EACF,MAAM;EACN"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"vitest-setup.d.ts","names":[],"sources":["../src/preview/vis_annotation.ts","../src/vitest-setup.ts"],"sourcesContent":[],"mappings":";;;;;;cAKa;kBAWoC,uBAAA,CAAA,kBAAA,uBAAA,CAAA,IAAA;;;;cCTpC,KAA6C,4BAAA,CAA1C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"vitest-setup.js","names":[],"sources":["../src/vitest-setup.ts"],"sourcesContent":["// `storybook-addon-vis/vitest-setup` provides code needed in `vitest.setup.ts`.\nimport './client/storybook/expect_extend.ts'\nimport './shared/global_matcher_augment.ts'\n\nimport { createVis } from 'vitest-plugin-vis/setup-api'\nimport { commands } from './client/vitest_proxy.ts'\n\nexport const vis = createVis<{ tags: string[] }>(commands)\nexport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nexport { visAnnotations } from './preview/vis_annotation.ts'\n"],"mappings":";;;;;AAOA,MAAa,MAAM,UAA8B,SAAS"}
package/src/matcher.ts DELETED
@@ -1 +0,0 @@
1
- import './shared/global_matcher_augment.ts'
package/src/node.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './node/define_storybook_vis.ts'
2
- export * from './node/define_storybook_vis_options.ts'
package/src/testing.ts DELETED
@@ -1 +0,0 @@
1
- export * from 'vitest-plugin-vis/testing'
@@ -1,2 +0,0 @@
1
- export { trimCommonFolder } from 'vitest-plugin-vis/config'
2
- export { storybookVis } from './vitest-plugin/storybook_vis.ts'
File without changes
File without changes
File without changes