/** * E2E-only backend: temp SQLite, configurable port/root. Used by Playwright webServer. */ import { spawn } from 'node:child_process' import { existsSync, mkdtempSync, rmSync, mkdirSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join, dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' const scriptDir = dirname(fileURLToPath(import.meta.url)) const frontendRoot = join(scriptDir, '..') const defaultBackend = join(frontendRoot, '..', 'backend-nest') const backendRoot = resolve(process.env.E2E_BACKEND_ROOT ?? defaultBackend) const backendPort = String(process.env.E2E_BACKEND_PORT ?? '3010') const frontendPort = String(process.env.E2E_FRONTEND_PORT ?? '5190') const corsOrigin = process.env.E2E_CORS_ORIGIN ?? `http://127.0.0.1:${frontendPort}` const distMain = join(backendRoot, 'dist', 'main.js') if (!existsSync(distMain)) { console.error(`Missing ${distMain}. Run: npm run e2e:prepare (or npm run build in backend).`) process.exit(1) } const runtimeDir = join(frontendRoot, 'e2e', '.runtime') mkdirSync(runtimeDir, { recursive: true }) const tempDir = mkdtempSync(join(tmpdir(), 'cgl-e2e-')) const dbPath = join(tempDir, 'app.db') writeFileSync( join(runtimeDir, 'state.json'), JSON.stringify({ tempDir, dbPath, backendPort: Number(backendPort) }), 'utf8', ) const backend = spawn(process.execPath, ['dist/main.js'], { cwd: backendRoot, env: { ...process.env, PORT: backendPort, DB_PATH: dbPath, CORS_ORIGIN: corsOrigin, JWT_SECRET: process.env.E2E_JWT_SECRET ?? 'e2e-ci-jwt-not-for-production', NODE_ENV: 'test', }, stdio: 'inherit', }) function cleanupTemp() { try { backend.kill() } catch { // ignore } try { rmSync(tempDir, { recursive: true, force: true }) } catch { // ignore } } function shutdown(code = 0) { cleanupTemp() process.exit(code) } process.on('SIGINT', () => shutdown(0)) process.on('SIGTERM', () => shutdown(0)) backend.on('exit', (code, signal) => { if (signal) shutdown(0) else process.exit(code ?? 1) })