fix(test): stub WebSocket in setupTests so rpcCall fails fast
770's HTTP→read-RPC migration replaced fetch-based agent calls with rpcCall over WebSocket. setupTests.ts only mocks fetch though, so the real jsdom WebSocket runs — and jsdom's WebSocket implementation asynchronously fires its connection-failure error after ~9 seconds (via internal Timeout._onTimeout). Tests that await component-mount state (like App.test.tsx > calls getCurrentProject() on mount) hang on that pending promise and time out at 10s. This silently broke 1 test on master (App.test.tsx getCurrentProject on mount) and cascaded into 16 failures in any worktree where the test file count changed and timing shifted (804, 806). Fix: replace the global WebSocket constructor with a stub that immediately fires onerror + onclose on the next microtask. rpcCall sees the error and rejects synchronously; components catch and continue rendering with empty state. Tests pass without flake. Verified locally: vitest run → 349/349 pass.
This commit is contained in:
@@ -1,6 +1,31 @@
|
|||||||
import "@testing-library/jest-dom";
|
import "@testing-library/jest-dom";
|
||||||
import { beforeEach, vi } from "vitest";
|
import { beforeEach, vi } from "vitest";
|
||||||
|
|
||||||
|
// Default WebSocket stub: every `new WebSocket(...)` immediately fires
|
||||||
|
// `onerror` + `onclose` on the next microtask. Without this, `rpcCall` from
|
||||||
|
// `./api/rpc` (added by 770's HTTP→read-RPC migration) opens a real jsdom
|
||||||
|
// WebSocket that hangs ~9s before firing its connection-failure error,
|
||||||
|
// making any test that mounts a component calling `listAgents()` time out.
|
||||||
|
// Tests that need real WS responses should override per-test with
|
||||||
|
// `vi.stubGlobal("WebSocket", ...)`.
|
||||||
|
class FailingWebSocket {
|
||||||
|
onopen: ((ev: Event) => void) | null = null;
|
||||||
|
onmessage: ((ev: MessageEvent) => void) | null = null;
|
||||||
|
onerror: ((ev: Event) => void) | null = null;
|
||||||
|
onclose: ((ev: CloseEvent) => void) | null = null;
|
||||||
|
readyState = 0;
|
||||||
|
constructor(_url: string) {
|
||||||
|
queueMicrotask(() => {
|
||||||
|
this.readyState = 3;
|
||||||
|
this.onerror?.(new Event("error"));
|
||||||
|
this.onclose?.(new CloseEvent("close"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
send(_data: string) {}
|
||||||
|
close() {}
|
||||||
|
}
|
||||||
|
vi.stubGlobal("WebSocket", FailingWebSocket);
|
||||||
|
|
||||||
// Provide a default fetch mock so components that call API endpoints on mount
|
// Provide a default fetch mock so components that call API endpoints on mount
|
||||||
// don't throw URL-parse errors in the jsdom test environment. Tests that need
|
// don't throw URL-parse errors in the jsdom test environment. Tests that need
|
||||||
// specific responses should mock the relevant `api.*` method as usual.
|
// specific responses should mock the relevant `api.*` method as usual.
|
||||||
|
|||||||
Reference in New Issue
Block a user