Files
F-r-ldraledigplannerare/frontend/playwright.config.ts
T
jacobh2 ed5680253e Check in a browser what the unit tests cannot see
Every serious defect in this project was found by opening the app, most
recently a feature that rendered blank cards to every user while its tests
passed, and a progress bar labelled in the wrong unit. Five checks now run
without a person: that the age-four figures on screen match what the API
computed, that a multi-week period draws as one bar rather than fragments,
that Sundays and holidays are red where Saturdays are not, that no identifier
leaks into visible text, and that no page logs an error.

Three of them were confirmed by reintroducing the original bug and watching
the right test fail. Dates are derived rather than written down: Easter is
computed independently instead of asked of the system under test, and the
fixture period is placed relative to today, so the suite does not expire.

It runs as its own job and does not block a merge until it has proved itself
stable.
2026-09-17 19:46:17 +02:00

62 lines
2.2 KiB
TypeScript

import { defineConfig, devices } from '@playwright/test'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const authFile = path.join(__dirname, 'e2e/.auth/user.json')
// NOTE: the frontend origin is deliberately `http://localhost:5173`, never
// `127.0.0.1` — Vite's dev server binds IPv6 `::1`, and on macOS
// `127.0.0.1` can silently miss it (see the matching comment in
// vite.config.ts's proxy target, which uses 127.0.0.1 for the *backend* for
// the opposite reason: to dodge a stray IPv6 listener there).
const FRONTEND_URL = 'http://localhost:5173'
const BACKEND_HEALTH_URL = 'http://127.0.0.1:8000/health'
export default defineConfig({
testDir: './e2e',
globalSetup: './e2e/global-setup.ts',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
// A fresh suite against a single shared demo workspace — keep it to one
// worker in CI until it's proven flake-free under parallel load. Left
// unset locally so Playwright picks its usual CPU-based default.
...(process.env.CI ? { workers: 1 } : {}),
reporter: process.env.CI ? [['github'], ['html', { open: 'never' }]] : 'list',
use: {
baseURL: FRONTEND_URL,
// Pinned so translated labels/aria-labels used as selectors (e.g.
// "Välj månad") are deterministic regardless of the host machine's
// locale — the app defaults to Swedish or English based on
// `navigator.language` (see LanguageContext.tsx).
locale: 'sv-SE',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
},
webServer: [
{
command: 'uv run uvicorn app.main:app --port 8000',
cwd: path.resolve(__dirname, '../backend'),
url: BACKEND_HEALTH_URL,
reuseExistingServer: !process.env.CI,
timeout: 60_000,
},
{
command: 'npx vite --port 5173 --strictPort',
cwd: __dirname,
url: FRONTEND_URL,
reuseExistingServer: !process.env.CI,
timeout: 60_000,
},
],
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
use: { ...devices['Desktop Chrome'], storageState: authFile },
dependencies: ['setup'],
},
],
})