/** * Run Playwright E2E tests against the built production bundle. * * Uses `npx serve -s dist` which supports SPA fallback (unlike * python3 -m http.server). This ensures client-side routes like * /app/editor work correctly. */ import { spawn } from 'child_process' import { fileURLToPath } from 'url' import { dirname, join } from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) const rootDir = join(__dirname, '..') async function main() { console.log('[e2e:built] Starting static server with SPA fallback...') const serve = spawn('npx', ['serve', '-s', 'dist', '-l', '4173', '--no-clipboard'], { cwd: rootDir, stdio: 'pipe', shell: true, }) // Wait for server to be ready await new Promise((resolve, reject) => { const timeout = setTimeout(() => reject(new Error('Server start timeout')), 15000) serve.stdout.on('data', (data) => { const text = data.toString() if (text.includes('Accepting connections')) { clearTimeout(timeout) resolve() } }) serve.stderr.on('data', (data) => { console.error('[serve]', data.toString().trim()) }) }) console.log('[e2e:built] Server ready. Running Playwright...') const playwright = spawn('npx', ['playwright', 'test', '--reporter=line'], { cwd: rootDir, stdio: 'inherit', shell: true, env: { ...process.env, PLAYWRIGHT_BASE_URL: 'http://127.0.0.1:4173', }, }) const exitCode = await new Promise((resolve) => { playwright.on('close', (code) => resolve(code ?? 1)) }) console.log('[e2e:built] Shutting down server...') serve.kill() process.exit(exitCode) } main().catch((err) => { console.error('[e2e:built] Failed:', err) process.exit(1) })