import { resolve } from "node:path"; import type { Page } from "playwright"; import { testDevices } from "../testDevices"; import { withPlaywright } from "../utils/withPlaywright"; import type { Task } from "./TaskExecutor"; type CaptureCase = { name: string; setup: (page: Page) => Promise; }; export const defineCapture = (options: { href: string; cases?: readonly CaptureCase[]; }) => { const { href, cases = [] } = options; const paths = href .split("/") .map((path) => path.trim()) .filter((path) => path !== ""); const colorSchemes = ["light", "dark"] as const; const captureWithCase = async ( device: (typeof testDevices)[number], colorScheme: (typeof colorSchemes)[number], testCase?: CaptureCase, ) => { await withPlaywright( async ({ context, cleanUp }) => { try { const page = await context.newPage(); await page.goto(href); await page.waitForLoadState("domcontentloaded"); await page.waitForTimeout(1000); if (testCase) { await testCase.setup(page); } await page.waitForTimeout(1000); const picturePath = testCase ? resolve( "e2e", "snapshots", ...paths, testCase.name, `${device.name}-${colorScheme}.png`, ) : resolve( "e2e", "snapshots", ...paths, `${device.name}-${colorScheme}.png`, ); await page.screenshot({ path: picturePath, fullPage: true, }); console.log(`[captured] ${picturePath}`); } finally { await cleanUp(); } }, { contextOptions: { ...device.device, baseURL: "http://localhost:4000", colorScheme, }, }, ); }; const tasks = testDevices.flatMap((device): Task[] => { return colorSchemes.flatMap((colorScheme): Task[] => [ { key: `${device.name}-${colorScheme}-default`, execute: () => captureWithCase(device, colorScheme), }, ...cases.map((testCase) => ({ key: `${device.name}-${colorScheme}-${testCase.name}`, execute: () => captureWithCase(device, colorScheme, testCase), })), ]); }); return { tasks, } as const; };