{"version":3,"file":"vis_annotation-BHBO0X19.mjs","names":["toMatchImageSnapshot","page","commands","cdp","getCurrentTest"],"sources":["../src/client/is_vitest_browser.ts","../src/client/page/to_match_image_snapshot.ts","../src/client/vitest_proxy.ts","../src/client/expect/to_match_image_snapshot.ts","../src/client/storybook/tags.ts","../src/preview/vis_annotation.ts"],"sourcesContent":["/**\n * Whether the code is running inside a Vitest browser-mode run.\n *\n * This is the signal the addon actually depends on: `commands` and `page` in\n * `vitest_proxy.ts` are only populated when `__vitest_browser__` is set, so any\n * broader \"am I under test\" check (such as one matching a `HeadlessChrome` user\n * agent) lets a plain headless browser reach the snapshot setup and fail on the\n * empty proxy with `commands.setupVisSuite is not a function`.\n */\nexport function isVitestBrowser() {\n\treturn !!(globalThis as any).__vitest_browser__\n}\n","import {\n\ttype ComparisonMethod,\n\tmatchPageImageSnapshotAction,\n\ttype ToMatchPageImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod = 'pixel'>(\n\toptions?: ToMatchPageImageSnapshotOptions<M> | undefined,\n) {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve()\n\t/* v8 ignore end */\n\n\treturn matchPageImageSnapshotAction(commands, toTaskId(test), options)\n}\n","import type { BrowserCommands, BrowserPage, CDPSession } from 'vitest/browser'\nimport type { SnapshotTestMeta } from 'vitest-plugin-vis/client-api'\nimport { isVitestBrowser } from './is_vitest_browser.ts'\nimport { toMatchImageSnapshot } from './page/to_match_image_snapshot.ts'\n\ntype BrowserModule = Awaited<typeof import('vitest/browser')>\ntype VitestModule = Awaited<typeof import('vitest')>\n\n/**\n * How the proxy gets hold of the vitest modules.\n *\n * They are loaded dynamically because this module is also reached from a plain\n * Storybook preview, where `vitest` and `vitest/browser` are not available.\n * Passing `undefined` stands for \"not a vitest browser run\": nothing is loaded\n * and the proxies stay empty.\n */\nexport type VitestProxyLoaders = {\n\tloadBrowser: () => Promise<BrowserModule>\n\tloadVitest: () => Promise<VitestModule>\n}\n\n/**\n * Build the `page` / `commands` / `cdp` / `getCurrentTest` proxies over `loaders`.\n *\n * Exported for tests: it is the only way to observe the window between module\n * load and the dynamic imports settling.\n */\nexport function createVitestProxy(loaders: VitestProxyLoaders | undefined) {\n\tlet browserContext: BrowserModule | undefined\n\tlet vitest: VitestModule | undefined\n\n\tconst browserReady = loaders\n\t\t? loaders.loadBrowser().then((m) => {\n\t\t\t\tm.page.extend({ toMatchImageSnapshot })\n\t\t\t\tbrowserContext = m\n\t\t\t})\n\t\t: Promise.resolve()\n\tconst vitestReady = loaders\n\t\t? loaders.loadVitest().then((m) => {\n\t\t\t\tvitest = m\n\t\t\t})\n\t\t: Promise.resolve()\n\tconst ready = Promise.all([browserReady, vitestReady]).then(() => undefined)\n\n\tconst page = new Proxy<BrowserPage>({} as any, {\n\t\tget(_target, prop) {\n\t\t\tconst r = (browserContext?.page as any)?.[prop]\n\t\t\tif (prop === 'toMatchImageSnapshot' && r === undefined) {\n\t\t\t\treturn () => {}\n\t\t\t}\n\t\t\treturn r\n\t\t},\n\t})\n\n\tconst commands = new Proxy<BrowserCommands>({} as any, {\n\t\tget(_target, prop) {\n\t\t\t// Outside a vitest browser run there is nothing to wait for: keep\n\t\t\t// yielding `undefined` so the addon guards stay in charge (#829).\n\t\t\tif (!loaders) return undefined\n\t\t\tif (browserContext) return (browserContext.commands as any)[prop]\n\t\t\t// The import has not settled yet (#835). Commands are async RPC calls,\n\t\t\t// so hand back a function that waits for the module instead of\n\t\t\t// `undefined`, which fails as `<command> is not a function`.\n\t\t\treturn (...args: unknown[]) => browserReady.then(() => (browserContext!.commands as any)[prop](...args))\n\t\t},\n\t})\n\n\t/**\n\t * The Chrome DevTools Protocol session of the current test, like `cdp()` from\n\t * `vitest/browser`, but safe to import from code a plain Storybook preview\n\t * also loads.\n\t *\n\t * Session calls made before the import settles wait for it (#835). CDP is\n\t * available only with the Playwright provider on Chromium.\n\t */\n\tconst cdp = (): CDPSession => {\n\t\tif (!loaders) throw new Error('cdp() is only available in a Vitest browser run.')\n\t\treturn new Proxy<CDPSession>({} as any, {\n\t\t\tget(_target, prop) {\n\t\t\t\treturn (...args: unknown[]) => browserReady.then(() => (browserContext!.cdp() as any)[prop](...args))\n\t\t\t},\n\t\t})\n\t}\n\n\tconst getCurrentTest = () =>\n\t\tvitest?.TestRunner.getCurrentTest() as\n\t\t\t| (ReturnType<VitestModule['TestRunner']['getCurrentTest']> & SnapshotTestMeta)\n\t\t\t| undefined\n\n\t/**\n\t * Resolves once the vitest modules behind `page`, `commands`, and\n\t * `getCurrentTest` are loaded.\n\t *\n\t * `page` and `getCurrentTest` are read synchronously, so hooks that depend on\n\t * them must await this first (#835).\n\t */\n\tconst whenReady = () => ready\n\n\treturn { page, commands, cdp, getCurrentTest, whenReady }\n}\n\nconst proxy = createVitestProxy(\n\tisVitestBrowser() ? { loadBrowser: () => import('vitest/browser'), loadVitest: () => import('vitest') } : undefined,\n)\n\nexport const page = proxy.page\nexport const commands = proxy.commands\nexport const cdp = proxy.cdp\nexport const getCurrentTest = proxy.getCurrentTest\nexport const whenVitestProxyReady = proxy.whenReady\n","import type { AsyncExpectationResult } from '@vitest/expect'\nimport {\n\ttype ComparisonMethod,\n\tmatchImageSnapshotAction,\n\tsuccess,\n\ttype ToMatchImageSnapshotOptions,\n\ttoTaskId,\n} from 'vitest-plugin-vis/client-api'\nimport { commands, getCurrentTest } from '../vitest_proxy.ts'\n\nexport function toMatchImageSnapshot<M extends ComparisonMethod>(\n\t/**\n\t * The element or locator to take the snapshot of,\n\t * or the base64 value of the image to compare against.\n\t */\n\tsubject: any,\n\toptions?: ToMatchImageSnapshotOptions<M> | undefined,\n): AsyncExpectationResult {\n\tconst test = getCurrentTest()\n\n\t/* v8 ignore start: stub as success when not in a test (e.g. in a story) */\n\tif (!test) return Promise.resolve(success)\n\t/* v8 ignore end */\n\n\treturn matchImageSnapshotAction(commands, toTaskId(test), subject, options).then(() => success)\n}\n","export function isSnapshotEnabled(tags: string[]) {\n\tconst noSnapshotIndex = tags.lastIndexOf('!snapshot')\n\tconst snapshotIndex = tags.lastIndexOf('snapshot')\n\n\tif (noSnapshotIndex < 0 && snapshotIndex < 0) return false\n\n\treturn noSnapshotIndex < snapshotIndex\n}\n","import type { NamedOrDefaultProjectAnnotations } from 'storybook/internal/types'\nimport { expect } from 'storybook/test'\nimport { setAutoSnapshotOptions } from 'vitest-plugin-vis'\nimport { toMatchImageSnapshot } from '../client/expect/to_match_image_snapshot.ts'\nimport { isVitestBrowser } from '../client/is_vitest_browser.ts'\nimport { isSnapshotEnabled } from '../client/storybook/tags.ts'\nimport { getCurrentTest } from '../client/vitest_proxy.ts'\n\nlet extended = false\n\nexport const visAnnotations = {\n\tbeforeEach(ctx) {\n\t\tif (!isVitestBrowser()) return\n\t\tif (!extended) {\n\t\t\texpect.extend({ toMatchImageSnapshot })\n\t\t\textended = true\n\t\t}\n\t\tconst test = getCurrentTest()\n\n\t\tsetAutoSnapshotOptions({\n\t\t\tenable: isSnapshotEnabled(ctx.tags),\n\t\t\t...ctx.parameters?.snapshot,\n\t\t\ttags: ctx.tags,\n\t\t\t...test?.meta.vis,\n\t\t})\n\t},\n} satisfies NamedOrDefaultProjectAnnotations<any>\n"],"mappings":";;;;;;;;;;;;;;AASA,SAAgB,kBAAkB;AACjC,QAAO,CAAC,CAAE,WAAmB;;;;;ACF9B,SAAgBA,uBACf,SACC;CACD,MAAM,OAAO,gBAAgB;;AAG7B,KAAI,CAAC,KAAM,QAAO,QAAQ,SAAS;;AAGnC,QAAO,6BAA6B,UAAU,SAAS,KAAK,EAAE,QAAQ;;;;;;;;;;;ACUvE,SAAgB,kBAAkB,SAAyC;CAC1E,IAAI;CACJ,IAAI;CAEJ,MAAM,eAAe,UAClB,QAAQ,aAAa,CAAC,MAAM,MAAM;AAClC,IAAE,KAAK,OAAO,EAAE,8CAAsB,CAAC;AACvC,mBAAiB;GAChB,GACD,QAAQ,SAAS;CACpB,MAAM,cAAc,UACjB,QAAQ,YAAY,CAAC,MAAM,MAAM;AACjC,WAAS;GACR,GACD,QAAQ,SAAS;CACpB,MAAM,QAAQ,QAAQ,IAAI,CAAC,cAAc,YAAY,CAAC,CAAC,WAAW,OAAU;CAE5E,MAAMC,SAAO,IAAI,MAAmB,EAAE,EAAS,EAC9C,IAAI,SAAS,MAAM;EAClB,MAAM,KAAK,gBAAgB,QAAe;AAC1C,MAAI,SAAS,0BAA0B,MAAM,OAC5C,cAAa;AAEd,SAAO;IAER,CAAC;CAEF,MAAMC,aAAW,IAAI,MAAuB,EAAE,EAAS,EACtD,IAAI,SAAS,MAAM;AAGlB,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,eAAgB,QAAQ,eAAe,SAAiB;AAI5D,UAAQ,GAAG,SAAoB,aAAa,WAAY,eAAgB,SAAiB,MAAM,GAAG,KAAK,CAAC;IAEzG,CAAC;;;;;;;;;CAUF,MAAMC,cAAwB;AAC7B,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,mDAAmD;AACjF,SAAO,IAAI,MAAkB,EAAE,EAAS,EACvC,IAAI,SAAS,MAAM;AAClB,WAAQ,GAAG,SAAoB,aAAa,WAAY,eAAgB,KAAK,CAAS,MAAM,GAAG,KAAK,CAAC;KAEtG,CAAC;;CAGH,MAAMC,yBACL,QAAQ,WAAW,gBAAgB;;;;;;;;CAWpC,MAAM,kBAAkB;AAExB,QAAO;EAAE;EAAM;EAAU;EAAK;EAAgB;EAAW;;AAG1D,MAAM,QAAQ,kBACb,iBAAiB,GAAG;CAAE,mBAAmB,OAAO;CAAmB,kBAAkB,OAAO;CAAW,GAAG,OAC1G;AAED,MAAa,OAAO,MAAM;AAC1B,MAAa,WAAW,MAAM;AAC9B,MAAa,MAAM,MAAM;AACzB,MAAa,iBAAiB,MAAM;AACpC,MAAa,uBAAuB,MAAM;;;;ACnG1C,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"}