import { defineConfig, devices } from "@playwright/test"; const host = process.env.PLAYWRIGHT_HOST ?? "localhost"; const port = Number(process.env.PLAYWRIGHT_PORT ?? 5173); const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? `http://${host}:${port}`; const publicBaseURL = process.env.E2E_PUBLIC_BASE_URL ?? "https://vignette.chanpaca.net"; const publicStorageState = process.env.E2E_PUBLIC_STORAGE_STATE; const includePublicAuth = process.env.E2E_PUBLIC_AUTH === "1"; const shouldStartWebServer = !includePublicAuth && !process.env.PLAYWRIGHT_BASE_URL && !process.env.PLAYWRIGHT_SKIP_WEB_SERVER; const reuseExistingServer = process.env.PLAYWRIGHT_REUSE_EXISTING_SERVER === "1"; const singleRunPattern = /@single-run/; const publicAuthPattern = /@public-auth/; const localProjectExclusions = /@single-run|@public-auth/; export default defineConfig({ testDir: "./e2e", outputDir: "./node_modules/.tmp/playwright-results", timeout: 30_000, expect: { timeout: 5_000, }, fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: process.env.CI ? [ ["list"], ["html", { open: "never", outputFolder: "node_modules/.tmp/playwright-report" }], ] : "list", use: { baseURL, trace: "on-first-retry", screenshot: "only-on-failure", video: "retain-on-failure", }, webServer: shouldStartWebServer ? { // npm 11 + Windows PowerShell에서는 공백형 값이 npm 옵션으로 다시 파싱돼 // `vite localhost 5174`처럼 위치 인자로 깨질 수 있다. 등호형으로 Vite에 고정한다. command: `npm run dev -- --host=${host} --port=${port}`, url: baseURL, // 공개 preview나 다른 checkout의 stale bundle을 로컬 GREEN으로 오인하지 않는다. // 의도적으로 같은 dev server를 공유할 때만 명시적으로 opt in 한다. reuseExistingServer, timeout: 120_000, env: { VITE_API_BASE: process.env.VITE_API_BASE ?? "/api", }, } : undefined, projects: [ { name: "chromium-desktop", grepInvert: localProjectExclusions, use: { ...devices["Desktop Chrome"], viewport: { width: 1440, height: 900 }, }, }, { name: "chromium-mobile", grepInvert: localProjectExclusions, use: { ...devices["Pixel 5"], }, }, { name: "chromium-single-run", grep: singleRunPattern, grepInvert: publicAuthPattern, // npm run e2e가 이 프로젝트를 fixture 프로젝트 뒤에 workers=1로 실행한다. // 직접 focused 실행할 때도 npm run e2e:single-run을 사용한다. fullyParallel: false, use: { ...devices["Desktop Chrome"], viewport: { width: 1280, height: 800 }, }, }, ...(includePublicAuth ? [ { name: "chromium-public-auth", grep: publicAuthPattern, use: { ...devices["Desktop Chrome"], baseURL: publicBaseURL, viewport: { width: 1440, height: 900 }, storageState: publicStorageState, }, }, ] : []), ], });