fix: replace brittle setTimeout(50) with polling waitForCondition in spawner tests
The agent-not-found fallback tests use fire-and-forget prompt chains that must settle before assertions run. A fixed 50ms setTimeout is insufficient on slower CI runners, causing intermittent failures. Replace with waitForCondition() that polls at 10ms intervals with a 2s timeout — fast on green runs, reliable on slow CI. Closes #3935
This commit is contained in:
@@ -6,6 +6,25 @@ import {
|
||||
getSessionPromptParams,
|
||||
} from "../../shared/session-prompt-params-state"
|
||||
|
||||
/**
|
||||
* Poll until `fn()` returns true or timeout elapses.
|
||||
* Replaces fixed `setTimeout(resolve, 50)` waits that cause flaky CI failures
|
||||
* when the fire-and-forget prompt chain hasn't settled in time.
|
||||
*/
|
||||
async function waitForCondition(
|
||||
fn: () => boolean,
|
||||
timeoutMs = 2000,
|
||||
intervalMs = 10,
|
||||
): Promise<void> {
|
||||
const start = Date.now()
|
||||
while (!fn()) {
|
||||
if (Date.now() - start > timeoutMs) {
|
||||
throw new Error(`waitForCondition timed out after ${timeoutMs}ms`)
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, intervalMs))
|
||||
}
|
||||
}
|
||||
|
||||
describe("background-agent spawner agent-not-found fallback", () => {
|
||||
afterEach(() => {
|
||||
clearSessionPromptParams("session-fallback")
|
||||
@@ -67,7 +86,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
||||
await startTask(item as never, ctx as never)
|
||||
|
||||
// Wait for the fire-and-forget prompt chain to settle
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await waitForCondition(() => promptCalls.length >= 2)
|
||||
|
||||
//#then
|
||||
// Should have called promptAsync twice: once with original agent, once with fallback
|
||||
@@ -146,7 +165,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
||||
|
||||
//#when
|
||||
await startTask(item as never, ctx as never)
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await waitForCondition(() => onTaskError.mock.calls.length > 0)
|
||||
|
||||
//#then
|
||||
// Only one attempt — no retry for non-agent errors
|
||||
@@ -199,7 +218,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
||||
|
||||
//#when
|
||||
await startTask(item as never, ctx as never)
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await waitForCondition(() => onTaskError.mock.calls.length > 0)
|
||||
|
||||
//#then
|
||||
// Verify retry was attempted (2 calls: original + fallback)
|
||||
@@ -261,7 +280,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
||||
|
||||
//#when
|
||||
await startTask(item as never, ctx as never)
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await waitForCondition(() => promptCalls.length >= 2)
|
||||
|
||||
//#then
|
||||
expect(promptCalls).toHaveLength(2)
|
||||
@@ -324,7 +343,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
||||
|
||||
//#when
|
||||
await startTask(item as never, ctx as never)
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
await waitForCondition(() => promptCalls.length >= 2)
|
||||
|
||||
//#then
|
||||
expect(promptCalls).toHaveLength(2)
|
||||
|
||||
Reference in New Issue
Block a user