import { defineConfig, devices } from "@playwright/test"; import * as dotenv from "dotenv"; import * as path from "path"; // Load .env.e2e from the repo root (one level up from e2e/). dotenv.config({ path: path.resolve(__dirname, "../.env.e2e") }); const BASE_URL = process.env.E2E_DOCMOST_URL ?? "http://localhost:5173"; const isCI = Boolean(process.env.CI); export default defineConfig({ testDir: "./tests", // Strict: every test must explicitly use fixtures — no implicit global state. fullyParallel: false, // Fail fast in CI — one failed test does not cascade to the rest. forbidOnly: isCI, retries: isCI ? 2 : 0, // Sequential workers — the e2e stack is shared and stateful (real DB). workers: 1, reporter: isCI ? [["github"], ["html", { outputFolder: "playwright-report", open: "never" }]] : [["list"], ["html", { outputFolder: "playwright-report", open: "on-failure" }]], use: { baseURL: BASE_URL, // Screenshot on every failure — uploaded as CI artifact. screenshot: "only-on-failure", // Video on failure — aids debugging SSE/realtime issues. video: "retain-on-failure", // Trace on first retry. trace: "on-first-retry", // All e2e calls go through real services — no mocking. bypassCSP: false, // Generous timeout for SSE events (up to 10s propagation). actionTimeout: 15_000, navigationTimeout: 30_000, }, // Global timeout per test. timeout: 60_000, // Expect assertions timeout — generous for SSE realtime updates. expect: { timeout: 15_000, }, projects: [ // Setup project: runs auth + baserow seed before all tests. { name: "setup", testMatch: /.*\.setup\.ts/, }, // Chromium — primary browser. { name: "chromium", use: { ...devices["Desktop Chrome"], storageState: ".auth/admin.json", }, dependencies: ["setup"], }, // Firefox — cross-browser validation. { name: "firefox", use: { ...devices["Desktop Firefox"], storageState: ".auth/admin.json", }, dependencies: ["setup"], }, // WebKit — Safari compat. { name: "webkit", use: { ...devices["Desktop Safari"], storageState: ".auth/admin.json", }, dependencies: ["setup"], }, ], // Run docker compose before all tests (local dev only — CI manages its own boot). // Disabled in CI because the workflow manages docker compose externally. webServer: isCI ? undefined : { command: "docker compose -f ../docker-compose.e2e.yml --env-file ../.env.e2e up -d --wait", url: BASE_URL, reuseExistingServer: true, timeout: 300_000, }, });