storybook-addon-vis 3.1.4 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/global_matcher_augment-CYxLwns2.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/manager.js +8 -5
- package/dist/manager.js.map +1 -1
- package/dist/{vis_annotation-DqZTkmEN.js → vis_annotation-B8BqzClA.js} +5 -5
- package/dist/vis_annotation-B8BqzClA.js.map +1 -0
- package/dist/vitest-plugin.mjs +1 -1
- package/dist/vitest-plugin.mjs.map +1 -1
- package/dist/vitest-setup.js +1 -1
- package/package.json +16 -16
- package/src/client/vitest_proxy.ts +6 -4
- package/src/components/vis_panel.tsx +15 -12
- package/src/shared/global_matcher_augment.ts +0 -1
- package/src/vitest-plugin/storybook_vis.ts +1 -1
- package/dist/vis_annotation-DqZTkmEN.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
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,
|
|
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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import "./global_matcher_augment-CYxLwns2.js";
|
|
|
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
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as page, i as getCurrentTest, n as isSnapshotEnabled, r as commands, t as visAnnotations } from "./vis_annotation-
|
|
1
|
+
import { a as page, i as getCurrentTest, n as isSnapshotEnabled, r as commands, t as visAnnotations } from "./vis_annotation-B8BqzClA.js";
|
|
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";
|
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,
|
|
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(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
package/dist/manager.js.map
CHANGED
|
@@ -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,
|
|
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, 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/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;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
|
|
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
|
|
24
|
-
|
|
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 = () =>
|
|
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-
|
|
74
|
+
//# sourceMappingURL=vis_annotation-B8BqzClA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vis_annotation-B8BqzClA.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 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/dist/vitest-plugin.mjs
CHANGED
|
@@ -1 +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/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: '
|
|
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: '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"}
|
package/dist/vitest-setup.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as commands, t as visAnnotations } from "./vis_annotation-
|
|
1
|
+
import { r as commands, t as visAnnotations } from "./vis_annotation-B8BqzClA.js";
|
|
2
2
|
import { setAutoSnapshotOptions } from "vitest-plugin-vis";
|
|
3
3
|
import { createVis } from "vitest-plugin-vis/setup-api";
|
|
4
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storybook-addon-vis",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Storybook Vitest visual testing addon",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"image-snapshot",
|
|
@@ -67,25 +67,25 @@
|
|
|
67
67
|
"memoize": "^11.0.0",
|
|
68
68
|
"pathe": "^2.0.3",
|
|
69
69
|
"type-plus": "8.0.0-beta.8",
|
|
70
|
-
"vitest-plugin-vis": "^
|
|
70
|
+
"vitest-plugin-vis": "^5.0.0"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@repobuddy/storybook": "^2.
|
|
74
|
-
"@storybook-community/storybook-dark-mode": "^7.1.
|
|
75
|
-
"@storybook/addon-docs": "^10.
|
|
76
|
-
"@storybook/addon-vitest": "^10.
|
|
77
|
-
"@storybook/react-vite": "^10.
|
|
73
|
+
"@repobuddy/storybook": "^2.28.0",
|
|
74
|
+
"@storybook-community/storybook-dark-mode": "^7.1.1",
|
|
75
|
+
"@storybook/addon-docs": "^10.3.5",
|
|
76
|
+
"@storybook/addon-vitest": "^10.3.5",
|
|
77
|
+
"@storybook/react-vite": "^10.3.5",
|
|
78
78
|
"@tailwindcss/cli": "^4.1.7",
|
|
79
79
|
"@tailwindcss/vite": "^4.1.17",
|
|
80
80
|
"@testing-library/react": "^16.0.1",
|
|
81
81
|
"@types/react": "^19.2.2",
|
|
82
82
|
"@types/react-dom": "^19.2.1",
|
|
83
83
|
"@vitejs/plugin-react": "^5.1.2",
|
|
84
|
-
"@vitest/browser": "^4.
|
|
85
|
-
"@vitest/browser-playwright": "^4.
|
|
86
|
-
"@vitest/browser-webdriverio": "^4.
|
|
87
|
-
"@vitest/coverage-istanbul": "^4.
|
|
88
|
-
"@vitest/expect": "^4.
|
|
84
|
+
"@vitest/browser": "^4.1.4",
|
|
85
|
+
"@vitest/browser-playwright": "^4.1.4",
|
|
86
|
+
"@vitest/browser-webdriverio": "^4.1.4",
|
|
87
|
+
"@vitest/coverage-istanbul": "^4.1.4",
|
|
88
|
+
"@vitest/expect": "^4.1.4",
|
|
89
89
|
"boxen": "^8.0.1",
|
|
90
90
|
"cross-env": "^10.0.0",
|
|
91
91
|
"dedent": "^1.5.1",
|
|
@@ -93,13 +93,13 @@
|
|
|
93
93
|
"playwright": "latest",
|
|
94
94
|
"react": "^19.0.0",
|
|
95
95
|
"react-dom": "^19.0.0",
|
|
96
|
-
"storybook": "^10.
|
|
97
|
-
"storybook-addon-tag-badges": "^3.0
|
|
96
|
+
"storybook": "^10.3.5",
|
|
97
|
+
"storybook-addon-tag-badges": "^3.1.0",
|
|
98
98
|
"tailwindcss": "^4.1.14",
|
|
99
99
|
"tsdown": "^0.19.0",
|
|
100
100
|
"typescript": "^5.9.3",
|
|
101
|
-
"vite": "^
|
|
102
|
-
"vitest": "^4.
|
|
101
|
+
"vite": "^8.0.0",
|
|
102
|
+
"vitest": "^4.1.4",
|
|
103
103
|
"vitest-browser-react": "^2.0.2",
|
|
104
104
|
"webdriverio": "latest",
|
|
105
105
|
"zx": "^8.0.0"
|
|
@@ -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
|
|
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
|
|
14
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
<
|
|
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
|
-
</
|
|
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 }>(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
+
)
|
|
@@ -4,7 +4,6 @@ import type { ImageSnapshotMatcher } from 'vitest-plugin-vis/client-api'
|
|
|
4
4
|
|
|
5
5
|
declare global {
|
|
6
6
|
namespace jest {
|
|
7
|
-
// biome-ignore lint/correctness/noUnusedVariables: augmentation must have matching type params.
|
|
8
7
|
interface Matchers<R, T> extends ImageSnapshotMatcher {}
|
|
9
8
|
}
|
|
10
9
|
}
|
|
@@ -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"}
|