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,
|
getSessionPromptParams,
|
||||||
} from "../../shared/session-prompt-params-state"
|
} 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", () => {
|
describe("background-agent spawner agent-not-found fallback", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
clearSessionPromptParams("session-fallback")
|
clearSessionPromptParams("session-fallback")
|
||||||
@@ -67,7 +86,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
|||||||
await startTask(item as never, ctx as never)
|
await startTask(item as never, ctx as never)
|
||||||
|
|
||||||
// Wait for the fire-and-forget prompt chain to settle
|
// Wait for the fire-and-forget prompt chain to settle
|
||||||
await new Promise(resolve => setTimeout(resolve, 50))
|
await waitForCondition(() => promptCalls.length >= 2)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
// Should have called promptAsync twice: once with original agent, once with fallback
|
// 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
|
//#when
|
||||||
await startTask(item as never, ctx as never)
|
await startTask(item as never, ctx as never)
|
||||||
await new Promise(resolve => setTimeout(resolve, 50))
|
await waitForCondition(() => onTaskError.mock.calls.length > 0)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
// Only one attempt — no retry for non-agent errors
|
// Only one attempt — no retry for non-agent errors
|
||||||
@@ -199,7 +218,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
|||||||
|
|
||||||
//#when
|
//#when
|
||||||
await startTask(item as never, ctx as never)
|
await startTask(item as never, ctx as never)
|
||||||
await new Promise(resolve => setTimeout(resolve, 50))
|
await waitForCondition(() => onTaskError.mock.calls.length > 0)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
// Verify retry was attempted (2 calls: original + fallback)
|
// Verify retry was attempted (2 calls: original + fallback)
|
||||||
@@ -261,7 +280,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
|||||||
|
|
||||||
//#when
|
//#when
|
||||||
await startTask(item as never, ctx as never)
|
await startTask(item as never, ctx as never)
|
||||||
await new Promise(resolve => setTimeout(resolve, 50))
|
await waitForCondition(() => promptCalls.length >= 2)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(promptCalls).toHaveLength(2)
|
expect(promptCalls).toHaveLength(2)
|
||||||
@@ -324,7 +343,7 @@ describe("background-agent spawner agent-not-found fallback", () => {
|
|||||||
|
|
||||||
//#when
|
//#when
|
||||||
await startTask(item as never, ctx as never)
|
await startTask(item as never, ctx as never)
|
||||||
await new Promise(resolve => setTimeout(resolve, 50))
|
await waitForCondition(() => promptCalls.length >= 2)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(promptCalls).toHaveLength(2)
|
expect(promptCalls).toHaveLength(2)
|
||||||
|
|||||||
Reference in New Issue
Block a user