fix: stop browser server tests from launching real chrome

This commit is contained in:
Peter Steinberger 2026-03-23 03:14:57 -07:00
parent 203eebec2f
commit 3ff2f85bad
No known key found for this signature in database
4 changed files with 46 additions and 7 deletions

View File

@ -1,4 +1,8 @@
import { BrowserProfileUnavailableError, BrowserTabNotFoundError } from "../errors.js";
import {
assertBrowserNavigationAllowed,
withBrowserNavigationPolicy,
} from "../navigation-guard.js";
import type { BrowserRouteContext, ProfileContext } from "../server-context.js";
import type { BrowserRequest, BrowserResponse, BrowserRouteRegistrar } from "./types.js";
import { getProfileContext, jsonError, toNumber, toStringOrEmpty } from "./utils.js";
@ -128,6 +132,10 @@ export function registerBrowserTabRoutes(app: BrowserRouteRegistrar, ctx: Browse
ctx,
mapTabError: true,
run: async (profileCtx) => {
await assertBrowserNavigationAllowed({
url,
...withBrowserNavigationPolicy(ctx.state().resolved.ssrfPolicy),
});
await profileCtx.ensureBrowserAvailable();
const tab = await profileCtx.openTab(url);
res.json(tab);

View File

@ -56,8 +56,8 @@ vi.mock("./pw-ai-state.js", () => ({
isPwAiLoaded: vi.fn(() => false),
}));
const { startBrowserControlServerFromConfig, stopBrowserControlServer } =
await import("./server.js");
let startBrowserControlServerFromConfig: typeof import("./server.js").startBrowserControlServerFromConfig;
let stopBrowserControlServer: typeof import("./server.js").stopBrowserControlServer;
describe("browser control auth bootstrap failures", () => {
beforeEach(async () => {
@ -65,10 +65,14 @@ describe("browser control auth bootstrap failures", () => {
mocks.ensureBrowserControlAuth.mockClear();
mocks.resolveBrowserControlAuth.mockClear();
mocks.ensureExtensionRelayForProfiles.mockClear();
vi.resetModules();
({ startBrowserControlServerFromConfig, stopBrowserControlServer } =
await import("./server.js"));
});
afterEach(async () => {
await stopBrowserControlServer();
vi.resetModules();
});
it("fails closed when auth bootstrap throws and no auth is configured", async () => {

View File

@ -184,6 +184,18 @@ export function getChromeMcpMocks(): Record<string, MockFn> {
const chromeUserDataDir = vi.hoisted(() => ({ dir: "/tmp/openclaw" }));
installChromeUserDataDirHooks(chromeUserDataDir);
type BrowserServerModule = typeof import("./server.js");
let browserServerModule: BrowserServerModule | null = null;
async function loadBrowserServerModule(): Promise<BrowserServerModule> {
if (browserServerModule) {
return browserServerModule;
}
vi.resetModules();
browserServerModule = await import("./server.js");
return browserServerModule;
}
function makeProc(pid = 123) {
const handlers = new Map<string, Array<(...args: unknown[]) => void>>();
return {
@ -303,9 +315,19 @@ vi.mock("./screenshot.js", () => ({
})),
}));
const server = await import("./server.js");
export const startBrowserControlServerFromConfig = server.startBrowserControlServerFromConfig;
export const stopBrowserControlServer = server.stopBrowserControlServer;
export async function startBrowserControlServerFromConfig() {
const server = await loadBrowserServerModule();
return await server.startBrowserControlServerFromConfig();
}
export async function stopBrowserControlServer(): Promise<void> {
const server = browserServerModule;
browserServerModule = null;
if (!server) {
return;
}
await server.stopBrowserControlServer();
}
export function makeResponse(
body: unknown,
@ -387,6 +409,7 @@ export function installBrowserControlServerHooks() {
});
await resetBrowserControlServerTestContext();
await loadBrowserServerModule();
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;

View File

@ -65,8 +65,8 @@ vi.mock("./server-context.js", async (importOriginal) => {
};
});
const { startBrowserControlServerFromConfig, stopBrowserControlServer } =
await import("./server.js");
let startBrowserControlServerFromConfig: typeof import("./server.js").startBrowserControlServerFromConfig;
let stopBrowserControlServer: typeof import("./server.js").stopBrowserControlServer;
describe("browser control evaluate gating", () => {
beforeEach(async () => {
@ -83,6 +83,9 @@ describe("browser control evaluate gating", () => {
pwMocks.evaluateViaPlaywright.mockClear();
routeCtxMocks.profileCtx.ensureTabAvailable.mockClear();
routeCtxMocks.profileCtx.stopRunningBrowser.mockClear();
vi.resetModules();
({ startBrowserControlServerFromConfig, stopBrowserControlServer } =
await import("./server.js"));
});
afterEach(async () => {
@ -104,6 +107,7 @@ describe("browser control evaluate gating", () => {
}
await stopBrowserControlServer();
vi.resetModules();
});
it("blocks act:evaluate but still allows cookies/storage reads", async () => {