diff --git a/frontend/e2e/dashboard-screenshots.spec.ts b/frontend/e2e/dashboard-screenshots.spec.ts new file mode 100644 index 00000000..2566b056 --- /dev/null +++ b/frontend/e2e/dashboard-screenshots.spec.ts @@ -0,0 +1,45 @@ +/** + * 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 + }); + }); + } +}