storybook-addon-vis 4.2.2 → 4.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/exports/node.d.mts +3 -3
- package/dist/exports/node.d.mts.map +1 -1
- package/dist/exports/node.mjs +2 -1
- package/dist/exports/node.mjs.map +1 -1
- package/dist/exports/preset.mjs +2 -2
- package/dist/exports/preset.mjs.map +1 -1
- package/dist/exports/vitest-setup.mjs +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/index.mjs.map +1 -1
- package/dist/manager.js.map +1 -1
- package/dist/{vis_annotation-Bst4UkfF.mjs → vis_annotation-CZE4YN-u.mjs} +19 -5
- package/dist/vis_annotation-CZE4YN-u.mjs.map +1 -0
- package/package.json +7 -8
- package/preset.js +0 -1
- package/src/client/expect/to_match_image_snapshot.ts +1 -1
- package/src/client/has_image_snapshot.ts +1 -1
- package/src/client/is_vitest_browser.ts +12 -0
- package/src/client/page/to_match_image_snapshot.ts +1 -1
- package/src/client/vitest_proxy.ts +3 -2
- package/src/exports/manager.tsx +1 -1
- package/src/index.ts +9 -2
- package/src/node/define_storybook_vis.ts +5 -4
- package/src/preview/vis_annotation.ts +2 -2
- package/src/server/create_storybook_vis_server.ts +2 -2
- package/dist/vis_annotation-Bst4UkfF.mjs.map +0 -1
package/dist/exports/node.d.mts
CHANGED
|
@@ -8,13 +8,13 @@ import { t as StorybookVisOptions } from "./types-CuNXsk6J.mjs";
|
|
|
8
8
|
* When called without options, returns the package directory name as a string.
|
|
9
9
|
* When called with options, returns an object containing both the package name and the provided options.
|
|
10
10
|
*
|
|
11
|
-
* @returns When called without options, returns the package directory path as a string.
|
|
11
|
+
* @returns When called without options, returns the package directory path as a filesystem path string (e.g., `/path/to/storybook-addon-vis`).
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```ts
|
|
15
|
-
* // Without options - returns just the package
|
|
15
|
+
* // Without options - returns just the package directory path
|
|
16
16
|
* const addonName = defineStorybookVis()
|
|
17
|
-
* // Returns: string (package directory
|
|
17
|
+
* // Returns: string (absolute filesystem path to package directory)
|
|
18
18
|
* ```
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
@@ -1 +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":";;;;;;
|
|
1
|
+
{"version":3,"file":"node.d.mts","names":[],"sources":["../../src/node/define_storybook_vis.ts","../../src/node/define_storybook_vis_options.ts"],"sourcesContent":[],"mappings":";;;;;;AAgCA;AAgCA;;;;AC3DA;;;;;;;;;;;;;;;;;;;;;iBD2BgB,kBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCA,kBAAA,UAA4B;;WAA+C;;;;;;AAhC3F;AAgCgB,iBC3DA,yBAAA,CD2D4B,OAA+C,EC3DxC,mBD2D2D,CAAA,EC3DxC,mBD2DwC"}
|
package/dist/exports/node.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { dirname } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
|
|
3
4
|
//#region src/node/define_storybook_vis.ts
|
|
4
5
|
function defineStorybookVis(options) {
|
|
5
|
-
const name = dirname(import.meta.resolve("storybook-addon-vis
|
|
6
|
+
const name = dirname(fileURLToPath(import.meta.resolve("storybook-addon-vis/package.json")));
|
|
6
7
|
return !options ? name : {
|
|
7
8
|
name,
|
|
8
9
|
options
|
|
@@ -1 +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
|
|
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 { fileURLToPath } from 'node:url'\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 filesystem path string (e.g., `/path/to/storybook-addon-vis`).\n *\n * @example\n * ```ts\n * // Without options - returns just the package directory path\n * const addonName = defineStorybookVis()\n * // Returns: string (absolute filesystem path to package directory)\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(fileURLToPath(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":";;;;AAiEA,SAAgB,mBAAmB,SAA2C;CAC7E,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,QAAQ,mCAAmC,CAAC,CAAC;AAC5F,QAAO,CAAC,UAAU,OAAO;EAAE;EAAM;EAAS;;;;;;;;AC9D3C,SAAgB,0BAA0B,SAA8B;AACvE,QAAO"}
|
package/dist/exports/preset.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as NAME } from "./constants-D_WcloLE.mjs";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { platform } from "node:process";
|
|
2
4
|
import { globSync } from "glob";
|
|
3
5
|
import ci from "is-ci";
|
|
4
6
|
import memoize from "memoize";
|
|
5
|
-
import { readFileSync } from "node:fs";
|
|
6
|
-
import { platform } from "node:process";
|
|
7
7
|
import { basename, resolve } from "pathe";
|
|
8
8
|
import { BASELINE_DIR, DIFF_DIR, SNAPSHOT_ROOT_DIR, getSnapshotRootDir, resolveSnapshotSubpathWithinLimits, trimCommonFolder } from "vitest-plugin-vis/server-utils";
|
|
9
9
|
|
|
@@ -1 +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 {
|
|
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 { readFileSync } from 'node:fs'\nimport { platform } from 'node:process'\nimport { globSync } from 'glob'\nimport ci from 'is-ci'\nimport memoize from 'memoize'\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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as commands, t as visAnnotations } from "../vis_annotation-CZE4YN-u.mjs";
|
|
2
2
|
import { setAutoSnapshotOptions } from "vitest-plugin-vis";
|
|
3
3
|
import { createVis } from "vitest-plugin-vis/setup-api";
|
|
4
4
|
|
package/dist/index.d.mts
CHANGED
|
@@ -31,7 +31,9 @@ declare function defineAutoSnapshotParam<M extends ComparisonMethod>(snapshot: T
|
|
|
31
31
|
declare function isSnapshotEnabled(tags: string[]): boolean;
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/index.d.ts
|
|
34
|
-
declare const _default: (options?: SetupVisOptions
|
|
34
|
+
declare const _default: (options?: SetupVisOptions<{
|
|
35
|
+
tags: string[];
|
|
36
|
+
}>) => storybook_internal_csf0.PreviewAddon<storybook_internal_csf0.AddonTypes>;
|
|
35
37
|
//#endregion
|
|
36
38
|
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, visAnnotations };
|
|
37
39
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/client/vitest_proxy.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/client/storybook/tags.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/client/vitest_proxy.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/client/storybook/tags.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAkBa,MAAI;;;;;;iBCXD,gBAAA,WAA2B,gDAAmC;;;;;;iBCqB9D,kCAAkC,4BACvC,4BAA4B,KAAK;;;;;;;;iBC7B5B,iBAAA;;;cCqBe,kBJH/B,GIKyB;;AJLzB,CAAA,CAAA,EAAa,GIKiE,uBAAA,CAAA,YJG5E,CIHsC,uBAAA,CAAsC,UAAA,CJG5E"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as getCurrentTest, i as commands, n as isSnapshotEnabled, o as page, r as toMatchImageSnapshot, s as isVitestBrowser, t as visAnnotations } from "./vis_annotation-CZE4YN-u.mjs";
|
|
2
2
|
import { definePreviewAddon } from "storybook/internal/csf";
|
|
3
3
|
import { expect } from "storybook/test";
|
|
4
4
|
import { autoSnapshotMatcher, hasImageSnapshotAction, setAutoSnapshotOptions, toTaskId } from "vitest-plugin-vis/client-api";
|
|
@@ -35,12 +35,14 @@ function defineAutoSnapshotParam(snapshot) {
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/index.ts
|
|
38
|
+
expect.extend({ toMatchImageSnapshot });
|
|
38
39
|
var src_default = (options = { auto: false }) => {
|
|
39
40
|
let matcher;
|
|
40
41
|
let matcherFn;
|
|
41
42
|
return definePreviewAddon({
|
|
42
|
-
tags: options.auto ? ["snapshot"] : [],
|
|
43
|
+
tags: options.auto === true ? ["snapshot"] : [],
|
|
43
44
|
async beforeAll() {
|
|
45
|
+
if (!isVitestBrowser()) return;
|
|
44
46
|
matcher = autoSnapshotMatcher(commands, expect);
|
|
45
47
|
const suiteDefaults = options?.createMissingBaseline !== void 0 ? { createMissingBaseline: options.createMissingBaseline } : void 0;
|
|
46
48
|
if (typeof options?.auto === "function") matcherFn = matcher.createMatcher({ auto: options.auto }, suiteDefaults);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/client/ctx.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/index.ts"],"sourcesContent":["import { getCurrentTest } from './vitest_proxy.ts'\n\nexport const ctx = {\n\tgetCurrentTest,\n\t__test__reset() {\n\t\tctx.getCurrentTest = getCurrentTest\n\t},\n}\n","import { hasImageSnapshotAction,
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/client/ctx.ts","../src/client/has_image_snapshot.ts","../src/client/storybook/param.ts","../src/index.ts"],"sourcesContent":["import { getCurrentTest } from './vitest_proxy.ts'\n\nexport const ctx = {\n\tgetCurrentTest,\n\t__test__reset() {\n\t\tctx.getCurrentTest = getCurrentTest\n\t},\n}\n","import { hasImageSnapshotAction, type ImageSnapshotKeyOptions, toTaskId } from 'vitest-plugin-vis/client-api'\nimport { ctx } from './ctx.ts'\nimport { commands } from './vitest_proxy.ts'\n\n/**\n * Check if the snapshot image exists.\n */\nexport function hasImageSnapshot(options?: ImageSnapshotKeyOptions | undefined) {\n\tconst test = ctx.getCurrentTest()\n\tif (!test) return false\n\n\treturn hasImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type {\n\tComparisonMethod,\n\tFailureThresholdOptions,\n\tImageSnapshotCompareOptions,\n\tImageSnapshotKeyOptions,\n\tImageSnapshotSubjectOptions,\n\tImageSnapshotTimeoutOptions,\n\tPixelComparisonOptions,\n\tSsimComparisonOptions,\n\tToMatchImageSnapshotOptions,\n} from 'vitest-plugin-vis/client-api'\n\n// This fix the inferred type cannot be named error\nexport type {\n\tComparisonMethod,\n\tFailureThresholdOptions,\n\tImageSnapshotCompareOptions,\n\tImageSnapshotKeyOptions,\n\tImageSnapshotSubjectOptions,\n\tImageSnapshotTimeoutOptions,\n\tPixelComparisonOptions,\n\tSsimComparisonOptions,\n\tToMatchImageSnapshotOptions,\n}\n\n/**\n * Define snapshot parameter for auto snapshot.\n */\nexport function defineAutoSnapshotParam<M extends ComparisonMethod>(\n\tsnapshot: ToMatchImageSnapshotOptions<M> & ImageSnapshotSubjectOptions,\n) {\n\treturn { snapshot }\n}\n","// `storybook-addon-vis` provides code that can be used in test files.\nimport './shared/global_matcher_augment.ts'\n\nimport { definePreviewAddon } from 'storybook/internal/csf'\nimport { expect } from 'storybook/test'\nimport type { SetupVisOptions } from 'vitest-plugin-vis'\nimport { autoSnapshotMatcher, setAutoSnapshotOptions } from 'vitest-plugin-vis/client-api'\nimport { toMatchImageSnapshot } from './client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from './client/is_vitest_browser.ts'\nimport { commands, page } from './client/vitest_proxy.ts'\nimport { visAnnotations } from './preview/vis_annotation.ts'\n\n// Register at module load time so it's available in Storybook dev mode.\n// (visAnnotations.beforeEach is only wired via vitest's setProjectAnnotations, not in dev mode)\nexpect.extend({ toMatchImageSnapshot })\n\nexport * from 'vitest-plugin-vis'\nexport * from './client/has_image_snapshot.ts'\nexport * from './client/storybook/param.ts'\nexport * from './client/storybook/tags.ts'\n\nexport { page, visAnnotations }\n\nexport default (options: SetupVisOptions<{ tags: string[] }> = { auto: false }) => {\n\tlet matcher: ReturnType<typeof autoSnapshotMatcher>\n\tlet matcherFn: () => Promise<void>\n\treturn definePreviewAddon({\n\t\ttags: options.auto === true ? ['snapshot'] : [],\n\t\tasync beforeAll() {\n\t\t\tif (!isVitestBrowser()) return\n\t\t\tmatcher = autoSnapshotMatcher(commands, expect)\n\t\t\tconst suiteDefaults =\n\t\t\t\toptions?.createMissingBaseline !== undefined\n\t\t\t\t\t? { createMissingBaseline: options.createMissingBaseline }\n\t\t\t\t\t: undefined\n\t\t\tif (typeof options?.auto === 'function') {\n\t\t\t\tmatcherFn = matcher.createMatcher(\n\t\t\t\t\t{\n\t\t\t\t\t\tauto: options.auto,\n\t\t\t\t\t},\n\t\t\t\t\tsuiteDefaults,\n\t\t\t\t)\n\t\t\t} else if (typeof options?.auto === 'object') {\n\t\t\t\tmatcherFn = matcher.createMatcher(options.auto, suiteDefaults)\n\t\t\t} else matcherFn = matcher.createMatcher({ async auto() {} }, suiteDefaults)\n\n\t\t\tawait matcher.setup()\n\t\t\tawait setAutoSnapshotOptions(true)\n\t\t},\n\t\tafterEach() {\n\t\t\tif (matcherFn) {\n\t\t\t\treturn matcherFn()\n\t\t\t}\n\t\t},\n\t\t...visAnnotations,\n\t})\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,MAAM;CAClB;CACA,gBAAgB;AACf,MAAI,iBAAiB;;CAEtB;;;;;;;ACAD,SAAgB,iBAAiB,SAA+C;CAC/E,MAAM,OAAO,IAAI,gBAAgB;AACjC,KAAI,CAAC,KAAM,QAAO;AAElB,QAAO,uBAAuB,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;;;;ACiBjE,SAAgB,wBACf,UACC;AACD,QAAO,EAAE,UAAU;;;;;ACjBpB,OAAO,OAAO,EAAE,sBAAsB,CAAC;AASvC,mBAAgB,UAA+C,EAAE,MAAM,OAAO,KAAK;CAClF,IAAI;CACJ,IAAI;AACJ,QAAO,mBAAmB;EACzB,MAAM,QAAQ,SAAS,OAAO,CAAC,WAAW,GAAG,EAAE;EAC/C,MAAM,YAAY;AACjB,OAAI,CAAC,iBAAiB,CAAE;AACxB,aAAU,oBAAoB,UAAU,OAAO;GAC/C,MAAM,gBACL,SAAS,0BAA0B,SAChC,EAAE,uBAAuB,QAAQ,uBAAuB,GACxD;AACJ,OAAI,OAAO,SAAS,SAAS,WAC5B,aAAY,QAAQ,cACnB,EACC,MAAM,QAAQ,MACd,EACD,cACA;YACS,OAAO,SAAS,SAAS,SACnC,aAAY,QAAQ,cAAc,QAAQ,MAAM,cAAc;OACxD,aAAY,QAAQ,cAAc,EAAE,MAAM,OAAO,IAAI,EAAE,cAAc;AAE5E,SAAM,QAAQ,OAAO;AACrB,SAAM,uBAAuB,KAAK;;EAEnC,YAAY;AACX,OAAI,UACH,QAAO,WAAW;;EAGpB,GAAG;EACH,CAAC"}
|
package/dist/manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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\
|
|
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\ttype ImageSnapshotResults,\n\trequestImageSnapshotResults,\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"}
|
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
import { expect } from "storybook/test";
|
|
2
2
|
import { matchImageSnapshotAction, matchPageImageSnapshotAction, success, toTaskId } from "vitest-plugin-vis/client-api";
|
|
3
|
-
import { isRunningInTest } from "@repobuddy/test";
|
|
4
3
|
import { setAutoSnapshotOptions as setAutoSnapshotOptions$1 } from "vitest-plugin-vis";
|
|
5
4
|
|
|
5
|
+
//#region src/client/is_vitest_browser.ts
|
|
6
|
+
/**
|
|
7
|
+
* Whether the code is running inside a Vitest browser-mode run.
|
|
8
|
+
*
|
|
9
|
+
* This is the signal the addon actually depends on: `commands` and `page` in
|
|
10
|
+
* `vitest_proxy.ts` are only populated when `__vitest_browser__` is set, so any
|
|
11
|
+
* broader "am I under test" check (such as one matching a `HeadlessChrome` user
|
|
12
|
+
* agent) lets a plain headless browser reach the snapshot setup and fail on the
|
|
13
|
+
* empty proxy with `commands.setupVisSuite is not a function`.
|
|
14
|
+
*/
|
|
15
|
+
function isVitestBrowser() {
|
|
16
|
+
return !!globalThis.__vitest_browser__;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
6
20
|
//#region src/client/page/to_match_image_snapshot.ts
|
|
7
21
|
function toMatchImageSnapshot$1(options) {
|
|
8
22
|
const test = getCurrentTest();
|
|
@@ -16,7 +30,7 @@ function toMatchImageSnapshot$1(options) {
|
|
|
16
30
|
//#region src/client/vitest_proxy.ts
|
|
17
31
|
let browserContext;
|
|
18
32
|
let vitest;
|
|
19
|
-
if (
|
|
33
|
+
if (isVitestBrowser()) {
|
|
20
34
|
import("vitest/browser").then((m) => {
|
|
21
35
|
m.page.extend({ toMatchImageSnapshot: toMatchImageSnapshot$1 });
|
|
22
36
|
browserContext = m;
|
|
@@ -58,7 +72,7 @@ function isSnapshotEnabled(tags) {
|
|
|
58
72
|
//#region src/preview/vis_annotation.ts
|
|
59
73
|
let extended = false;
|
|
60
74
|
const visAnnotations = { beforeEach(ctx) {
|
|
61
|
-
if (!
|
|
75
|
+
if (!isVitestBrowser()) return;
|
|
62
76
|
if (!extended) {
|
|
63
77
|
expect.extend({ toMatchImageSnapshot });
|
|
64
78
|
extended = true;
|
|
@@ -73,5 +87,5 @@ const visAnnotations = { beforeEach(ctx) {
|
|
|
73
87
|
} };
|
|
74
88
|
|
|
75
89
|
//#endregion
|
|
76
|
-
export {
|
|
77
|
-
//# sourceMappingURL=vis_annotation-
|
|
90
|
+
export { getCurrentTest as a, commands as i, isSnapshotEnabled as n, page as o, toMatchImageSnapshot as r, isVitestBrowser as s, visAnnotations as t };
|
|
91
|
+
//# sourceMappingURL=vis_annotation-CZE4YN-u.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vis_annotation-CZE4YN-u.mjs","names":["toMatchImageSnapshot"],"sources":["../src/client/is_vitest_browser.ts","../src/client/page/to_match_image_snapshot.ts","../src/client/vitest_proxy.ts","../src/client/expect/to_match_image_snapshot.ts","../src/client/storybook/tags.ts","../src/preview/vis_annotation.ts"],"sourcesContent":["/**\n * Whether the code is running inside a Vitest browser-mode run.\n *\n * This is the signal the addon actually depends on: `commands` and `page` in\n * `vitest_proxy.ts` are only populated when `__vitest_browser__` is set, so any\n * broader \"am I under test\" check (such as one matching a `HeadlessChrome` user\n * agent) lets a plain headless browser reach the snapshot setup and fail on the\n * empty proxy with `commands.setupVisSuite is not a function`.\n */\nexport function isVitestBrowser() {\n\treturn !!(globalThis as any).__vitest_browser__\n}\n","import {\n\ttype ComparisonMethod,\n\tmatchPageImageSnapshotAction,\n\ttype ToMatchPageImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod = 'pixel'>(\n\toptions?: ToMatchPageImageSnapshotOptions<M> | undefined,\n) {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve()\n\t/* v8 ignore end */\n\n\treturn matchPageImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type { BrowserCommands, BrowserPage } from 'vitest/browser'\nimport type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'\nimport { isVitestBrowser } from './is_vitest_browser.ts'\nimport { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'\n\nlet browserContext: Awaited<typeof import('vitest/browser')>\nlet vitest: Awaited<typeof import('vitest')>\n\nif (isVitestBrowser()) {\n\timport('vitest/browser').then((m) => {\n\t\tm.page.extend({ toMatchImageSnapshot })\n\t\tbrowserContext = m\n\t})\n\timport('vitest').then((m) => {\n\t\tvitest = m\n\t})\n}\n\nexport const page = new Proxy<BrowserPage>({} as any, {\n\tget(_target, prop) {\n\t\tconst r = (browserContext?.page as any)?.[prop]\n\t\tif (prop === 'toMatchImageSnapshot' && r === undefined) {\n\t\t\treturn () => {}\n\t\t}\n\t\treturn r\n\t},\n})\n\nexport const commands = new Proxy<BrowserCommands>({} as any, {\n\tget(_target, prop) {\n\t\treturn (browserContext?.commands as any)?.[prop]\n\t},\n})\n\nexport const getCurrentTest = () =>\n\tvitest?.TestRunner.getCurrentTest() as\n\t\t| (ReturnType<typeof vitest.TestRunner.getCurrentTest> & SnapshotTestMeta)\n\t\t| undefined\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport {\n\ttype ComparisonMethod,\n\tmatchImageSnapshotAction,\n\tsuccess,\n\ttype ToMatchImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod>(\n\t/**\n\t * The element or locator to take the snapshot of,\n\t * or the base64 value of the image to compare against.\n\t */\n\tsubject: any,\n\toptions?: ToMatchImageSnapshotOptions<M> | undefined,\n): AsyncExpectationResult {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve(success)\n\t/* v8 ignore end */\n\n\treturn matchImageSnapshotAction(commands, toTaskId(test), subject, options).then(() => success)\n}\n","export function isSnapshotEnabled(tags: string[]) {\n\tconst noSnapshotIndex = tags.lastIndexOf('!snapshot')\n\tconst snapshotIndex = tags.lastIndexOf('snapshot')\n\n\tif (noSnapshotIndex < 0 && snapshotIndex < 0) return false\n\n\treturn noSnapshotIndex < snapshotIndex\n}\n","import type { NamedOrDefaultProjectAnnotations } from 'storybook/internal/types'\nimport { expect } from 'storybook/test'\nimport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { toMatchImageSnapshot } from '../client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from '../client/is_vitest_browser.ts'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nlet extended = false\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\n\t\tif (!isVitestBrowser()) return\n\t\tif (!extended) {\n\t\t\texpect.extend({ toMatchImageSnapshot })\n\t\t\textended = true\n\t\t}\n\t\tconst test = getCurrentTest()\n\n\t\tsetAutoSnapshotOptions({\n\t\t\tenable: isSnapshotEnabled(ctx.tags),\n\t\t\t...ctx.parameters?.snapshot,\n\t\t\ttags: ctx.tags,\n\t\t\t...test?.meta.vis,\n\t\t})\n\t},\n} satisfies NamedOrDefaultProjectAnnotations<any>\n"],"mappings":";;;;;;;;;;;;;;AASA,SAAgB,kBAAkB;AACjC,QAAO,CAAC,CAAE,WAAmB;;;;;ACF9B,SAAgBA,uBACf,SACC;CACD,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,SAAS;;AAGnC,QAAO,6BAA6B,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;ACZvE,IAAI;AACJ,IAAI;AAEJ,IAAI,iBAAiB,EAAE;AACtB,QAAO,kBAAkB,MAAM,MAAM;AACpC,IAAE,KAAK,OAAO,EAAE,8CAAsB,CAAC;AACvC,mBAAiB;GAChB;AACF,QAAO,UAAU,MAAM,MAAM;AAC5B,WAAS;GACR;;AAGH,MAAa,OAAO,IAAI,MAAmB,EAAE,EAAS,EACrD,IAAI,SAAS,MAAM;CAClB,MAAM,KAAK,gBAAgB,QAAe;AAC1C,KAAI,SAAS,0BAA0B,MAAM,OAC5C,cAAa;AAEd,QAAO;GAER,CAAC;AAEF,MAAa,WAAW,IAAI,MAAuB,EAAE,EAAS,EAC7D,IAAI,SAAS,MAAM;AAClB,SAAQ,gBAAgB,YAAmB;GAE5C,CAAC;AAEF,MAAa,uBACZ,QAAQ,WAAW,gBAAgB;;;;ACzBpC,SAAgB,qBAKf,SACA,SACyB;CACzB,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,QAAQ,QAAQ;;AAG1C,QAAO,yBAAyB,UAAU,SAAS,KAAK,EAAE,SAAS,QAAQ,CAAC,WAAW,QAAQ;;;;;ACxBhG,SAAgB,kBAAkB,MAAgB;CACjD,MAAM,kBAAkB,KAAK,YAAY,YAAY;CACrD,MAAM,gBAAgB,KAAK,YAAY,WAAW;AAElD,KAAI,kBAAkB,KAAK,gBAAgB,EAAG,QAAO;AAErD,QAAO,kBAAkB;;;;;ACE1B,IAAI,WAAW;AAEf,MAAa,iBAAiB,EAC7B,WAAW,KAAK;AACf,KAAI,CAAC,iBAAiB,CAAE;AACxB,KAAI,CAAC,UAAU;AACd,SAAO,OAAO,EAAE,sBAAsB,CAAC;AACvC,aAAW;;CAEZ,MAAM,OAAO,gBAAgB;AAE7B,0BAAuB;EACtB,QAAQ,kBAAkB,IAAI,KAAK;EACnC,GAAG,IAAI,YAAY;EACnB,MAAM,IAAI;EACV,GAAG,MAAM,KAAK;EACd,CAAC;GAEH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storybook-addon-vis",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.4",
|
|
4
4
|
"description": "Storybook Vitest visual testing addon",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"image-snapshot",
|
|
@@ -56,21 +56,20 @@
|
|
|
56
56
|
"!**/*.{spec,test,unit,accept,integrate,system,perf,stress,stories,study}.*"
|
|
57
57
|
],
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@repobuddy/test": "^1.0.1",
|
|
60
59
|
"@storybook/icons": "^2.0.0",
|
|
61
60
|
"glob": "^13.0.0",
|
|
62
61
|
"is-ci": "^4.1.0",
|
|
63
62
|
"memoize": "^11.0.0",
|
|
64
63
|
"pathe": "^2.0.3",
|
|
65
64
|
"type-plus": "8.0.0-beta.8",
|
|
66
|
-
"vitest-plugin-vis": "^5.1.
|
|
65
|
+
"vitest-plugin-vis": "^5.1.1"
|
|
67
66
|
},
|
|
68
67
|
"devDependencies": {
|
|
69
68
|
"@repobuddy/storybook": "^2.28.0",
|
|
70
69
|
"@storybook-community/storybook-dark-mode": "^7.1.1",
|
|
71
|
-
"@storybook/addon-docs": "^10.
|
|
72
|
-
"@storybook/addon-vitest": "^10.
|
|
73
|
-
"@storybook/react-vite": "^10.
|
|
70
|
+
"@storybook/addon-docs": "^10.4.1",
|
|
71
|
+
"@storybook/addon-vitest": "^10.4.1",
|
|
72
|
+
"@storybook/react-vite": "^10.4.2",
|
|
74
73
|
"@tailwindcss/cli": "^4.1.7",
|
|
75
74
|
"@tailwindcss/vite": "^4.1.17",
|
|
76
75
|
"@testing-library/react": "^16.0.1",
|
|
@@ -85,11 +84,11 @@
|
|
|
85
84
|
"boxen": "^8.0.1",
|
|
86
85
|
"cross-env": "^10.0.0",
|
|
87
86
|
"dedent": "^1.5.1",
|
|
88
|
-
"npm-run-all2": "^
|
|
87
|
+
"npm-run-all2": "^9.0.1",
|
|
89
88
|
"playwright": "latest",
|
|
90
89
|
"react": "^19.0.0",
|
|
91
90
|
"react-dom": "^19.0.0",
|
|
92
|
-
"storybook": "^10.
|
|
91
|
+
"storybook": "^10.4.2",
|
|
93
92
|
"storybook-addon-tag-badges": "^3.1.0",
|
|
94
93
|
"tailwindcss": "^4.1.14",
|
|
95
94
|
"tsdown": "^0.19.0",
|
package/preset.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { AsyncExpectationResult } from '@vitest/expect'
|
|
2
2
|
import {
|
|
3
3
|
type ComparisonMethod,
|
|
4
|
-
type ToMatchImageSnapshotOptions,
|
|
5
4
|
matchImageSnapshotAction,
|
|
6
5
|
success,
|
|
6
|
+
type ToMatchImageSnapshotOptions,
|
|
7
7
|
toTaskId,
|
|
8
8
|
} from 'vitest-plugin-vis/client-api'
|
|
9
9
|
import { commands, getCurrentTest } from '../vitest_proxy.ts'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasImageSnapshotAction,
|
|
1
|
+
import { hasImageSnapshotAction, type ImageSnapshotKeyOptions, toTaskId } from 'vitest-plugin-vis/client-api'
|
|
2
2
|
import { ctx } from './ctx.ts'
|
|
3
3
|
import { commands } from './vitest_proxy.ts'
|
|
4
4
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the code is running inside a Vitest browser-mode run.
|
|
3
|
+
*
|
|
4
|
+
* This is the signal the addon actually depends on: `commands` and `page` in
|
|
5
|
+
* `vitest_proxy.ts` are only populated when `__vitest_browser__` is set, so any
|
|
6
|
+
* broader "am I under test" check (such as one matching a `HeadlessChrome` user
|
|
7
|
+
* agent) lets a plain headless browser reach the snapshot setup and fail on the
|
|
8
|
+
* empty proxy with `commands.setupVisSuite is not a function`.
|
|
9
|
+
*/
|
|
10
|
+
export function isVitestBrowser() {
|
|
11
|
+
return !!(globalThis as any).__vitest_browser__
|
|
12
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'
|
|
2
1
|
import type { BrowserCommands, BrowserPage } from 'vitest/browser'
|
|
2
|
+
import type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'
|
|
3
|
+
import { isVitestBrowser } from './is_vitest_browser.ts'
|
|
3
4
|
import { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'
|
|
4
5
|
|
|
5
6
|
let browserContext: Awaited<typeof import('vitest/browser')>
|
|
6
7
|
let vitest: Awaited<typeof import('vitest')>
|
|
7
8
|
|
|
8
|
-
if ((
|
|
9
|
+
if (isVitestBrowser()) {
|
|
9
10
|
import('vitest/browser').then((m) => {
|
|
10
11
|
m.page.extend({ toMatchImageSnapshot })
|
|
11
12
|
browserContext = m
|
package/src/exports/manager.tsx
CHANGED
|
@@ -4,8 +4,8 @@ import { VisPanel } from '../components/vis_panel.tsx'
|
|
|
4
4
|
import { NAME, VIS_PANEL_ID } from '../shared/constants.ts'
|
|
5
5
|
import {
|
|
6
6
|
IMAGE_SNAPSHOT_RESULTS_RESPONSE,
|
|
7
|
-
requestImageSnapshotResults,
|
|
8
7
|
type ImageSnapshotResults,
|
|
8
|
+
requestImageSnapshotResults,
|
|
9
9
|
type VisEvent,
|
|
10
10
|
} from '../shared/events.ts'
|
|
11
11
|
|
package/src/index.ts
CHANGED
|
@@ -5,9 +5,15 @@ import { definePreviewAddon } from 'storybook/internal/csf'
|
|
|
5
5
|
import { expect } from 'storybook/test'
|
|
6
6
|
import type { SetupVisOptions } from 'vitest-plugin-vis'
|
|
7
7
|
import { autoSnapshotMatcher, setAutoSnapshotOptions } from 'vitest-plugin-vis/client-api'
|
|
8
|
+
import { toMatchImageSnapshot } from './client/expect/to_match_image_snapshot.ts'
|
|
9
|
+
import { isVitestBrowser } from './client/is_vitest_browser.ts'
|
|
8
10
|
import { commands, page } from './client/vitest_proxy.ts'
|
|
9
11
|
import { visAnnotations } from './preview/vis_annotation.ts'
|
|
10
12
|
|
|
13
|
+
// Register at module load time so it's available in Storybook dev mode.
|
|
14
|
+
// (visAnnotations.beforeEach is only wired via vitest's setProjectAnnotations, not in dev mode)
|
|
15
|
+
expect.extend({ toMatchImageSnapshot })
|
|
16
|
+
|
|
11
17
|
export * from 'vitest-plugin-vis'
|
|
12
18
|
export * from './client/has_image_snapshot.ts'
|
|
13
19
|
export * from './client/storybook/param.ts'
|
|
@@ -15,12 +21,13 @@ export * from './client/storybook/tags.ts'
|
|
|
15
21
|
|
|
16
22
|
export { page, visAnnotations }
|
|
17
23
|
|
|
18
|
-
export default (options: SetupVisOptions = { auto: false }) => {
|
|
24
|
+
export default (options: SetupVisOptions<{ tags: string[] }> = { auto: false }) => {
|
|
19
25
|
let matcher: ReturnType<typeof autoSnapshotMatcher>
|
|
20
26
|
let matcherFn: () => Promise<void>
|
|
21
27
|
return definePreviewAddon({
|
|
22
|
-
tags: options.auto ? ['snapshot'] : [],
|
|
28
|
+
tags: options.auto === true ? ['snapshot'] : [],
|
|
23
29
|
async beforeAll() {
|
|
30
|
+
if (!isVitestBrowser()) return
|
|
24
31
|
matcher = autoSnapshotMatcher(commands, expect)
|
|
25
32
|
const suiteDefaults =
|
|
26
33
|
options?.createMissingBaseline !== undefined
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { dirname } from 'node:path'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
2
3
|
import type { StorybookVisOptions } from '../server/types.ts'
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -7,13 +8,13 @@ import type { StorybookVisOptions } from '../server/types.ts'
|
|
|
7
8
|
* When called without options, returns the package directory name as a string.
|
|
8
9
|
* When called with options, returns an object containing both the package name and the provided options.
|
|
9
10
|
*
|
|
10
|
-
* @returns When called without options, returns the package directory path as a string.
|
|
11
|
+
* @returns When called without options, returns the package directory path as a filesystem path string (e.g., `/path/to/storybook-addon-vis`).
|
|
11
12
|
*
|
|
12
13
|
* @example
|
|
13
14
|
* ```ts
|
|
14
|
-
* // Without options - returns just the package
|
|
15
|
+
* // Without options - returns just the package directory path
|
|
15
16
|
* const addonName = defineStorybookVis()
|
|
16
|
-
* // Returns: string (package directory
|
|
17
|
+
* // Returns: string (absolute filesystem path to package directory)
|
|
17
18
|
* ```
|
|
18
19
|
*
|
|
19
20
|
* @example
|
|
@@ -63,6 +64,6 @@ export function defineStorybookVis(): string
|
|
|
63
64
|
*/
|
|
64
65
|
export function defineStorybookVis(options: StorybookVisOptions): { name: string; options: StorybookVisOptions }
|
|
65
66
|
export function defineStorybookVis(options?: StorybookVisOptions | undefined) {
|
|
66
|
-
const name = dirname(import.meta.resolve('storybook-addon-vis
|
|
67
|
+
const name = dirname(fileURLToPath(import.meta.resolve('storybook-addon-vis/package.json')))
|
|
67
68
|
return !options ? name : { name, options }
|
|
68
69
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { isRunningInTest } from '@repobuddy/test'
|
|
2
1
|
import type { NamedOrDefaultProjectAnnotations } from 'storybook/internal/types'
|
|
3
2
|
import { expect } from 'storybook/test'
|
|
4
3
|
import { setAutoSnapshotOptions } from 'vitest-plugin-vis'
|
|
5
4
|
import { toMatchImageSnapshot } from '../client/expect/to_match_image_snapshot.ts'
|
|
5
|
+
import { isVitestBrowser } from '../client/is_vitest_browser.ts'
|
|
6
6
|
import { isSnapshotEnabled } from '../client/storybook/tags.ts'
|
|
7
7
|
import { getCurrentTest } from '../client/vitest_proxy.ts'
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ let extended = false
|
|
|
10
10
|
|
|
11
11
|
export const visAnnotations = {
|
|
12
12
|
beforeEach(ctx) {
|
|
13
|
-
if (!
|
|
13
|
+
if (!isVitestBrowser()) return
|
|
14
14
|
if (!extended) {
|
|
15
15
|
expect.extend({ toMatchImageSnapshot })
|
|
16
16
|
extended = true
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { platform } from 'node:process'
|
|
1
3
|
import { globSync } from 'glob'
|
|
2
4
|
import ci from 'is-ci'
|
|
3
5
|
import memoize from 'memoize'
|
|
4
|
-
import { readFileSync } from 'node:fs'
|
|
5
|
-
import { platform } from 'node:process'
|
|
6
6
|
import { basename, resolve } from 'pathe'
|
|
7
7
|
import {
|
|
8
8
|
BASELINE_DIR,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vis_annotation-Bst4UkfF.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/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","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 { isRunningInTest } from '@repobuddy/test'\nimport type { NamedOrDefaultProjectAnnotations } from 'storybook/internal/types'\nimport { expect } from 'storybook/test'\nimport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { toMatchImageSnapshot } from '../client/expect/to_match_image_snapshot.ts'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nlet extended = false\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\n\t\tif (!isRunningInTest()) return\n\t\tif (!extended) {\n\t\t\texpect.extend({ toMatchImageSnapshot })\n\t\t\textended = true\n\t\t}\n\t\tconst test = getCurrentTest()\n\n\t\tsetAutoSnapshotOptions({\n\t\t\tenable: isSnapshotEnabled(ctx.tags),\n\t\t\t...ctx.parameters?.snapshot,\n\t\t\ttags: ctx.tags,\n\t\t\t...test?.meta.vis,\n\t\t})\n\t},\n} satisfies NamedOrDefaultProjectAnnotations<any>\n"],"mappings":";;;;;;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;;;;;ACxBhG,SAAgB,kBAAkB,MAAgB;CACjD,MAAM,kBAAkB,KAAK,YAAY,YAAY;CACrD,MAAM,gBAAgB,KAAK,YAAY,WAAW;AAElD,KAAI,kBAAkB,KAAK,gBAAgB,EAAG,QAAO;AAErD,QAAO,kBAAkB;;;;;ACE1B,IAAI,WAAW;AAEf,MAAa,iBAAiB,EAC7B,WAAW,KAAK;AACf,KAAI,CAAC,iBAAiB,CAAE;AACxB,KAAI,CAAC,UAAU;AACd,SAAO,OAAO,EAAE,sBAAsB,CAAC;AACvC,aAAW;;CAEZ,MAAM,OAAO,gBAAgB;AAE7B,0BAAuB;EACtB,QAAQ,kBAAkB,IAAI,KAAK;EACnC,GAAG,IAAI,YAAY;EACnB,MAAM,IAAI;EACV,GAAG,MAAM,KAAK;EACd,CAAC;GAEH"}
|