import { chromium, type FullConfig } from '@playwright/test' import { mkdirSync } from 'node:fs' import path from 'node:path' export default async function globalSetup(config: FullConfig) { const projectName = process.env.DODO_E2E_PROJECT if (!projectName) throw new Error('DODO_E2E_PROJECT is required') const baseURL = config.projects[0]?.use.baseURL as string const storageState = path.resolve('playwright-runtime', projectName, 'auth.json') mkdirSync(path.dirname(storageState), { recursive: true }) const browser = await chromium.launch() try { const context = await browser.newContext({ baseURL }) const page = await context.newPage() const readyDeadline = Date.now() + 90_000 let ready = false while (Date.now() < readyDeadline) { try { const [health, frontend, proxy] = await Promise.all([ page.request.get('/health/ready'), page.request.get('/'), page.request.get('/api/v1/setup/status'), ]) if (health.ok() && frontend.ok() && proxy.ok()) { ready = true; break } } catch {} await new Promise(resolve => setTimeout(resolve, 250)) } if (!ready) throw new Error('isolated frontend/backend/proxy did not become ready') const initialized = await page.request.get('/api/v1/setup/status') if (!initialized.ok()) throw new Error(`setup status failed: ${initialized.status()}`) if ((await initialized.json()).initialized) throw new Error(`isolated ${projectName} runtime was already initialized`) const response = await page.request.post('/api/v1/setup/initialize', { data: { username: `e2e-owner-${projectName}`, password: 'e2e-password-1234' } }) if (!response.ok()) throw new Error(`initialize failed: ${response.status()} ${await response.text()}`) await context.storageState({ path: storageState }) } finally { await browser.close() } }