From b1c50cc5c0f7cf507e2785efecf43d2eb13884dd Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 23:03:29 +0000 Subject: [PATCH] test(browser): tighten relay test watchdog timeouts --- src/browser/extension-relay.test.ts | 218 +++++++++++++++------------- 1 file changed, 114 insertions(+), 104 deletions(-) diff --git a/src/browser/extension-relay.test.ts b/src/browser/extension-relay.test.ts index e943ca3e2..3464e82f3 100644 --- a/src/browser/extension-relay.test.ts +++ b/src/browser/extension-relay.test.ts @@ -9,6 +9,10 @@ import { } from "./extension-relay.js"; import { getFreePort } from "./test-port.js"; +const RELAY_MESSAGE_TIMEOUT_MS = 2_000; +const RELAY_LIST_MATCH_TIMEOUT_MS = 1_500; +const RELAY_TEST_TIMEOUT_MS = 10_000; + function waitForOpen(ws: WebSocket) { return new Promise((resolve, reject) => { ws.once("open", () => resolve()); @@ -81,7 +85,7 @@ function createMessageQueue(ws: WebSocket) { reject(err instanceof Error ? err : new Error(String(err))); }); - const next = (timeoutMs = 5000) => + const next = (timeoutMs = RELAY_MESSAGE_TIMEOUT_MS) => new Promise((resolve, reject) => { const existing = queue.shift(); if (existing !== undefined) { @@ -103,7 +107,7 @@ function createMessageQueue(ws: WebSocket) { async function waitForListMatch( fetchList: () => Promise, predicate: (value: T) => boolean, - timeoutMs = 2000, + timeoutMs = RELAY_LIST_MATCH_TIMEOUT_MS, intervalMs = 50, ): Promise { let latest: T | undefined; @@ -217,123 +221,129 @@ describe("chrome extension relay server", () => { ext.close(); }); - it("tracks attached page targets and exposes them via CDP + /json/list", async () => { - const port = await getFreePort(); - cdpUrl = `http://127.0.0.1:${port}`; - await ensureChromeExtensionRelayServer({ cdpUrl }); + it( + "tracks attached page targets and exposes them via CDP + /json/list", + async () => { + const port = await getFreePort(); + cdpUrl = `http://127.0.0.1:${port}`; + await ensureChromeExtensionRelayServer({ cdpUrl }); - const ext = new WebSocket(`ws://127.0.0.1:${port}/extension`, { - headers: relayAuthHeaders(`ws://127.0.0.1:${port}/extension`), - }); - await waitForOpen(ext); + const ext = new WebSocket(`ws://127.0.0.1:${port}/extension`, { + headers: relayAuthHeaders(`ws://127.0.0.1:${port}/extension`), + }); + await waitForOpen(ext); - // Simulate a tab attach coming from the extension. - ext.send( - JSON.stringify({ - method: "forwardCDPEvent", - params: { - method: "Target.attachedToTarget", + // Simulate a tab attach coming from the extension. + ext.send( + JSON.stringify({ + method: "forwardCDPEvent", params: { - sessionId: "cb-tab-1", - targetInfo: { - targetId: "t1", - type: "page", - title: "Example", - url: "https://example.com", - }, - waitingForDebugger: false, - }, - }, - }), - ); - - const list = (await fetch(`${cdpUrl}/json/list`, { - headers: relayAuthHeaders(cdpUrl), - }).then((r) => r.json())) as Array<{ - id?: string; - url?: string; - title?: string; - }>; - expect(list.some((t) => t.id === "t1" && t.url === "https://example.com")).toBe(true); - - // Simulate navigation updating tab metadata. - ext.send( - JSON.stringify({ - method: "forwardCDPEvent", - params: { - method: "Target.targetInfoChanged", - params: { - targetInfo: { - targetId: "t1", - type: "page", - title: "DER STANDARD", - url: "https://www.derstandard.at/", + method: "Target.attachedToTarget", + params: { + sessionId: "cb-tab-1", + targetInfo: { + targetId: "t1", + type: "page", + title: "Example", + url: "https://example.com", + }, + waitingForDebugger: false, }, }, - }, - }), - ); + }), + ); - const list2 = await waitForListMatch( - async () => - (await fetch(`${cdpUrl}/json/list`, { - headers: relayAuthHeaders(cdpUrl), - }).then((r) => r.json())) as Array<{ - id?: string; - url?: string; - title?: string; - }>, - (list) => - list.some( + const list = (await fetch(`${cdpUrl}/json/list`, { + headers: relayAuthHeaders(cdpUrl), + }).then((r) => r.json())) as Array<{ + id?: string; + url?: string; + title?: string; + }>; + expect(list.some((t) => t.id === "t1" && t.url === "https://example.com")).toBe(true); + + // Simulate navigation updating tab metadata. + ext.send( + JSON.stringify({ + method: "forwardCDPEvent", + params: { + method: "Target.targetInfoChanged", + params: { + targetInfo: { + targetId: "t1", + type: "page", + title: "DER STANDARD", + url: "https://www.derstandard.at/", + }, + }, + }, + }), + ); + + const list2 = await waitForListMatch( + async () => + (await fetch(`${cdpUrl}/json/list`, { + headers: relayAuthHeaders(cdpUrl), + }).then((r) => r.json())) as Array<{ + id?: string; + url?: string; + title?: string; + }>, + (list) => + list.some( + (t) => + t.id === "t1" && + t.url === "https://www.derstandard.at/" && + t.title === "DER STANDARD", + ), + ); + expect( + list2.some( (t) => t.id === "t1" && t.url === "https://www.derstandard.at/" && t.title === "DER STANDARD", ), - ); - expect( - list2.some( - (t) => - t.id === "t1" && t.url === "https://www.derstandard.at/" && t.title === "DER STANDARD", - ), - ).toBe(true); + ).toBe(true); - const cdp = new WebSocket(`ws://127.0.0.1:${port}/cdp`, { - headers: relayAuthHeaders(`ws://127.0.0.1:${port}/cdp`), - }); - await waitForOpen(cdp); - const q = createMessageQueue(cdp); + const cdp = new WebSocket(`ws://127.0.0.1:${port}/cdp`, { + headers: relayAuthHeaders(`ws://127.0.0.1:${port}/cdp`), + }); + await waitForOpen(cdp); + const q = createMessageQueue(cdp); - cdp.send(JSON.stringify({ id: 1, method: "Target.getTargets" })); - const res1 = JSON.parse(await q.next()) as { id: number; result?: unknown }; - expect(res1.id).toBe(1); - expect(JSON.stringify(res1.result ?? {})).toContain("t1"); + cdp.send(JSON.stringify({ id: 1, method: "Target.getTargets" })); + const res1 = JSON.parse(await q.next()) as { id: number; result?: unknown }; + expect(res1.id).toBe(1); + expect(JSON.stringify(res1.result ?? {})).toContain("t1"); - cdp.send( - JSON.stringify({ - id: 2, - method: "Target.attachToTarget", - params: { targetId: "t1" }, - }), - ); - const received: Array<{ - id?: number; - method?: string; - result?: unknown; - params?: unknown; - }> = []; - received.push(JSON.parse(await q.next()) as never); - received.push(JSON.parse(await q.next()) as never); + cdp.send( + JSON.stringify({ + id: 2, + method: "Target.attachToTarget", + params: { targetId: "t1" }, + }), + ); + const received: Array<{ + id?: number; + method?: string; + result?: unknown; + params?: unknown; + }> = []; + received.push(JSON.parse(await q.next()) as never); + received.push(JSON.parse(await q.next()) as never); - const res2 = received.find((m) => m.id === 2); - expect(res2?.id).toBe(2); - expect(JSON.stringify(res2?.result ?? {})).toContain("cb-tab-1"); + const res2 = received.find((m) => m.id === 2); + expect(res2?.id).toBe(2); + expect(JSON.stringify(res2?.result ?? {})).toContain("cb-tab-1"); - const evt = received.find((m) => m.method === "Target.attachedToTarget"); - expect(evt?.method).toBe("Target.attachedToTarget"); - expect(JSON.stringify(evt?.params ?? {})).toContain("t1"); + const evt = received.find((m) => m.method === "Target.attachedToTarget"); + expect(evt?.method).toBe("Target.attachedToTarget"); + expect(JSON.stringify(evt?.params ?? {})).toContain("t1"); - cdp.close(); - ext.close(); - }, 15_000); + cdp.close(); + ext.close(); + }, + RELAY_TEST_TIMEOUT_MS, + ); it("rebroadcasts attach when a session id is reused for a new target", async () => { const port = await getFreePort();