Skip to content

Commit a482b8f

Browse files
carderneTrigger.dev RepoOps
authored andcommitted
test(webapp): fix run-status backstop polling race
## Summary Fix the flaky run-status backstop test by controlling the polling interval while keeping real HTTP requests. Wait for each expected response before disabling polling, so an already-sent request cannot arrive after the request-count snapshot. Also replace the failed-poll recovery test's fixed delay with a condition-based wait. No production code changes. Verified with 20 consecutive runs of all four tests. Mono-RevId: a3d38fe9fdd77d4184f2f9afa2cd892c1a3793a8
1 parent 8864faa commit a482b8f

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

‎apps/webapp/test/useRunStatusBackstop.dom.test.ts‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import type { AddressInfo } from "node:net";
44
import { createElement } from "react";
55
import { createRoot, type Root } from "react-dom/client";
66
import { act } from "react-dom/test-utils";
7-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
7+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
88
import { useRunStatusBackstop } from "~/hooks/useRunStatusBackstop";
99

1010
type Reply = { status: number; body?: unknown };
1111

12+
const POLL_MS = 20;
13+
// expect.poll otherwise advances fake timers on every retry.
14+
const ASSERTION_POLL_OPTIONS = { interval: 0 };
15+
1216
let server: Server;
1317
let baseUrl: string;
1418
let replies: Reply[];
@@ -31,6 +35,7 @@ beforeEach(async () => {
3135

3236
afterEach(async () => {
3337
if (root) act(() => root!.unmount());
38+
vi.useRealTimers();
3439
container?.remove();
3540
container = undefined;
3641
root = undefined;
@@ -39,6 +44,10 @@ afterEach(async () => {
3944

4045
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
4146

47+
function poll() {
48+
act(() => vi.advanceTimersByTime(POLL_MS));
49+
}
50+
4251
function render(props: { enabled?: boolean; skip?: () => boolean }) {
4352
let finished = 0;
4453
function Harness({ enabled }: { enabled: boolean }) {
@@ -47,7 +56,7 @@ function render(props: { enabled?: boolean; skip?: () => boolean }) {
4756
statusPath: `${baseUrl}/status`,
4857
shouldSkip: props.skip ?? (() => false),
4958
onFinished: () => finished++,
50-
pollMs: 20,
59+
pollMs: POLL_MS,
5160
});
5261
return null;
5362
}
@@ -63,17 +72,24 @@ function render(props: { enabled?: boolean; skip?: () => boolean }) {
6372

6473
describe("useRunStatusBackstop", () => {
6574
it("calls onFinished on each poll that sees the run finished until disabled", async () => {
75+
vi.useFakeTimers({ toFake: ["setInterval", "clearInterval"] });
6676
replies = [
6777
{ status: 200, body: { isFinished: false, completedAt: null } },
6878
{ status: 200, body: { isFinished: true, completedAt: null } },
6979
];
7080
const harness = render({});
71-
await act(() => sleep(200));
72-
expect(harness.finished()).toBeGreaterThan(1);
81+
poll();
82+
await expect.poll(() => requests, ASSERTION_POLL_OPTIONS).toBe(1);
83+
expect(harness.finished()).toBe(0);
84+
poll();
85+
await expect.poll(harness.finished, ASSERTION_POLL_OPTIONS).toBe(1);
86+
poll();
87+
await expect.poll(harness.finished, ASSERTION_POLL_OPTIONS).toBe(2);
7388

7489
harness.disable();
7590
const finishedAtDisable = harness.finished();
7691
const requestsAtDisable = requests;
92+
act(() => vi.advanceTimersByTime(POLL_MS * 5));
7793
await act(() => sleep(100));
7894
expect(harness.finished()).toBe(finishedAtDisable);
7995
expect(requests).toBe(requestsAtDisable);
@@ -86,8 +102,7 @@ describe("useRunStatusBackstop", () => {
86102
{ status: 200, body: { isFinished: false, completedAt: "2026-10-06T10:00:00.000Z" } },
87103
];
88104
const harness = render({});
89-
await act(() => sleep(250));
90-
expect(harness.finished()).toBeGreaterThanOrEqual(1);
105+
await expect.poll(harness.finished).toBeGreaterThanOrEqual(1);
91106
});
92107

93108
it("does not poll while shouldSkip is true", async () => {

0 commit comments

Comments
 (0)