From 44fea2c5e2da04eb41bc750f4f404e7c0a497bae Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Thu, 11 Jun 2026 01:41:44 -0400 Subject: [PATCH] feat(07-01): add playwright.config.ts with two-profile device matrix - Two projects: iphone/WebKit (iPhone 14) + pixel/Chromium (Pixel 7) - serviceWorkers: 'block' on both profiles per D-02/Pitfall 15 - env-driven baseURL via PLAYWRIGHT_BASE_URL (D-08/Rule 8) - globalSetup ref to e2e/global-setup.ts (Plan 02 implements) - webServer manages vite only with reuseExistingServer (D-10) - no storageState, no toHaveScreenshot per D-01/UI-SPEC Rule 6 - add e2e/global-setup.ts placeholder (stub) so config path resolves --- apps/pwa/e2e/global-setup.ts | 15 ++++++++ apps/pwa/playwright.config.ts | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 apps/pwa/e2e/global-setup.ts create mode 100644 apps/pwa/playwright.config.ts diff --git a/apps/pwa/e2e/global-setup.ts b/apps/pwa/e2e/global-setup.ts new file mode 100644 index 0000000..ca86c58 --- /dev/null +++ b/apps/pwa/e2e/global-setup.ts @@ -0,0 +1,15 @@ +/** + * global-setup.ts — Phase 7 Plan 02 will implement this + * + * Placeholder to satisfy Playwright config path resolution. + * Plan 02 replaces this with: + * - health poll on baseURL/health (D-08 readiness gate) + * - mysql2 DB seed: TRUNCATE + INSERT onto calendar id=10 + lists for user 1 (D-05/D-06/D-07) + * + * Run: + * pnpm --filter @familysync/pwa test:e2e + */ + +export default async function globalSetup(): Promise { + // Implemented in Plan 02 +} diff --git a/apps/pwa/playwright.config.ts b/apps/pwa/playwright.config.ts new file mode 100644 index 0000000..1f30e36 --- /dev/null +++ b/apps/pwa/playwright.config.ts @@ -0,0 +1,65 @@ +/** + * 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, + }, +})