mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 17:14:57 +00:00
refactor(browser): centralize navigation guard enforcement
This commit is contained in:
95
src/browser/pw-session.create-page.navigation-guard.test.ts
Normal file
95
src/browser/pw-session.create-page.navigation-guard.test.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user