From 068e47fcf706060417a25cd1bb968f8ee56cb03a Mon Sep 17 00:00:00 2001 From: f3tch Date: Sat, 22 Aug 2026 07:18:26 +0500 Subject: [PATCH 1/4] test: make process cleanup work on Windows --- tests/setup.ts | 71 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/tests/setup.ts b/tests/setup.ts index 6b81d53f..696a2735 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -2,7 +2,9 @@ // This file runs before all tests import { beforeAll, afterAll } from 'vitest'; -import { execSync } from 'child_process'; +import { execSync, execFileSync } from 'child_process'; + +const isWindows = process.platform === 'win32'; // Track if we're in cleanup mode let isCleaningUp = false; @@ -17,7 +19,7 @@ afterAll(() => { }); /** - * Cleanup function to kill all Firefox and geckodriver processes + * Cleanup function to kill leftover test Firefox and geckodriver processes * This ensures no zombie processes are left after test runs */ function cleanup() { @@ -26,6 +28,20 @@ function cleanup() { } isCleaningUp = true; + try { + if (isWindows) { + cleanupWindows(); + } else { + cleanupUnix(); + } + } catch { + // Ignore errors - processes might already be dead + } finally { + isCleaningUp = false; + } +} + +function cleanupUnix() { try { // Find Firefox processes started with --marionette (test instances) const firefoxPids = execSync('pgrep -f "firefox.*marionette" || true', { @@ -57,8 +73,55 @@ function cleanup() { console.log('✅ Global cleanup: All test Firefox processes terminated'); } catch { // Ignore errors - processes might already be dead - } finally { - isCleaningUp = false; + } +} + +// Only matches Firefox instances whose command line carries --marionette, +// so regular user-launched Firefox windows are never touched. +function findWindowsProcessIds(imageName: string, commandLinePattern?: string): number[] { + const filter = commandLinePattern + ? `Name='${imageName}' AND CommandLine LIKE '%${commandLinePattern}%'` + : `Name='${imageName}'`; + const script = + `Get-CimInstance Win32_Process -Filter "${filter}" | ` + + 'Select-Object -ExpandProperty ProcessId'; + const output = execFileSync( + 'powershell.exe', + ['-NoProfile', '-NonInteractive', '-Command', script], + { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] } + ); + return output + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => /^\d+$/.test(line)) + .map(Number); +} + +function cleanupWindows() { + try { + const firefoxPids = findWindowsProcessIds('firefox.exe', '--marionette'); + for (const pid of firefoxPids) { + try { + // /T kills the whole process tree, replacing the Unix child-kill step + execSync(`taskkill /PID ${pid} /T /F`, { stdio: 'ignore' }); + } catch { + // Ignore errors - process might already be dead + } + } + + for (const pid of findWindowsProcessIds('geckodriver.exe')) { + try { + execSync(`taskkill /PID ${pid} /T /F`, { stdio: 'ignore' }); + } catch { + // Ignore errors - process might already be dead + } + } + + if (firefoxPids.length > 0) { + console.log('✅ Global cleanup: All test Firefox processes terminated'); + } + } catch { + // Ignore errors - processes might already be dead } } From 83986466a205fa601a131b25982a758253d871de Mon Sep 17 00:00:00 2001 From: f3tch <76998773+f3tchcodes@users.noreply.github.com> Date: Tue, 25 Aug 2026 20:28:03 +0500 Subject: [PATCH 2/4] test: removing extra try/catch from `cleanup()` Co-authored-by: Julian Descottes --- tests/setup.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/setup.ts b/tests/setup.ts index 696a2735..07c8bf7f 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -28,17 +28,12 @@ function cleanup() { } isCleaningUp = true; - try { - if (isWindows) { - cleanupWindows(); - } else { - cleanupUnix(); - } - } catch { - // Ignore errors - processes might already be dead - } finally { - isCleaningUp = false; + if (isWindows) { + cleanupWindows(); + } else { + cleanupUnix(); } + isCleaningUp = false; } function cleanupUnix() { From b56ecadffe3979e7f2e9aa0d2fab647b3b106dd6 Mon Sep 17 00:00:00 2001 From: f3tch Date: Tue, 25 Aug 2026 20:31:34 +0500 Subject: [PATCH 3/4] test: hiding powershell window in `findWindowsProcessIds()` --- tests/setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/setup.ts b/tests/setup.ts index 07c8bf7f..3f9d8c1a 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -83,7 +83,7 @@ function findWindowsProcessIds(imageName: string, commandLinePattern?: string): const output = execFileSync( 'powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script], - { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] } + { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true } ); return output .split(/\r?\n/) From b13525bf588b5125484b770f7b3ff91a45b8727d Mon Sep 17 00:00:00 2001 From: f3tch <76998773+f3tchcodes@users.noreply.github.com> Date: Tue, 25 Aug 2026 22:32:32 +0500 Subject: [PATCH 4/4] test: clarify windows process cleanup comment Co-authored-by: Julian Descottes --- tests/setup.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/setup.ts b/tests/setup.ts index 3f9d8c1a..2f8dae23 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -71,8 +71,10 @@ function cleanupUnix() { } } -// Only matches Firefox instances whose command line carries --marionette, -// so regular user-launched Firefox windows are never touched. +/** + * Windows only. Retrieve all process ids matching the provided name and + * optional command line pattern. + */ function findWindowsProcessIds(imageName: string, commandLinePattern?: string): number[] { const filter = commandLinePattern ? `Name='${imageName}' AND CommandLine LIKE '%${commandLinePattern}%'`