From 32fc0d43adb242f72adcee9d5ed66fe0dc628017 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 3 Sep 2026 16:43:28 +0900 Subject: [PATCH] test(ai): wait for the manual OAuth prompt before aborting the login The abort raced a setTimeout(0) against the login opening its manual prompt and then judged the outcome with a 500 ms timer; loaded CI runners opened the prompt late and reported 'still pending'. Resolve an explicit signal from the prompt callback, await it, then abort and assert the settled rejection. --- packages/ai/test/anthropic-oauth.test.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/ai/test/anthropic-oauth.test.ts b/packages/ai/test/anthropic-oauth.test.ts index a5498bdb62..2db5598f81 100644 --- a/packages/ai/test/anthropic-oauth.test.ts +++ b/packages/ai/test/anthropic-oauth.test.ts @@ -100,6 +100,12 @@ describe.sequential("Anthropic OAuth", () => { installFailingListen("EADDRINUSE"); const controller = new AbortController(); let promptSignal: AbortSignal | undefined; + // Resolve the moment the login opens its manual prompt, so the abort below is + // ordered after the prompt exists instead of racing a macrotask tick. + let promptOpened!: () => void; + const opened = new Promise((resolve) => { + promptOpened = resolve; + }); const login = anthropicOAuth.login({ signal: controller.signal, notify: vi.fn(), @@ -107,21 +113,17 @@ describe.sequential("Anthropic OAuth", () => { new Promise((_resolve, reject) => { promptSignal = prompt.signal; prompt.signal?.addEventListener("abort", () => reject(new Error("prompt aborted")), { once: true }); + promptOpened(); }), }); const settled = login.then( () => "resolved", (error: unknown) => (error instanceof Error ? error.message : String(error)), ); - // Give the login a turn to open the manual prompt, then cancel from the outside. - await new Promise((resolve) => setTimeout(resolve, 0)); + await opened; controller.abort(); - const outcome = await Promise.race([ - settled, - new Promise((resolve) => setTimeout(() => resolve("still pending"), 500)), - ]); + expect(await settled).toBe("prompt aborted"); expect(promptSignal?.aborted).toBe(true); - expect(outcome).toBe("prompt aborted"); }); it("rejects non-bind callback errors with the callback host and port", async () => {