From bc55e1ea3eaef536126d43f83c6ff8d44f9b57c0 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 15 Jul 2026 13:44:09 -0700 Subject: [PATCH] test(codex): stabilize nullable-turn watch proof (#108456) --- .../run-attempt.turn-watches.test.ts | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/extensions/codex/src/app-server/run-attempt.turn-watches.test.ts b/extensions/codex/src/app-server/run-attempt.turn-watches.test.ts index 4c312f876cb6..9480d9f3b9d3 100644 --- a/extensions/codex/src/app-server/run-attempt.turn-watches.test.ts +++ b/extensions/codex/src/app-server/run-attempt.turn-watches.test.ts @@ -49,9 +49,7 @@ const DISABLED_CODEX_WEB_SEARCH_THREAD_CONFIG_FINGERPRINT = JSON.stringify({ web_search: "disabled", }); -function writeCodexAppServerBinding( - ...args: Parameters -) { +function writeCodexAppServerBinding(...args: Parameters) { const [sessionFile, binding, lookup] = args; return writeRawCodexAppServerBinding( sessionFile, @@ -704,7 +702,10 @@ describe("runCodexAppServerAttempt turn watches", () => { expect(harness.request.mock.calls.some(([method]) => method === "turn/interrupt")).toBe(true); }); - it("counts handled nullable-turn elicitations as turn attempt progress", async () => { + it("refreshes the turn attempt watch for handled nullable-turn elicitations", async () => { + let nowMs = 1_000_000; + vi.spyOn(Date, "now").mockImplementation(() => nowMs); + const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout"); const harness = createStartedThreadHarness(); vi.spyOn(elicitationBridge, "handleCodexAppServerElicitationRequest").mockResolvedValue({ action: "accept", @@ -715,7 +716,7 @@ describe("runCodexAppServerAttempt turn watches", () => { path.join(tempDir, "session.jsonl"), path.join(tempDir, "workspace"), ); - params.timeoutMs = 100; + params.timeoutMs = 10_000; const onRunProgress = vi.fn(); params.onRunProgress = onRunProgress; @@ -732,10 +733,14 @@ describe("runCodexAppServerAttempt turn watches", () => { ), fastWait, ); + const initialAttemptWatch = setTimeoutSpy.mock.calls.find( + ([callback]) => typeof callback === "function" && callback.name === "fireAttemptIdleTimeout", + )?.[0]; + if (typeof initialAttemptWatch !== "function") { + throw new Error("Expected the initial turn attempt watch timer"); + } + nowMs += 6_000; - await new Promise((resolve) => { - setTimeout(resolve, 60); - }); await harness.handleServerRequest({ id: "request-null-turn-elicitation", method: "mcpServer/elicitation/request", @@ -749,9 +754,15 @@ describe("runCodexAppServerAttempt turn watches", () => { _meta: null, }, }); - await new Promise((resolve) => { - setTimeout(resolve, 60); - }); + await vi.waitFor( + () => + expect(onRunProgress).toHaveBeenCalledWith( + expect.objectContaining({ reason: "request:mcpServer/elicitation/request:start" }), + ), + fastWait, + ); + nowMs += 6_000; + initialAttemptWatch(); expect(harness.request.mock.calls.some(([method]) => method === "turn/interrupt")).toBe(false); await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });