/** * Captures dashboard screenshots at multiple viewport sizes and in both * light and dark theme. Output goes to proofshot-artifacts/dashboard/. * Run via: npx playwright test e2e/dashboard-screenshots.spec.ts */ 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 outDir = path.join(__dirname, '../../proofshot-artifacts/dashboard'); fs.mkdirSync(outDir, { recursive: true }); const viewports = [ { name: 'mobile', width: 390, height: 844 }, { name: 'tablet', width: 768, height: 1024 }, { name: 'desktop', width: 1440, height: 900 } ]; for (const vp of viewports) { for (const theme of ['light', 'dark'] as const) { test(`dashboard – ${vp.name} – ${theme}`, async ({ page }) => { await page.setViewportSize({ width: vp.width, height: vp.height }); await page.goto('/'); // Apply theme await page.evaluate((t) => { document.documentElement.setAttribute('data-theme', t); localStorage.setItem('theme', t); }, theme); // Wait for the main content to be rendered. // 'networkidle' is unreliable in SvelteKit dev mode due to the HMR WebSocket. await page.waitForLoadState('domcontentloaded'); // Wait for at least one dashboard widget or the search bar to be visible await page.waitForSelector('main', { state: 'visible' }); await page.screenshot({ path: path.join(outDir, `dashboard-${vp.name}-${theme}.png`), fullPage: true }); }); } }