/** * Shared proofshot helper for Playwright. * * Usage in any spec file: * import { captureProofshots } from './proofshots'; * captureProofshots('/persons', 'persons'); * * This registers one test per viewport × theme combination. * Screenshots are saved to proofshot-artifacts/{featureName}/. */ import { test } from '@playwright/test'; import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const viewports = [ { name: 'mobile', width: 390, height: 844 }, { name: 'tablet', width: 768, height: 1024 }, { name: 'desktop', width: 1440, height: 900 } ]; /** * Registers Playwright tests that navigate to `url`, apply each theme, * and capture full-page screenshots at all standard viewports. * * @param url The path to screenshot (e.g. '/', '/persons', '/admin') * @param featureName Used as the output directory name and screenshot file prefix */ export function captureProofshots(url: string, featureName: string): void { const outDir = path.join(__dirname, '../../proofshot-artifacts', featureName); fs.mkdirSync(outDir, { recursive: true }); for (const vp of viewports) { for (const theme of ['light', 'dark'] as const) { test(`${featureName} – ${vp.name} – ${theme}`, async ({ page }) => { await page.setViewportSize({ width: vp.width, height: vp.height }); await page.goto(url); // Apply theme via data-theme attribute and localStorage await page.evaluate((t) => { document.documentElement.setAttribute('data-theme', t); localStorage.setItem('theme', t); }, theme); // 'networkidle' is unreliable in SvelteKit dev mode due to the HMR WebSocket. await page.waitForLoadState('domcontentloaded'); await page.waitForSelector('main', { state: 'visible' }); await page.screenshot({ path: path.join(outDir, `${featureName}-${vp.name}-${theme}.png`), fullPage: true }); }); } } }