import { defineConfig, devices } from '@playwright/test'; import { fileURLToPath } from 'node:url'; import path from 'node:path'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DASHBOARD_PORT = Number(process.env.PICLOUD_DASHBOARD_PORT ?? 5173); // baseURL is the origin only — the SvelteKit dashboard is mounted at // `/admin` (svelte.config.js paths.base), so tests use full paths like // `/admin/login` rather than relying on baseURL path resolution. const DASHBOARD_BASE = process.env.E2E_BASE_URL ?? `http://localhost:${DASHBOARD_PORT}`; export default defineConfig({ testDir: './tests/e2e', outputDir: './tests/e2e/.results', fullyParallel: true, forbidOnly: !!process.env.CI, // Local: 1 retry to absorb dev-server warmup flakiness. CI: 2. retries: process.env.CI ? 2 : 1, // Cap at 4 workers locally to keep the shared Vite dev server // from getting stampeded during cold-start compiles. workers: process.env.CI ? 2 : 4, reporter: process.env.CI ? [['html'], ['github']] : 'html', globalSetup: './tests/e2e/global-setup.ts', expect: { timeout: 5_000 }, use: { baseURL: DASHBOARD_BASE, actionTimeout: 10_000, navigationTimeout: 30_000, trace: 'on-first-retry', screenshot: 'only-on-failure', video: 'retain-on-failure' }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'], storageState: path.join(__dirname, 'tests/e2e/.auth/admin.json') } } ], webServer: { command: 'npm run dev', url: `http://localhost:${DASHBOARD_PORT}/admin/`, reuseExistingServer: !process.env.CI, stdout: 'pipe', stderr: 'pipe', timeout: 60_000 } });