import { defineConfig, devices } from "@playwright/test" /** * Playwright configuration for tibi-svelte projects. * * Run against the CODING_URL (externally reachable via HTTPS). * Override with: CODING_URL=https://... yarn test */ /** * Traefik skips basic-auth for requests whose User-Agent contains * "Playwright" (see docker-compose-local.yml, priority-100 router). * Append the marker to every device preset so the original UA is preserved * (important for mobile/responsive detection) while bypassing auth. */ function withPlaywrightUA(device: (typeof devices)[string]) { return { ...device, userAgent: `${device.userAgent} Playwright` } } export default defineConfig({ testDir: "./tests", fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : 16, reporter: [["html", { open: "never" }]], globalSetup: "./tests/global-setup.ts", globalTeardown: "./tests/global-teardown.ts", /* ── Visual Regression defaults ──────────────────────────────────── */ snapshotPathTemplate: "{testDir}/__screenshots__/{projectName}/{testFilePath}/{arg}{ext}", expect: { toHaveScreenshot: { /* 2 % pixel tolerance – accounts for cross-OS font rendering */ maxDiffPixelRatio: 0.02, /* per-pixel colour distance threshold (0 = exact, 1 = any) */ threshold: 0.2, /* animation settling time before capture */ animations: "disabled", }, }, use: { /* Read from .env PROJECT_NAME or override via CODING_URL env var */ baseURL: process.env.CODING_URL || "https://localhost:3000", headless: true, ignoreHTTPSErrors: true, trace: "on", /* BrowserSync keeps a WebSocket open permanently, preventing "networkidle" and "load" from resolving reliably. Default all navigations to "domcontentloaded". */ navigationTimeout: 30000, }, projects: [ /* ── Desktop E2E ───────────────────────────────────────────────── */ { name: "chromium", testDir: "./tests/e2e", use: { ...withPlaywrightUA(devices["Desktop Chrome"]) }, }, /* ── API Tests ─────────────────────────────────────────────────── */ { name: "api", testDir: "./tests/api", use: { ...withPlaywrightUA(devices["Desktop Chrome"]), }, }, /* ── Mobile E2E ────────────────────────────────────────────────── */ { name: "mobile-iphonese", testDir: "./tests/e2e-mobile", use: { ...withPlaywrightUA(devices["iPhone SE"]), defaultBrowserType: "chromium", }, }, { name: "mobile-ipad", testDir: "./tests/e2e-mobile", use: { ...withPlaywrightUA(devices["iPad Mini"]), defaultBrowserType: "chromium", }, }, /* ── Visual Regression ─────────────────────────────────────────── */ { name: "visual-desktop", testDir: "./tests/e2e-visual", use: { ...withPlaywrightUA(devices["Desktop Chrome"]) }, }, { name: "visual-iphonese", testDir: "./tests/e2e-visual", use: { ...withPlaywrightUA(devices["iPhone SE"]), defaultBrowserType: "chromium", }, }, { name: "visual-ipad", testDir: "./tests/e2e-visual", use: { ...withPlaywrightUA(devices["iPad Mini"]), defaultBrowserType: "chromium", }, }, ], })