/** * Playwright configuration — Phase 7 Mobile Test Harness * * Two-profile device matrix: iPhone 14/WebKit + Pixel 7/Chromium * Auth: DEV_AUTH_BYPASS=true on the API (never storageState — D-01/Pitfall 14) * SW: serviceWorkers: 'block' on both profiles (D-02/Pitfall 15) * baseURL: env-driven PLAYWRIGHT_BASE_URL (D-08/Rule 8) * webServer: manages Vite only — API+MariaDB+Redis stay compose-managed (D-10) * * Run: * pnpm --filter @familysync/pwa test:e2e * pnpm --filter @familysync/pwa exec playwright test --project=pixel */ import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './e2e', testMatch: '**/*.spec.ts', fullyParallel: true, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: process.env.CI ? 'github' : 'list', // Plan 02 creates this file — forward-declared, resolves at runtime globalSetup: './e2e/global-setup.ts', use: { // env-driven per D-08/Rule 8 — never a hardcoded host baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:5173', trace: 'on-first-retry', video: 'on-first-retry', screenshot: 'only-on-failure', }, projects: [ { // iPhone 14: 390×844 viewport, WebKit engine, Mobile Safari UA, hasTouch: true // Device descriptor confirmed: playwright deviceDescriptorsSource.json name: 'iphone', use: { ...devices['iPhone 14'], // serviceWorkers: 'block' prevents the injectManifest sw.js (Workbox) from // intercepting requests — satisfies D-02 / Pitfall 15 serviceWorkers: 'block', }, }, { // Pixel 7: 412×915 viewport, Chromium engine, Chrome Android UA, hasTouch: true name: 'pixel', use: { ...devices['Pixel 7'], serviceWorkers: 'block', }, }, ], // D-10: manage Vite only; API+MariaDB+Redis are compose-managed // reuseExistingServer: reuse operator's pnpm dev locally; start fresh in CI webServer: { command: 'pnpm --filter @familysync/pwa dev', url: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:5173', reuseExistingServer: !process.env.CI, timeout: 120_000, }, });