diff --git a/packages/server/scripts/supervisor.logging.test.ts b/packages/server/scripts/supervisor.logging.test.ts index 7589cb92a1..6f9754994a 100644 --- a/packages/server/scripts/supervisor.logging.test.ts +++ b/packages/server/scripts/supervisor.logging.test.ts @@ -29,6 +29,7 @@ async function runSupervisorFixture(options: { blockLogPath?: boolean; /** Close the reading end of the supervisor's stdout and stderr as soon as it starts. */ closeOutput?: boolean; + env?: NodeJS.ProcessEnv; }): Promise<{ code: number | null; signal: NodeJS.Signals | null; @@ -84,7 +85,9 @@ async function runSupervisorFixture(options: { ]; const child = spawn(command, args, { cwd: repoRoot, - env: { ...process.env }, + // A Node color-conflict warning can hit closed stderr before runSupervisor installs + // its pipe-error handlers. This fixture exercises the supervisor's own output. + env: { ...process.env, ...options.env, NO_COLOR: undefined, FORCE_COLOR: undefined }, stdio: ["ignore", "pipe", "pipe"], }); @@ -205,10 +208,16 @@ describe("supervisor durable logging", () => { expect(result.stderr).toContain('"worker-json-stderr"'); }); - test("keeps supervising the worker when nobody reads its stdout or stderr", async () => { - const result = await runSupervisorFixture({ - closeOutput: true, - workerSource: ` + test.each([ + { colors: "inherited", env: {} }, + { colors: "conflicting", env: { NO_COLOR: "1", FORCE_COLOR: "1" } }, + ])( + "keeps supervising the worker when nobody reads its stdout or stderr with $colors colors", + async ({ env }) => { + const result = await runSupervisorFixture({ + closeOutput: true, + env, + workerSource: ` process.on("message", (message) => { if (message?.type === "paseo:graceful-shutdown") process.exit(0); }); @@ -220,14 +229,15 @@ describe("supervisor durable logging", () => { }, 500); setInterval(() => {}, 1000); `, - }); + }); - expect(result.code).toBe(0); - expect(result.signal).toBeNull(); - expect(result.log).toContain("first stderr line\n"); - expect(result.log).toContain("later stdout line\n"); - expect(result.log).toContain('"reason":"closed_output_probe"'); - }); + expect(result.code).toBe(0); + expect(result.signal).toBeNull(); + expect(result.log).toContain("first stderr line\n"); + expect(result.log).toContain("later stdout line\n"); + expect(result.log).toContain('"reason":"closed_output_probe"'); + }, + ); test("preserves raw non-JSON stdout and stderr lines", async () => { const result = await runSupervisorFixture({ diff --git a/packages/server/src/utils/spawn.launch-regression.test.ts b/packages/server/src/utils/spawn.launch-regression.test.ts index 847214c624..4943e68990 100644 --- a/packages/server/src/utils/spawn.launch-regression.test.ts +++ b/packages/server/src/utils/spawn.launch-regression.test.ts @@ -126,10 +126,15 @@ async function runFixture(params: { command: string; args: string[]; shell?: boolean; + env?: NodeJS.ProcessEnv; }): Promise { const child = spawnProcess(params.command, params.args, { env: { ...process.env, + ...params.env, + // Terminal color settings must not add Node warnings to the argv fixture's stderr. + NO_COLOR: undefined, + FORCE_COLOR: undefined, PASEO_EXPECTED_ARGV_JSON: JSON.stringify(["--config", JSON_ARG]), }, stdio: ["ignore", "pipe", "pipe"], @@ -216,6 +221,8 @@ async function findAndLaunch(fixture: LaunchFixture): Promise<{ const child = spawnProcess(found, fixture.args, { env: { ...process.env, + NO_COLOR: undefined, + FORCE_COLOR: undefined, PASEO_EXPECTED_ARGV_JSON: fixture.expectedArgvJson, PASEO_ARGV_SLICE_FROM: String(fixture.sliceFrom), }, @@ -331,18 +338,25 @@ describe.runIf(isPlatform("win32"))("Windows spawn launch regression", () => { }); describe.skipIf(isPlatform("win32"))("spawn launch regression smoke", () => { - test("direct launch with a space-containing executable works on this platform", async () => { - const fixture = makeFixture(); + test.each([ + { colors: "inherited", env: {} }, + { colors: "conflicting", env: { NO_COLOR: "1", FORCE_COLOR: "1" } }, + ])( + "direct launch with a space-containing executable works with $colors colors", + async ({ env }) => { + const fixture = makeFixture(); - const result = await runFixture({ - command: fixture.fakeDaemonNode, - args: [fixture.assertScript, ...fixture.expectedArgs], - shell: false, - }); + const result = await runFixture({ + command: fixture.fakeDaemonNode, + args: [fixture.assertScript, ...fixture.expectedArgs], + shell: false, + env, + }); - expect(result.error).toBeNull(); - expect(result.code).toBe(0); - expect(result.stderr).toBe(""); - expect(result.stdout.trim()).toBe("ARGV_OK"); - }); + expect(result.error).toBeNull(); + expect(result.code).toBe(0); + expect(result.stderr).toBe(""); + expect(result.stdout.trim()).toBe("ARGV_OK"); + }, + ); });