const { spawn } = require('node:child_process'); const { mkdtempSync, readdirSync, rmSync } = require('node:fs'); const { tmpdir } = require('node:os'); const { join, resolve } = require('node:path'); const cwd = resolve(__dirname, '..'); const available = readdirSync(__dirname) .filter((name) => name.endsWith('.e2e-spec.ts')) .sort(); const performanceSuites = new Set(['tbank-read-baseline.e2e-spec.ts']); const requested = process.argv.slice(2); const suites = requested.length === 0 ? ['app.e2e-spec.ts', 'bank-cards.e2e-spec.ts'] : requested.length === 1 && requested[0] === '--all' ? available.filter((suite) => !performanceSuites.has(suite)) : requested; if (suites.some((suite) => !available.includes(suite))) { throw new Error('Unknown e2e suite'); } let child; let interrupted; let killTimer; function kill(signal) { if (!child) return; try { process.kill(-child.pid, signal); } catch (error) { if (error.code !== 'ESRCH') throw error; } } for (const signal of ['SIGINT', 'SIGTERM']) { process.on(signal, () => { interrupted = signal; kill(signal); killTimer ??= setTimeout(() => kill('SIGKILL'), 5000); }); } function run(args, env) { return new Promise((resolve, reject) => { child = spawn(process.execPath, args, { cwd, env, stdio: 'inherit', detached: true, }); child.once('error', reject); child.once('close', (code, signal) => { clearTimeout(killTimer); child = undefined; if (code !== 0 || signal) { reject(new Error(`Child failed: ${signal ?? code}`)); } else resolve(); }); }); } (async () => { for (const suite of suites) { if (interrupted) throw new Error(interrupted); const dir = mkdtempSync(join(tmpdir(), 'wealthledger-e2e-')); const env = { ...process.env, DATABASE_URL: `file:${join(dir, 'test.db')}`, WL_E2E_DIRECTORY: dir, NODE_ENV: 'development', NODE_OPTIONS: '--experimental-vm-modules', LOG_LEVEL: 'error', }; console.log(`SQLite ${suite}: ${dir}`); try { await run( ['node_modules/prisma/build/index.js', 'migrate', 'deploy'], env, ); if (interrupted) throw new Error(interrupted); await run( [ 'node_modules/jest/bin/jest.js', '--config', 'test/jest-e2e.json', '--runInBand', '--runTestsByPath', `test/${suite}`, ], env, ); } finally { rmSync(dir, { recursive: true, force: true }); } } })().catch((error) => { console.error(error.message); process.exitCode = interrupted === 'SIGINT' ? 130 : interrupted === 'SIGTERM' ? 143 : 1; });