import { defineConfig, devices } from '@playwright/test' const chromiumProject = { name: 'chromium', use: { ...devices['Desktop Chrome'], ...(process.env.PLAYWRIGHT_CHROME_CHANNEL ? { channel: process.env.PLAYWRIGHT_CHROME_CHANNEL as 'chrome' | 'chrome-beta' | 'msedge' | 'msedge-beta' } : {}), }, } const localBrowserProjects = [ chromiumProject, { name: 'firefox', use: { ...devices['Desktop Firefox'] }, }, { name: 'webkit', use: { ...devices['Desktop Safari'] }, }, { name: 'android-chrome', use: { ...devices['Pixel 7'] }, }, ] export default defineConfig({ testDir: './e2e', globalSetup: './e2e/global-setup.ts', globalTeardown: './e2e/global-teardown.ts', fullyParallel: true, forbidOnly: Boolean(process.env.CI), // Keep CI green under transient network flakes; local stays strict. retries: process.env.CI ? 1 : 0, reporter: process.env.CI ? [['html', { open: 'never' }], ['github']] : 'list', use: { baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://127.0.0.1:3102', screenshot: 'only-on-failure', // Network-heavy application specs rely on Playwright route interception. // Service workers can hide requests from that layer, especially in WebKit; // PWA registration/cache behavior is covered by the dedicated smoke suite. serviceWorkers: 'block', trace: 'retain-on-failure', video: 'retain-on-failure', }, // Full matrix locally; Chromium-only gate in CI for signal vs flakiness cost. projects: process.env.CI ? [chromiumProject] : localBrowserProjects, })