import { defineConfig, devices } from "@playwright/test"; import { readFileSync, existsSync, mkdirSync } from "node:fs"; // Playwright does not load Next's .env.local; the E2E run needs the real Jev key and a stable APP_SECRET. if (existsSync(".env.local")) for (const line of readFileSync(".env.local", "utf8").split("\n")) { const m = /^([A-Z_]+)=(.*)$/.exec(line.trim()); if (m && !process.env[m[1]]) process.env[m[1]] = m[2]; } mkdirSync(".auth", { recursive: true }); export default defineConfig({ testDir: "./tests-e2e", fullyParallel: false, // one SQLite file, one app process workers: 1, retries: 0, timeout: 180_000, // real models are slow; say so with a timeout, not with retries reporter: [["list"]], use: { baseURL: "http://localhost:3000", trace: "retain-on-failure" }, projects: [ { name: "setup", testMatch: /auth\.setup\.ts/ }, { name: "chromium", use: { ...devices["Desktop Chrome"] }, dependencies: ["setup"] }, // A real model run costs ~40s; the mobile project only needs the layout checks, not a second full run. { name: "mobile", use: { ...devices["Pixel 7"] }, dependencies: ["setup"], testMatch: /responsive\.spec\.ts/ }, ], webServer: { command: "npm run dev", url: "http://localhost:3000/api/healthz", reuseExistingServer: true, timeout: 120_000, env: { DATA_DIR: ".playwright-data", APP_SECRET: process.env.APP_SECRET ?? "playwright-secret-value" } }, });