Files
openclaw/src/browser/pw-session.create-page.navigation-guard.test.ts
2026-02-21 11:46:11 +01:00

96 lines
2.7 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import { InvalidBrowserNavigationUrlError } from "./navigation-guard.js";
import { closePlaywrightBrowserConnection, createPageViaPlaywright } from "./pw-session.js";
const connectOverCdpMock = vi.fn();
const getChromeWebSocketUrlMock = vi.fn();
vi.mock("playwright-core", () => ({
chromium: {
connectOverCDP: (...args: unknown[]) => connectOverCdpMock(...args),
},
}));
vi.mock("./chrome.js", () => ({
getChromeWebSocketUrl: (...args: unknown[]) => getChromeWebSocketUrlMock(...args),
}));
function installBrowserMocks() {
const pageOn = vi.fn();
const pageGoto = vi.fn(async () => {});
const pageTitle = vi.fn(async () => "");
const pageUrl = vi.fn(() => "about:blank");
const contextOn = vi.fn();
const browserOn = vi.fn();
const browserClose = vi.fn(async () => {});
const sessionSend = vi.fn(async (method: string) => {
if (method === "Target.getTargetInfo") {
return { targetInfo: { targetId: "TARGET_1" } };
}
return {};
});
const sessionDetach = vi.fn(async () => {});
const context = {
pages: () => [],
on: contextOn,
newPage: vi.fn(async () => page),
newCDPSession: vi.fn(async () => ({
send: sessionSend,
detach: sessionDetach,
})),
} as unknown as import("playwright-core").BrowserContext;
const page = {
on: pageOn,
context: () => context,
goto: pageGoto,
title: pageTitle,
url: pageUrl,
} as unknown as import("playwright-core").Page;
const browser = {
contexts: () => [context],
on: browserOn,
close: browserClose,
} as unknown as import("playwright-core").Browser;
connectOverCdpMock.mockResolvedValue(browser);
getChromeWebSocketUrlMock.mockResolvedValue(null);
return { pageGoto, browserClose };
}
afterEach(async () => {
connectOverCdpMock.mockReset();
getChromeWebSocketUrlMock.mockReset();
await closePlaywrightBrowserConnection().catch(() => {});
});
describe("pw-session createPageViaPlaywright navigation guard", () => {
it("blocks unsupported non-network URLs", async () => {
const { pageGoto } = installBrowserMocks();
await expect(
createPageViaPlaywright({
cdpUrl: "http://127.0.0.1:18792",
url: "file:///etc/passwd",
}),
).rejects.toBeInstanceOf(InvalidBrowserNavigationUrlError);
expect(pageGoto).not.toHaveBeenCalled();
});
it("allows about:blank without network navigation", async () => {
const { pageGoto } = installBrowserMocks();
const created = await createPageViaPlaywright({
cdpUrl: "http://127.0.0.1:18792",
url: "about:blank",
});
expect(created.targetId).toBe("TARGET_1");
expect(pageGoto).not.toHaveBeenCalled();
});
});