veza/apps/web/playwright.config.visual.ts
senke be7d7b02cc feat(e2e): Playwright + pixelmatch stack for pixel-perfect visual regression
- playwright.config.visual.ts: dedicated config, viewport 1280x720, Chromium only,
  snapshots in e2e/tests/visual/__snapshots__
- e2e/tests/visual/visual-regression.spec.ts: login, register, dashboard (full/header/sidebar),
  player bar, playlists, 404, mobile/tablet viewports; dark theme + reduceMotion
- scripts/visual-diff.js: optional pixelmatch script to generate diff image from two PNGs
- docs/VISUAL_TESTING_STRATEGY.md: strategy, commands, CI, workflow
- npm scripts: test:visual, test:visual:update, test:visual:report
- deps: pixelmatch, pngjs; @playwright/test aligned to 1.58.1
- baseline snapshots added for login, dashboard, playlists, 404, viewports

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 20:01:30 +01:00

64 lines
1.9 KiB
TypeScript

import { defineConfig, devices } from '@playwright/test';
/**
* Playwright config for pixel-perfect visual regression tests.
*
* - Fixed viewport and single browser (Chromium) for reproducible screenshots.
* - Snapshots stored in e2e/snapshots/ for easy review and CI artifact.
* - Optional: run without global auth for login/register snapshots.
*
* Run:
* npx playwright test --config=playwright.config.visual.ts
* Update baselines:
* npx playwright test --config=playwright.config.visual.ts --update-snapshots
*/
export default defineConfig({
testDir: './e2e/tests/visual',
testMatch: /.*\.spec\.ts/,
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
workers: 1,
timeout: 30000,
outputDir: 'e2e/test-results-visual',
snapshotPathTemplate: '{testDir}/__snapshots__/{arg}-{projectName}{ext}',
reporter: [
['html', { outputFolder: 'e2e/playwright-report-visual', open: 'never' }],
['list'],
],
use: {
baseURL: process.env.PLAYWRIGHT_BASE_URL || process.env.VITE_FRONTEND_URL || 'http://localhost:5173',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'off',
// Fixed viewport for pixel-perfect comparison (no cross-resolution variance)
viewport: { width: 1280, height: 720 },
// Storage state: set per-test for login (no auth) vs dashboard (auth)
storageState: process.env.VISUAL_AUTH_STATE || 'e2e/.auth/user.json',
},
projects: [
{
name: 'chromium-desktop',
use: {
...devices['Desktop Chrome'],
viewport: { width: 1280, height: 720 },
deviceScaleFactor: 1,
isMobile: false,
hasTouch: false,
locale: 'en-US',
timezoneId: 'Europe/Paris',
},
},
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:5173',
reuseExistingServer: true,
timeout: 120_000,
},
});