import "@testing-library/jest-dom"; 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 // don't throw URL-parse errors in the jsdom test environment. Tests that need // specific responses should mock the relevant `api.*` method as usual. beforeEach(() => { vi.stubGlobal( "fetch", vi.fn((input: string | URL | Request) => { const url = typeof input === "string" ? input : input.toString(); // Endpoints that return arrays need [] not {} to avoid "not iterable" errors. const arrayEndpoints = ["/agents/config"]; const body = arrayEndpoints.some((ep) => url.endsWith(ep)) ? JSON.stringify([]) : JSON.stringify({}); return Promise.resolve(new Response(body, { status: 200 })); }), ); });