import { rm } from 'node:fs/promises'; import { metadataPath, playwrightArtifactRoot, repoRoot } from './fixtures/cluster'; import { readClusterMetadata } from './fixtures/cluster'; import { spawn } from 'node:child_process'; async function runCommand(command: string, args: string[], cwd: string) { await new Promise((resolve, reject) => { const child = spawn(command, args, { cwd, stdio: 'ignore', shell: false, }); child.on('error', reject); child.on('close', (code) => { if (code === 0) { resolve(); return; } reject(new Error(`${command} ${args.join(' ')} failed with code ${code}`)); }); }); } async function killProcessTree(pid: number) { if (process.platform === 'win32') { await runCommand('taskkill', ['/PID', String(pid), '/T', '/F'], repoRoot); return; } process.kill(pid, 'SIGTERM'); } export default async function globalTeardown() { try { const metadata = await readClusterMetadata(); await killProcessTree(metadata.serverPid); } catch { // ignore missing metadata or already-exited processes } await rm(metadataPath, { force: true }); await rm(playwrightArtifactRoot, { recursive: false, force: false }).catch(() => { // keep artifacts when directory is not empty }); }