import { existsSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { defineConfig, devices } from "@playwright/test"; const WEB_PORT = 4173; const API_PORT = 3135; const WEB = `http://127.0.0.1:${WEB_PORT}`; // Local runs read the repo-root .env (TEST_DATABASE_URL); CI sets real variables. const envFile = fileURLToPath(new URL("../../.env", import.meta.url)); if (existsSync(envFile)) process.loadEnvFile(envFile); const databaseUrl = process.env.TEST_DATABASE_URL; /** * Browser tests against the production build (Phases 11–12): service worker, * install, offline, and end-to-end play against a real API server on the test * database. Run `pnpm build` first. The server clock is shared, and the * end-to-end tests move it forward, so tests run one at a time. */ export default defineConfig({ testDir: "e2e", testMatch: "**/*.e2e.ts", workers: 1, fullyParallel: false, retries: process.env.CI ? 1 : 0, timeout: 120_000, use: { baseURL: WEB, ...devices["Desktop Chrome"] }, webServer: [ { // The API on the test database, migrated first; developer routes on (not production). command: "pnpm --filter @deadhead/server db:migrate && pnpm --filter @deadhead/server start", cwd: "../..", url: `http://127.0.0.1:${API_PORT}/api/health`, reuseExistingServer: !process.env.CI, timeout: 120_000, env: { NODE_ENV: "test", PORT: String(API_PORT), LOG_LEVEL: "warn", DATABASE_URL: databaseUrl ?? "", BETTER_AUTH_URL: WEB, BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET ?? "e2e-only-secret-not-for-production-use-0000", WORKERS_ENABLED: "false", }, }, { // The built app, with /api proxied to the server above (same origin, decision 0.5.20). command: `pnpm exec vite preview --port ${WEB_PORT} --strictPort --host 127.0.0.1`, url: WEB, reuseExistingServer: !process.env.CI, env: { API_PROXY_TARGET: `http://127.0.0.1:${API_PORT}` }, }, ], });