From 4dcd4f43644509b05fdd97ec9506ca81b45c57f0 Mon Sep 17 00:00:00 2001 From: Hako Date: Thu, 13 Aug 2026 16:23:09 +0900 Subject: [PATCH] fix(test): wait for the second interrupt instead of sleeping The repeated-interrupt assertion slept 100ms and then required exactly two recorded interrupts, so a slower runner failed it: PR #37 went red on Node 24 while Node 22 passed on the same commit, and a rerun went green. waitForInterrupt now takes an expected count and polls to the harness deadline, so the test waits on the event it asserts. The equality check still pins exactly two, so an extra interrupt remains a failure. Verified by running the file three times in a row after the change. Co-Authored-By: Claude Opus 5 --- .../providers/tests/support/tmux-e2e-harness.ts | 15 ++++++++------- .../providers/tests/tmux-runtime.e2e.test.ts | 4 +++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/server/modules/providers/tests/support/tmux-e2e-harness.ts b/server/modules/providers/tests/support/tmux-e2e-harness.ts index 303e8fe..65b9ab7 100644 --- a/server/modules/providers/tests/support/tmux-e2e-harness.ts +++ b/server/modules/providers/tests/support/tmux-e2e-harness.ts @@ -32,7 +32,8 @@ export type FakeTmuxAgent = { events: () => Promise; waitUntilReady: () => Promise; waitForInput: (value: string) => Promise; - waitForInterrupt: () => Promise; + /** Resolves once at least `count` interrupts have been recorded. */ + waitForInterrupt: (count?: number) => Promise; waitForTurnStarted: () => Promise; waitForTurnInterrupted: () => Promise; }; @@ -325,9 +326,9 @@ export async function createTmuxE2EHarness(): Promise { async () => (await events()).some((event) => event.type === 'input' && event.value === value), `${sessionName} input ${JSON.stringify(value)}`, ), - waitForInterrupt: () => waitFor( - async () => (await events()).some((event) => event.type === 'interrupt'), - `${sessionName} SIGINT`, + waitForInterrupt: (count = 1) => waitFor( + async () => (await events()).filter((event) => event.type === 'interrupt').length >= count, + `${sessionName} SIGINT x${count}`, ), waitForTurnStarted: () => waitFor( async () => (await events()).some((event) => event.type === 'turn_started'), @@ -430,9 +431,9 @@ export async function createTmuxE2EHarness(): Promise { async () => (await events()).some((event) => event.type === 'input' && event.value === value), `${sessionName} input ${JSON.stringify(value)}`, ), - waitForInterrupt: () => waitFor( - async () => (await events()).some((event) => event.type === 'interrupt'), - `${sessionName} SIGINT`, + waitForInterrupt: (count = 1) => waitFor( + async () => (await events()).filter((event) => event.type === 'interrupt').length >= count, + `${sessionName} SIGINT x${count}`, ), waitForTurnStarted: () => waitFor( async () => (await events()).some((event) => event.type === 'turn_started'), diff --git a/server/modules/providers/tests/tmux-runtime.e2e.test.ts b/server/modules/providers/tests/tmux-runtime.e2e.test.ts index c407432..b75ce80 100644 --- a/server/modules/providers/tests/tmux-runtime.e2e.test.ts +++ b/server/modules/providers/tests/tmux-runtime.e2e.test.ts @@ -386,7 +386,9 @@ test('real tmux interrupt cancels a running verified fake-agent turn and repeats ); await sendTmuxProcessAction(target, 'interrupt'); - await delay(100); + // Wait for the second interrupt to be recorded instead of sleeping: a fixed + // delay made this assertion fail on slower CI runners (observed on Node 24). + await agent.waitForInterrupt(2); assert.equal( (await agent.events()).filter((event) => event.type === 'interrupt').length, 2,