import { spawn } from "node:child_process"; import { fileURLToPath } from "node:url"; import { createServer } from "vite"; const baseUrl = new URL(process.env.PLAYWRIGHT_BASE_URL || "http://localhost:3010"); const port = Number(baseUrl.port || 3010); const host = baseUrl.hostname || "localhost"; let child = null; let closing = false; const server = await createServer({ server: { host, port, strictPort: true, }, }); async function closeServer() { if (closing) { return; } closing = true; await server.close(); } async function shutdown(signal) { if (child && !child.killed) { child.kill(signal); } try { await closeServer(); } finally { process.exit(signal === "SIGINT" || signal === "SIGTERM" ? 130 : 1); } } process.once("SIGINT", () => { void shutdown("SIGINT"); }); process.once("SIGTERM", () => { void shutdown("SIGTERM"); }); await server.listen(); server.printUrls(); const playwrightCli = fileURLToPath( new URL("../node_modules/@playwright/test/cli.js", import.meta.url) ); const frontendRoot = fileURLToPath(new URL("..", import.meta.url)); child = spawn(process.execPath, [playwrightCli, "test", ...process.argv.slice(2)], { cwd: frontendRoot, env: { ...process.env, PLAYWRIGHT_BASE_URL: baseUrl.toString().replace(/\/$/, ""), PLAYWRIGHT_SKIP_WEBSERVER: "1", }, stdio: "inherit", }); child.on("exit", async (code, signal) => { try { await closeServer(); } catch (error) { console.error("Failed to close Vite after Playwright run:", error); process.exit(1); } if (signal) { process.kill(process.pid, signal); return; } process.exit(code ?? 1); });