mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:20:42 +00:00
test: share browser route fixtures
This commit is contained in:
@@ -97,6 +97,10 @@ describe("existing-session interaction navigation guard", () => {
|
||||
}
|
||||
|
||||
async function expectActionToReject(body: Record<string, unknown>) {
|
||||
await expectActionToThrow(body, "Unable to verify stable post-interaction navigation");
|
||||
}
|
||||
|
||||
async function expectActionToThrow(body: Record<string, unknown>, message: string) {
|
||||
const handler = getActPostHandler();
|
||||
const response = createBrowserRouteResponse();
|
||||
const pending = handler?.({ params: {}, query: {}, body }, response.res) ?? Promise.resolve();
|
||||
@@ -106,7 +110,7 @@ describe("existing-session interaction navigation guard", () => {
|
||||
await pending;
|
||||
})();
|
||||
|
||||
await expect(completion).rejects.toThrow("Unable to verify stable post-interaction navigation");
|
||||
await expect(completion).rejects.toThrow(message);
|
||||
}
|
||||
|
||||
function expectNavigationProbeUrls(urls: string[]) {
|
||||
@@ -215,18 +219,7 @@ describe("existing-session interaction navigation guard", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const handler = getActPostHandler();
|
||||
const response = createBrowserRouteResponse();
|
||||
const pending =
|
||||
handler?.({ params: {}, query: {}, body: { kind: "click", ref: "btn-1" } }, response.res) ??
|
||||
Promise.resolve();
|
||||
void pending.catch(() => {});
|
||||
const completion = (async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
await pending;
|
||||
})();
|
||||
|
||||
await expect(completion).rejects.toThrow("blocked new tab");
|
||||
await expectActionToThrow({ kind: "click", ref: "btn-1" }, "blocked new tab");
|
||||
expect(chromeMcpMocks.clickChromeMcpElement).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
@@ -338,18 +331,7 @@ describe("existing-session interaction navigation guard", () => {
|
||||
throw new Error("stale element");
|
||||
});
|
||||
|
||||
const handler = getActPostHandler();
|
||||
const response = createBrowserRouteResponse();
|
||||
const pending =
|
||||
handler?.({ params: {}, query: {}, body: { kind: "click", ref: "btn-1" } }, response.res) ??
|
||||
Promise.resolve();
|
||||
void pending.catch(() => {});
|
||||
const completion = (async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
await pending;
|
||||
})();
|
||||
|
||||
await expect(completion).rejects.toThrow("stale element");
|
||||
await expectActionToThrow({ kind: "click", ref: "btn-1" }, "stale element");
|
||||
expect(chromeMcpMocks.evaluateChromeMcpScript).toHaveBeenCalled();
|
||||
expect(navigationGuardMocks.assertBrowserNavigationResultAllowed).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -25,6 +25,27 @@ function setupEnsureBrowserAvailableHarness() {
|
||||
return { launchOpenClawChrome, stopOpenClawChrome, isChromeCdpReady, profile, state };
|
||||
}
|
||||
|
||||
function createAttachOnlyLoopbackProfile(cdpUrl: string) {
|
||||
const state = makeBrowserServerState({
|
||||
profile: {
|
||||
name: "manual-cdp",
|
||||
cdpUrl,
|
||||
cdpHost: "127.0.0.1",
|
||||
cdpIsLoopback: true,
|
||||
cdpPort: 9222,
|
||||
color: "#00AA00",
|
||||
driver: "openclaw",
|
||||
attachOnly: true,
|
||||
},
|
||||
resolvedOverrides: {
|
||||
defaultProfile: "manual-cdp",
|
||||
ssrfPolicy: {},
|
||||
},
|
||||
});
|
||||
const ctx = createBrowserRouteContext({ getState: () => state });
|
||||
return { profile: ctx.forProfile("manual-cdp"), state };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
vi.clearAllMocks();
|
||||
@@ -142,24 +163,7 @@ describe("browser server-context ensureBrowserAvailable", () => {
|
||||
const isChromeReachable = vi.mocked(chromeModule.isChromeReachable);
|
||||
const isChromeCdpReady = vi.mocked(chromeModule.isChromeCdpReady);
|
||||
|
||||
const state = makeBrowserServerState({
|
||||
profile: {
|
||||
name: "manual-cdp",
|
||||
cdpUrl: "http://127.0.0.1:9222",
|
||||
cdpHost: "127.0.0.1",
|
||||
cdpIsLoopback: true,
|
||||
cdpPort: 9222,
|
||||
color: "#00AA00",
|
||||
driver: "openclaw",
|
||||
attachOnly: true,
|
||||
},
|
||||
resolvedOverrides: {
|
||||
defaultProfile: "manual-cdp",
|
||||
ssrfPolicy: {},
|
||||
},
|
||||
});
|
||||
const ctx = createBrowserRouteContext({ getState: () => state });
|
||||
const profile = ctx.forProfile("manual-cdp");
|
||||
const { profile, state } = createAttachOnlyLoopbackProfile("http://127.0.0.1:9222");
|
||||
|
||||
isChromeReachable.mockResolvedValueOnce(true);
|
||||
isChromeCdpReady.mockResolvedValueOnce(true);
|
||||
@@ -195,24 +199,7 @@ describe("browser server-context ensureBrowserAvailable", () => {
|
||||
const isChromeReachable = vi.mocked(chromeModule.isChromeReachable);
|
||||
const isChromeCdpReady = vi.mocked(chromeModule.isChromeCdpReady);
|
||||
|
||||
const state = makeBrowserServerState({
|
||||
profile: {
|
||||
name: "manual-cdp",
|
||||
cdpUrl: "ws://127.0.0.1:9222",
|
||||
cdpHost: "127.0.0.1",
|
||||
cdpIsLoopback: true,
|
||||
cdpPort: 9222,
|
||||
color: "#00AA00",
|
||||
driver: "openclaw",
|
||||
attachOnly: true,
|
||||
},
|
||||
resolvedOverrides: {
|
||||
defaultProfile: "manual-cdp",
|
||||
ssrfPolicy: {},
|
||||
},
|
||||
});
|
||||
const ctx = createBrowserRouteContext({ getState: () => state });
|
||||
const profile = ctx.forProfile("manual-cdp");
|
||||
const { profile, state } = createAttachOnlyLoopbackProfile("ws://127.0.0.1:9222");
|
||||
|
||||
isChromeReachable.mockResolvedValueOnce(true);
|
||||
isChromeCdpReady.mockResolvedValueOnce(true);
|
||||
|
||||
@@ -8,6 +8,15 @@ import {
|
||||
const deps: RemoteProfileTestDeps = await loadRemoteProfileTestDeps();
|
||||
installRemoteProfileTestLifecycle(deps);
|
||||
|
||||
function page(targetId: string, url = `https://${targetId.toLowerCase()}.example`) {
|
||||
return {
|
||||
targetId,
|
||||
title: targetId === "T1" ? "Tab 1" : targetId,
|
||||
url,
|
||||
type: "page" as const,
|
||||
};
|
||||
}
|
||||
|
||||
describe("browser remote profile tab ops via Playwright", () => {
|
||||
it("uses Playwright tab operations when available", async () => {
|
||||
const listPagesViaPlaywright = vi.fn(async () => [
|
||||
@@ -91,10 +100,7 @@ describe("browser remote profile tab ops via Playwright", () => {
|
||||
});
|
||||
|
||||
it("rejects stale targetId for remote profiles even when only one tab remains", async () => {
|
||||
const responses = [
|
||||
[{ targetId: "T1", title: "Tab 1", url: "https://example.com", type: "page" }],
|
||||
[{ targetId: "T1", title: "Tab 1", url: "https://example.com", type: "page" }],
|
||||
];
|
||||
const responses = Array.from({ length: 2 }, () => [page("T1", "https://example.com")]);
|
||||
const listPagesViaPlaywright = vi.fn(deps.createSequentialPageLister(responses));
|
||||
|
||||
vi.spyOn(deps.pwAiModule, "getPwAiModule").mockResolvedValue({
|
||||
@@ -106,16 +112,7 @@ describe("browser remote profile tab ops via Playwright", () => {
|
||||
});
|
||||
|
||||
it("keeps rejecting stale targetId for remote profiles when multiple tabs exist", async () => {
|
||||
const responses = [
|
||||
[
|
||||
{ targetId: "A", title: "A", url: "https://a.example", type: "page" },
|
||||
{ targetId: "B", title: "B", url: "https://b.example", type: "page" },
|
||||
],
|
||||
[
|
||||
{ targetId: "A", title: "A", url: "https://a.example", type: "page" },
|
||||
{ targetId: "B", title: "B", url: "https://b.example", type: "page" },
|
||||
],
|
||||
];
|
||||
const responses = Array.from({ length: 2 }, () => [page("A"), page("B")]);
|
||||
const listPagesViaPlaywright = vi.fn(deps.createSequentialPageLister(responses));
|
||||
|
||||
vi.spyOn(deps.pwAiModule, "getPwAiModule").mockResolvedValue({
|
||||
|
||||
Reference in New Issue
Block a user