mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 00:28:26 +00:00
test(browser): tighten relay test watchdog timeouts
This commit is contained in:
@@ -9,6 +9,10 @@ import {
|
|||||||
} from "./extension-relay.js";
|
} from "./extension-relay.js";
|
||||||
import { getFreePort } from "./test-port.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) {
|
function waitForOpen(ws: WebSocket) {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
ws.once("open", () => resolve());
|
ws.once("open", () => resolve());
|
||||||
@@ -81,7 +85,7 @@ function createMessageQueue(ws: WebSocket) {
|
|||||||
reject(err instanceof Error ? err : new Error(String(err)));
|
reject(err instanceof Error ? err : new Error(String(err)));
|
||||||
});
|
});
|
||||||
|
|
||||||
const next = (timeoutMs = 5000) =>
|
const next = (timeoutMs = RELAY_MESSAGE_TIMEOUT_MS) =>
|
||||||
new Promise<string>((resolve, reject) => {
|
new Promise<string>((resolve, reject) => {
|
||||||
const existing = queue.shift();
|
const existing = queue.shift();
|
||||||
if (existing !== undefined) {
|
if (existing !== undefined) {
|
||||||
@@ -103,7 +107,7 @@ function createMessageQueue(ws: WebSocket) {
|
|||||||
async function waitForListMatch<T>(
|
async function waitForListMatch<T>(
|
||||||
fetchList: () => Promise<T>,
|
fetchList: () => Promise<T>,
|
||||||
predicate: (value: T) => boolean,
|
predicate: (value: T) => boolean,
|
||||||
timeoutMs = 2000,
|
timeoutMs = RELAY_LIST_MATCH_TIMEOUT_MS,
|
||||||
intervalMs = 50,
|
intervalMs = 50,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
let latest: T | undefined;
|
let latest: T | undefined;
|
||||||
@@ -217,123 +221,129 @@ describe("chrome extension relay server", () => {
|
|||||||
ext.close();
|
ext.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("tracks attached page targets and exposes them via CDP + /json/list", async () => {
|
it(
|
||||||
const port = await getFreePort();
|
"tracks attached page targets and exposes them via CDP + /json/list",
|
||||||
cdpUrl = `http://127.0.0.1:${port}`;
|
async () => {
|
||||||
await ensureChromeExtensionRelayServer({ cdpUrl });
|
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`, {
|
const ext = new WebSocket(`ws://127.0.0.1:${port}/extension`, {
|
||||||
headers: relayAuthHeaders(`ws://127.0.0.1:${port}/extension`),
|
headers: relayAuthHeaders(`ws://127.0.0.1:${port}/extension`),
|
||||||
});
|
});
|
||||||
await waitForOpen(ext);
|
await waitForOpen(ext);
|
||||||
|
|
||||||
// Simulate a tab attach coming from the extension.
|
// Simulate a tab attach coming from the extension.
|
||||||
ext.send(
|
ext.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
method: "forwardCDPEvent",
|
method: "forwardCDPEvent",
|
||||||
params: {
|
|
||||||
method: "Target.attachedToTarget",
|
|
||||||
params: {
|
params: {
|
||||||
sessionId: "cb-tab-1",
|
method: "Target.attachedToTarget",
|
||||||
targetInfo: {
|
params: {
|
||||||
targetId: "t1",
|
sessionId: "cb-tab-1",
|
||||||
type: "page",
|
targetInfo: {
|
||||||
title: "Example",
|
targetId: "t1",
|
||||||
url: "https://example.com",
|
type: "page",
|
||||||
},
|
title: "Example",
|
||||||
waitingForDebugger: false,
|
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/",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
}),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const list2 = await waitForListMatch(
|
const list = (await fetch(`${cdpUrl}/json/list`, {
|
||||||
async () =>
|
headers: relayAuthHeaders(cdpUrl),
|
||||||
(await fetch(`${cdpUrl}/json/list`, {
|
}).then((r) => r.json())) as Array<{
|
||||||
headers: relayAuthHeaders(cdpUrl),
|
id?: string;
|
||||||
}).then((r) => r.json())) as Array<{
|
url?: string;
|
||||||
id?: string;
|
title?: string;
|
||||||
url?: string;
|
}>;
|
||||||
title?: string;
|
expect(list.some((t) => t.id === "t1" && t.url === "https://example.com")).toBe(true);
|
||||||
}>,
|
|
||||||
(list) =>
|
// Simulate navigation updating tab metadata.
|
||||||
list.some(
|
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) =>
|
||||||
t.id === "t1" && t.url === "https://www.derstandard.at/" && t.title === "DER STANDARD",
|
t.id === "t1" && t.url === "https://www.derstandard.at/" && t.title === "DER STANDARD",
|
||||||
),
|
),
|
||||||
);
|
).toBe(true);
|
||||||
expect(
|
|
||||||
list2.some(
|
|
||||||
(t) =>
|
|
||||||
t.id === "t1" && t.url === "https://www.derstandard.at/" && t.title === "DER STANDARD",
|
|
||||||
),
|
|
||||||
).toBe(true);
|
|
||||||
|
|
||||||
const cdp = new WebSocket(`ws://127.0.0.1:${port}/cdp`, {
|
const cdp = new WebSocket(`ws://127.0.0.1:${port}/cdp`, {
|
||||||
headers: relayAuthHeaders(`ws://127.0.0.1:${port}/cdp`),
|
headers: relayAuthHeaders(`ws://127.0.0.1:${port}/cdp`),
|
||||||
});
|
});
|
||||||
await waitForOpen(cdp);
|
await waitForOpen(cdp);
|
||||||
const q = createMessageQueue(cdp);
|
const q = createMessageQueue(cdp);
|
||||||
|
|
||||||
cdp.send(JSON.stringify({ id: 1, method: "Target.getTargets" }));
|
cdp.send(JSON.stringify({ id: 1, method: "Target.getTargets" }));
|
||||||
const res1 = JSON.parse(await q.next()) as { id: number; result?: unknown };
|
const res1 = JSON.parse(await q.next()) as { id: number; result?: unknown };
|
||||||
expect(res1.id).toBe(1);
|
expect(res1.id).toBe(1);
|
||||||
expect(JSON.stringify(res1.result ?? {})).toContain("t1");
|
expect(JSON.stringify(res1.result ?? {})).toContain("t1");
|
||||||
|
|
||||||
cdp.send(
|
cdp.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
id: 2,
|
id: 2,
|
||||||
method: "Target.attachToTarget",
|
method: "Target.attachToTarget",
|
||||||
params: { targetId: "t1" },
|
params: { targetId: "t1" },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const received: Array<{
|
const received: Array<{
|
||||||
id?: number;
|
id?: number;
|
||||||
method?: string;
|
method?: string;
|
||||||
result?: unknown;
|
result?: unknown;
|
||||||
params?: unknown;
|
params?: unknown;
|
||||||
}> = [];
|
}> = [];
|
||||||
received.push(JSON.parse(await q.next()) as never);
|
received.push(JSON.parse(await q.next()) as never);
|
||||||
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);
|
const res2 = received.find((m) => m.id === 2);
|
||||||
expect(res2?.id).toBe(2);
|
expect(res2?.id).toBe(2);
|
||||||
expect(JSON.stringify(res2?.result ?? {})).toContain("cb-tab-1");
|
expect(JSON.stringify(res2?.result ?? {})).toContain("cb-tab-1");
|
||||||
|
|
||||||
const evt = received.find((m) => m.method === "Target.attachedToTarget");
|
const evt = received.find((m) => m.method === "Target.attachedToTarget");
|
||||||
expect(evt?.method).toBe("Target.attachedToTarget");
|
expect(evt?.method).toBe("Target.attachedToTarget");
|
||||||
expect(JSON.stringify(evt?.params ?? {})).toContain("t1");
|
expect(JSON.stringify(evt?.params ?? {})).toContain("t1");
|
||||||
|
|
||||||
cdp.close();
|
cdp.close();
|
||||||
ext.close();
|
ext.close();
|
||||||
}, 15_000);
|
},
|
||||||
|
RELAY_TEST_TIMEOUT_MS,
|
||||||
|
);
|
||||||
|
|
||||||
it("rebroadcasts attach when a session id is reused for a new target", async () => {
|
it("rebroadcasts attach when a session id is reused for a new target", async () => {
|
||||||
const port = await getFreePort();
|
const port = await getFreePort();
|
||||||
|
|||||||
Reference in New Issue
Block a user