From 1ede829fbfa9b014a4c8f5ce718a5349cab4119d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 20 Jun 2026 12:50:08 +0200 Subject: [PATCH] fix(qa-lab): leave vitest timeout cleanup to wrapper --- .../src/test-file-scenario-runner.test.ts | 3 ++ .../qa-lab/src/test-file-scenario-runner.ts | 34 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/extensions/qa-lab/src/test-file-scenario-runner.test.ts b/extensions/qa-lab/src/test-file-scenario-runner.test.ts index bd5f535fd7cb..6aa84c9b60e0 100644 --- a/extensions/qa-lab/src/test-file-scenario-runner.test.ts +++ b/extensions/qa-lab/src/test-file-scenario-runner.test.ts @@ -132,6 +132,7 @@ describe("qa test file scenario runner", () => { "--reporter=verbose", ], ]); + expect(commands.map((command) => command.timeoutMs)).toEqual([undefined, undefined]); const evidence = validateQaEvidenceSummaryJson( JSON.parse(await fs.readFile(result.evidencePath, "utf8")), ); @@ -208,6 +209,7 @@ describe("qa test file scenario runner", () => { "--reporter=verbose", ], ]); + expect(commands.map((command) => command.timeoutMs)).toEqual([undefined]); const evidence = validateQaEvidenceSummaryJson( JSON.parse(await fs.readFile(result.evidencePath, "utf8")), ); @@ -344,6 +346,7 @@ describe("qa test file scenario runner", () => { path.join(repoRoot, ".artifacts", "qa-e2e", "scenario-script", "scenario-script"), ], ]); + expect(commands.map((command) => command.timeoutMs)).toEqual([30 * 60_000]); const evidence = validateQaEvidenceSummaryJson( JSON.parse(await fs.readFile(result.evidencePath, "utf8")), ); diff --git a/extensions/qa-lab/src/test-file-scenario-runner.ts b/extensions/qa-lab/src/test-file-scenario-runner.ts index 574b999423e4..89025a49a061 100644 --- a/extensions/qa-lab/src/test-file-scenario-runner.ts +++ b/extensions/qa-lab/src/test-file-scenario-runner.ts @@ -48,7 +48,7 @@ export type QaScenarioCommandExecution = { command: string; cwd: string; env: NodeJS.ProcessEnv; - timeoutMs: number; + timeoutMs?: number; }; type QaScenarioCommandResult = { @@ -199,6 +199,7 @@ function runQaScenarioCommand( }); const stdout: Buffer[] = []; const stderr: Buffer[] = []; + const timeoutMs = execution.timeoutMs; let forceKillTimer: NodeJS.Timeout | undefined; let forceSettleTimer: NodeJS.Timeout | undefined; let settled = false; @@ -307,16 +308,19 @@ function runQaScenarioCommand( }, QA_TEST_FILE_COMMAND_TIMEOUT_FORCE_SETTLE_MS); }, QA_TEST_FILE_COMMAND_TIMEOUT_KILL_GRACE_MS); }; - timeoutTimer = setTimeout(() => { - timeoutTimer = undefined; - timedOut = true; - signalChild("SIGTERM"); - scheduleForcedCleanup({ - exitCode: 1, - failureMessage: `${commandLabel()} timed out after ${execution.timeoutMs}ms`, - signal: null, - }); - }, execution.timeoutMs); + timeoutTimer = + timeoutMs === undefined + ? undefined + : setTimeout(() => { + timeoutTimer = undefined; + timedOut = true; + signalChild("SIGTERM"); + scheduleForcedCleanup({ + exitCode: 1, + failureMessage: `${commandLabel()} timed out after ${timeoutMs}ms`, + signal: null, + }); + }, timeoutMs); child.stdout?.on("data", (chunk: Buffer) => { stdout.push(chunk); }); @@ -340,9 +344,7 @@ function runQaScenarioCommand( const result = { exitCode: timedOut ? 1 : (exitCode ?? (signal ? 1 : 0)), signal, - ...(timedOut - ? { failureMessage: `${commandLabel()} timed out after ${execution.timeoutMs}ms` } - : {}), + ...(timedOut ? { failureMessage: `${commandLabel()} timed out after ${timeoutMs}ms` } : {}), }; if (isProcessGroupRunning()) { if (!timedOut) { @@ -384,12 +386,14 @@ async function runScenarioCommandSteps(params: { for (const step of params.steps) { logChunks.push(`$ ${formatCommand(step)}\n`); try { + const timeoutMs = + params.scenario.execution.kind === "script" ? params.commandTimeoutMs : undefined; const result = await params.runCommand({ command: step.command, args: step.args, cwd: params.repoRoot, env: params.env, - timeoutMs: params.commandTimeoutMs, + ...(timeoutMs === undefined ? {} : { timeoutMs }), }); if (result.stdout) { logChunks.push(result.stdout);