Files
siftlode/frontend/src/lib/e2eRetryConnect.test.ts
T
peter b9eb8458b3 test(e2e): a localhost connect the machine dropped is tried again on the test side
On a Windows host a burst of test traffic can drop a loopback connect now and then (every port,
any program — measured on the dev desktop). The browser resends it and only waits; Node (libuv)
sends a loopback SYN once and fails at ~300 ms with "connect ETIMEDOUT". `e2e/retryConnect.ts` wraps
Playwright's request context so that one error is tried again (0.5 / 1 / 2 / 4 / 8 s, the system's
own retry waits) while every other failure goes straight to the test; global.setup's health check,
login and /api/me and speed.measure's share probe go through it. Unit-tested; e2e 61/61.
2026-10-11 00:45:13 +02:00

42 lines
1.7 KiB
TypeScript

// The e2e suite's request wrapper (e2e/retryConnect.ts): a connect that never came about is tried
// again, as every TCP stack would; any other failure, or an answer, goes straight to the test.
import { describe, expect, it, vi } from "vitest";
import { retryConnect } from "../../e2e/retryConnect";
const noConnection = () => new Error("apiRequestContext.get: connect ETIMEDOUT 127.0.0.1:8080");
describe("retryConnect", () => {
it("tries a connect that timed out again, and hands back the answer that came", async () => {
vi.useFakeTimers();
const get = vi
.fn()
.mockRejectedValueOnce(noConnection())
.mockRejectedValueOnce(noConnection())
.mockResolvedValue("ok");
const api = retryConnect({ get });
const answer = api.get("/healthz");
await vi.runAllTimersAsync();
await expect(answer).resolves.toBe("ok");
expect(get).toHaveBeenCalledTimes(3);
expect(get).toHaveBeenLastCalledWith("/healthz");
vi.useRealTimers();
});
it("passes any other failure straight on, untried", async () => {
const post = vi.fn().mockRejectedValue(new Error("read ECONNRESET"));
await expect(retryConnect({ post }).post("/auth/password-login")).rejects.toThrow("ECONNRESET");
expect(post).toHaveBeenCalledTimes(1);
});
it("gives up after its last wait, with the connect error", async () => {
vi.useFakeTimers();
const get = vi.fn().mockRejectedValue(noConnection());
const answer = retryConnect({ get }).get("/api/me");
const settled = expect(answer).rejects.toThrow("ETIMEDOUT");
await vi.runAllTimersAsync();
await settled;
expect(get).toHaveBeenCalledTimes(6); // the first try and five more
vi.useRealTimers();
});
});