import { defineConfig, devices } from "@playwright/test"; /** E2E base URL: `PLAYWRIGHT_BASE_URL` / `E2E_BASE_URL` (set by global-setup), else the dev server. */ function resolveBaseURL(): string { return process.env.PLAYWRIGHT_BASE_URL ?? process.env.E2E_BASE_URL ?? "http://localhost:5173"; } export default defineConfig({ globalSetup: "./e2e/global-setup.ts", globalTeardown: "./e2e/global-teardown.ts", testDir: "./e2e", // The app under test is remote, so logins and fetches need more headroom than // the 30s default — but tight enough that a hung test fails well before the job cap. timeout: 90_000, expect: { timeout: 15_000 }, // Parallelize at the test level across workers; each worker reuses its per-actor sign-in. fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, // Network-bound, so more workers than cores is fine. workers: process.env.CI ? 16 : undefined, reporter: process.env.CI ? [["github"], ["html", { open: "never" }]] : "html", use: { baseURL: resolveBaseURL(), // Bound each action so a dead locator fails fast instead of waiting out the // full test timeout. actionTimeout: 20_000, navigationTimeout: 30_000, trace: "on-first-retry", screenshot: "only-on-failure", }, projects: [ { name: "chromium", testMatch: /tests\/.*\.spec\.ts/, use: { ...devices["Desktop Chrome"] }, }, ], });