{"version":3,"file":"index.mjs","names":["waitForStableMetrics","waitForStableMetricsBase"],"sources":["../src/hooks/animation.ts","../src/hooks/removal.ts","../src/hooks/masking.ts","../src/wait-for-stable.ts","../src/screenshot.ts"],"sourcesContent":["import type { NodeScreenshotHook } from './types';\n\n/**\n * Creates hook that disables CSS animations and transitions during screenshot capture using Playwright\n */\nexport const createAnimationsHook = (): NodeScreenshotHook => ({\n  async setup(page) {\n    await page.evaluate(() => {\n      const style = document.createElement('style');\n      style.innerHTML = `\n        *,\n        *::before,\n        *::after {\n          transition: none !important;\n          animation: none !important;\n        }\n      `;\n      style.id = '::x-storycap-animations';\n      document.head.appendChild(style);\n    });\n  },\n\n  async postCapture(page) {\n    await page.evaluate(() => {\n      document.getElementById('::x-storycap-animations')?.remove();\n    });\n  },\n});\n","import type { Page } from 'playwright';\nimport type { NodeScreenshotHook } from './types';\n\nconst remove = async (page: Page, selector: string) => {\n  await page.evaluate(\n    ([selector]) => {\n      document.querySelectorAll(selector!).forEach((el) => {\n        el.remove();\n      });\n    },\n    [selector],\n  );\n};\n\n/**\n * Creates hook that removes DOM elements matching the selector before screenshot capture using Playwright\n */\nexport const createRemovalHook = (selector: string): NodeScreenshotHook => ({\n  async setup(page) {\n    await remove(page, selector);\n  },\n\n  async preCapture(page) {\n    await remove(page, selector);\n  },\n});\n","import type { ScreenshotMaskConfig } from '@storycap-testrun/internal';\nimport type { NodeScreenshotHook } from './types';\n\n/**\n * Creates hook that overlays colored masks on elements matching the selector using Playwright\n */\nexport const createMaskingHook = (\n  config: ScreenshotMaskConfig,\n): NodeScreenshotHook => ({\n  async preCapture(page) {\n    await page.evaluate(\n      ([selector, color]) => {\n        document.querySelectorAll(selector!).forEach((el) => {\n          const rect = el.getBoundingClientRect();\n          const mask = document.createElement('x-storycap-mask');\n          mask.style.position = 'absolute';\n          mask.style.top = `${rect.top}px`;\n          mask.style.left = `${rect.left}px`;\n          mask.style.zIndex = 'calc(infinity)';\n          mask.style.display = 'block';\n          mask.style.width = `${Math.ceil(rect.width)}px`;\n          mask.style.height = `${Math.ceil(rect.height)}px`;\n          mask.style.pointerEvents = 'none';\n          mask.style.background = color!;\n          document.body.appendChild(mask);\n        });\n      },\n      [config.selector, config.color],\n    );\n  },\n\n  postCapture: async (page) => {\n    await page.evaluate(() => {\n      document.querySelectorAll('x-storycap-mask').forEach((el) => {\n        el.remove();\n      });\n    });\n  },\n});\n","import type { Page } from 'playwright';\nimport type { NodeScreenshotContext } from './context';\nimport { waitForStableMetrics as waitForStableMetricsBase } from '@storycap-testrun/internal';\nimport { waitForPageReady } from '@storybook/test-runner';\n\nconst waitForStableMetrics = async (\n  page: Page,\n  context: NodeScreenshotContext,\n  retries: number,\n) => {\n  const client = await page.context().newCDPSession(page);\n  await waitForStableMetricsBase(client, retries, context.id);\n};\n\n/**\n * Waits for page to be stable with metrics monitoring (Chromium only) or basic page ready state using Playwright\n */\nexport const waitForStable = async (\n  page: Page,\n  context: NodeScreenshotContext,\n  {\n    enabled,\n    retries,\n  }: {\n    enabled: boolean;\n    retries: number;\n  },\n): Promise<void> => {\n  const name = page.context().browser()?.browserType().name();\n\n  if (enabled && name === 'chromium') {\n    await waitForPageReady(page);\n    await waitForStableMetrics(page, context, retries);\n  } else {\n    if (enabled) {\n      console.warn(\n        'Prevention of flakiness through metrics is supported only in Chromium',\n      );\n    }\n    await waitForPageReady(page);\n  }\n};\n","import * as path from 'node:path';\nimport type { TestContext } from '@storybook/test-runner';\nimport { getStoryContext } from '@storybook/test-runner';\nimport type { Page } from 'playwright';\nimport type { NodeScreenshotOptions } from './options';\nimport type { NodeScreenshotContext } from './context';\nimport {\n  createScreenshotFunction,\n  resolveScreenshotFilename,\n  type ScreenshotAdapter,\n  type ScreenshotOutputOptions,\n} from '@storycap-testrun/internal';\nimport { createAnimationsHook } from './hooks/animation';\nimport { createRemovalHook } from './hooks/removal';\nimport { createMaskingHook } from './hooks/masking';\nimport { waitForStable } from './wait-for-stable';\nimport { createHash } from 'node:crypto';\n\n/**\n * Creates screenshot adapter for Node.js environment with Storybook test-runner integration\n * TODO: unit test\n */\nexport const createNodeScreenshotAdapter = (\n  output: Required<ScreenshotOutputOptions<NodeScreenshotContext>>,\n): ScreenshotAdapter<Page, TestContext, NodeScreenshotContext> => ({\n  createContext: (context) => ({\n    id: context.id,\n    title: context.title,\n    name: context.name,\n  }),\n\n  getParameters: async (page, context) => {\n    const { parameters } = await getStoryContext(page, context);\n    return parameters['screenshot'] ?? {};\n  },\n\n  resolveFilepath: async (context) => {\n    return path.join(output.dir, resolveScreenshotFilename(output, context));\n  },\n\n  createHash: async (data) => {\n    return createHash('sha256').update(data).digest('hex');\n  },\n\n  waitForStable: async (page, context, options) => {\n    await waitForStable(page, context, options);\n  },\n\n  takeScreenshot: async (page, filepath, options) => {\n    const data = await page.screenshot({\n      path: filepath,\n      animations: 'disabled',\n      caret: 'hide',\n      fullPage: options.fullPage,\n      omitBackground: options.omitBackground,\n      scale: options.scale,\n      type: options.type,\n    });\n    return data;\n  },\n\n  createAnimationsHook,\n  createRemovalHook,\n  createMaskingHook,\n});\n\n/**\n * Captures screenshot in Node.js environment using Playwright and Storybook test context\n */\nexport const screenshot = async (\n  page: Page,\n  context: TestContext,\n  options: NodeScreenshotOptions = {},\n): Promise<void> => {\n  const output = {\n    dir: path.join(process.cwd(), '__screenshots__'),\n    file: path.join('[title]', '[name].png'),\n    ...options.output,\n  };\n\n  const adapter = createNodeScreenshotAdapter(output);\n  const fn = createScreenshotFunction(adapter);\n\n  await fn(page, context, options);\n};\n"],"mappings":"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"}