diff --git a/browse/src/cli.ts b/browse/src/cli.ts index 59327b7923..b4a8a86092 100644 --- a/browse/src/cli.ts +++ b/browse/src/cli.ts @@ -285,6 +285,7 @@ function raiseHeadedWindowMacOS(): void { nodeSpawn('osascript', ['-e', 'tell application "Google Chrome for Testing" to activate'], { stdio: 'ignore', detached: true, + windowsHide: true, }).unref(); } catch { // osascript missing or app not present — non-fatal @@ -323,7 +324,7 @@ async function startServer(extraEnv?: Record): Promise): Promise !line.trim().startsWith("//")) + .join("\n"); +} + +// #1835 tripwire. On Windows, detached child_process.spawn allocates a +// console window unless windowsHide:true is set. These static checks fail CI +// if any detached spawn path in cli.ts drops the Windows no-window flag. +describe("#1835 detached browse spawns hide Windows consoles", () => { + test("Windows Node launcher spawn carries windowsHide:true", () => { + const src = readCodeOnly(); + expect(src).toMatch(/spawn\(process\.execPath,[\s\S]{0,500}detached:\s*true[\s\S]{0,100}windowsHide:\s*true/); + }); + + test("non-Windows server nodeSpawn carries windowsHide:true", () => { + const src = readCodeOnly(); + expect(src).toMatch(/nodeSpawn\('bun',[\s\S]{0,500}detached:\s*true[\s\S]{0,100}windowsHide:\s*true/); + }); + + test("every detached spawn site in cli.ts carries windowsHide:true", () => { + const src = readCodeOnly(); + const detachedSpawns = src.match(/detached:\s*true/g)?.length ?? 0; + const windowsHideFlags = src.match(/windowsHide:\s*true/g)?.length ?? 0; + expect(detachedSpawns).toBeGreaterThan(0); + expect(windowsHideFlags).toBeGreaterThanOrEqual(detachedSpawns); + }); +});