/** * Server management utilities for E2E tests. */ import { existsSync, mkdirSync } from 'node:fs' import { join, dirname } from 'node:path' import { fileURLToPath } from 'node:url' import { execSync } from 'node:child_process' const _dirname = dirname(fileURLToPath(import.meta.url)) const projectRoot = join(_dirname, '../../..') const devCertsDir = join(projectRoot, '.dev-certs') const devKey = join(devCertsDir, 'key.pem') const devCert = join(devCertsDir, 'cert.pem') /** * Ensure .dev-certs directory exists and contains certificates. * Generates certs if missing (same logic as scripts/gen-dev-cert.sh). */ export function ensureDevCerts() { if (existsSync(devKey) && existsSync(devCert)) { return // Certs already exist } // Create .dev-certs directory mkdirSync(devCertsDir, { recursive: true }) // Generate self-signed cert for localhost/127.0.0.1 const SAN = 'subjectAltName=IP:127.0.0.1,DNS:localhost' try { execSync( `openssl req -x509 -newkey rsa:2048 -keyout "${devKey}" -out "${devCert}" -days 365 -nodes -subj "/CN=localhost" -addext "${SAN}"`, { cwd: projectRoot, stdio: 'inherit' }, ) console.log('[test] Generated .dev-certs/key.pem and .dev-certs/cert.pem') } catch (error) { throw new Error(`Failed to generate dev certificates: ${error.message}`) } } /** * Wait for server to be ready by polling the health endpoint. * @param {string} baseURL * @param {number} timeoutMs * @returns {Promise} */ export async function waitForServerReady(baseURL = 'https://localhost:3000', timeoutMs = 120000) { const startTime = Date.now() const checkInterval = 1000 // Check every second while (Date.now() - startTime < timeoutMs) { try { const response = await fetch(`${baseURL}/health`, { method: 'GET', // @ts-ignore - ignoreHTTPSErrors is handled by Playwright context }) if (response.ok) { return // Server is ready } } catch { // Server not ready yet, continue polling } await new Promise(resolve => setTimeout(resolve, checkInterval)) } throw new Error(`Server did not become ready within ${timeoutMs}ms`) }