test: share browser route test helpers

This commit is contained in:
Peter Steinberger 2026-03-14 00:33:00 +00:00
parent 4523260dda
commit dcbc574a27
3 changed files with 77 additions and 115 deletions

View File

@ -1,12 +1,8 @@
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerBrowserAgentActRoutes } from "./agent.act.js"; import { registerBrowserAgentActRoutes } from "./agent.act.js";
import { registerBrowserAgentSnapshotRoutes } from "./agent.snapshot.js"; import { registerBrowserAgentSnapshotRoutes } from "./agent.snapshot.js";
import type { import { createBrowserRouteApp, createBrowserRouteResponse } from "./test-helpers.js";
BrowserRequest, import type { BrowserRequest } from "./types.js";
BrowserResponse,
BrowserRouteHandler,
BrowserRouteRegistrar,
} from "./types.js";
const routeState = vi.hoisted(() => ({ const routeState = vi.hoisted(() => ({
profileCtx: { profileCtx: {
@ -100,39 +96,34 @@ vi.mock("./agent.shared.js", () => ({
}), }),
})); }));
function createApp() { function getSnapshotGetHandler() {
const getHandlers = new Map<string, BrowserRouteHandler>(); const { app, getHandlers } = createBrowserRouteApp();
const postHandlers = new Map<string, BrowserRouteHandler>(); registerBrowserAgentSnapshotRoutes(app, {
const deleteHandlers = new Map<string, BrowserRouteHandler>(); state: () => ({ resolved: { ssrfPolicy: undefined } }),
const app: BrowserRouteRegistrar = { } as never);
get: (path, handler) => void getHandlers.set(path, handler), const handler = getHandlers.get("/snapshot");
post: (path, handler) => void postHandlers.set(path, handler), expect(handler).toBeTypeOf("function");
delete: (path, handler) => void deleteHandlers.set(path, handler), return handler;
};
return { app, getHandlers, postHandlers, deleteHandlers };
} }
function createResponse() { function getSnapshotPostHandler() {
let statusCode = 200; const { app, postHandlers } = createBrowserRouteApp();
let jsonBody: unknown; registerBrowserAgentSnapshotRoutes(app, {
const res: BrowserResponse = { state: () => ({ resolved: { ssrfPolicy: undefined } }),
status(code) { } as never);
statusCode = code; const handler = postHandlers.get("/screenshot");
return res; expect(handler).toBeTypeOf("function");
}, return handler;
json(body) { }
jsonBody = body;
}, function getActPostHandler() {
}; const { app, postHandlers } = createBrowserRouteApp();
return { registerBrowserAgentActRoutes(app, {
res, state: () => ({ resolved: { evaluateEnabled: true } }),
get statusCode() { } as never);
return statusCode; const handler = postHandlers.get("/act");
}, expect(handler).toBeTypeOf("function");
get body() { return handler;
return jsonBody;
},
};
} }
describe("existing-session browser routes", () => { describe("existing-session browser routes", () => {
@ -148,14 +139,8 @@ describe("existing-session browser routes", () => {
}); });
it("allows labeled AI snapshots for existing-session profiles", async () => { it("allows labeled AI snapshots for existing-session profiles", async () => {
const { app, getHandlers } = createApp(); const handler = getSnapshotGetHandler();
registerBrowserAgentSnapshotRoutes(app, { const response = createBrowserRouteResponse();
state: () => ({ resolved: { ssrfPolicy: undefined } }),
} as never);
const handler = getHandlers.get("/snapshot");
expect(handler).toBeTypeOf("function");
const response = createResponse();
await handler?.({ params: {}, query: { format: "ai", labels: "1" } }, response.res); await handler?.({ params: {}, query: { format: "ai", labels: "1" } }, response.res);
expect(response.statusCode).toBe(200); expect(response.statusCode).toBe(200);
@ -174,14 +159,8 @@ describe("existing-session browser routes", () => {
}); });
it("allows ref screenshots for existing-session profiles", async () => { it("allows ref screenshots for existing-session profiles", async () => {
const { app, postHandlers } = createApp(); const handler = getSnapshotPostHandler();
registerBrowserAgentSnapshotRoutes(app, { const response = createBrowserRouteResponse();
state: () => ({ resolved: { ssrfPolicy: undefined } }),
} as never);
const handler = postHandlers.get("/screenshot");
expect(handler).toBeTypeOf("function");
const response = createResponse();
await handler?.( await handler?.(
{ {
params: {}, params: {},
@ -207,14 +186,8 @@ describe("existing-session browser routes", () => {
}); });
it("rejects selector-based element screenshots for existing-session profiles", async () => { it("rejects selector-based element screenshots for existing-session profiles", async () => {
const { app, postHandlers } = createApp(); const handler = getSnapshotPostHandler();
registerBrowserAgentSnapshotRoutes(app, { const response = createBrowserRouteResponse();
state: () => ({ resolved: { ssrfPolicy: undefined } }),
} as never);
const handler = postHandlers.get("/screenshot");
expect(handler).toBeTypeOf("function");
const response = createResponse();
await handler?.( await handler?.(
{ {
params: {}, params: {},
@ -232,14 +205,8 @@ describe("existing-session browser routes", () => {
}); });
it("fails closed for existing-session networkidle waits", async () => { it("fails closed for existing-session networkidle waits", async () => {
const { app, postHandlers } = createApp(); const handler = getActPostHandler();
registerBrowserAgentActRoutes(app, { const response = createBrowserRouteResponse();
state: () => ({ resolved: { evaluateEnabled: true } }),
} as never);
const handler = postHandlers.get("/act");
expect(handler).toBeTypeOf("function");
const response = createResponse();
await handler?.( await handler?.(
{ {
params: {}, params: {},
@ -263,14 +230,8 @@ describe("existing-session browser routes", () => {
(fn === "() => window.location.href" ? "https://example.com/" : true) as never, (fn === "() => window.location.href" ? "https://example.com/" : true) as never,
); );
const { app, postHandlers } = createApp(); const handler = getActPostHandler();
registerBrowserAgentActRoutes(app, { const response = createBrowserRouteResponse();
state: () => ({ resolved: { evaluateEnabled: true } }),
} as never);
const handler = postHandlers.get("/act");
expect(handler).toBeTypeOf("function");
const response = createResponse();
await handler?.( await handler?.(
{ {
params: {}, params: {},

View File

@ -1,46 +1,11 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { BrowserProfileUnavailableError } from "../errors.js"; import { BrowserProfileUnavailableError } from "../errors.js";
import { registerBrowserBasicRoutes } from "./basic.js"; import { registerBrowserBasicRoutes } from "./basic.js";
import type { BrowserResponse, BrowserRouteHandler, BrowserRouteRegistrar } from "./types.js"; import { createBrowserRouteApp, createBrowserRouteResponse } from "./test-helpers.js";
function createApp() {
const getHandlers = new Map<string, BrowserRouteHandler>();
const postHandlers = new Map<string, BrowserRouteHandler>();
const deleteHandlers = new Map<string, BrowserRouteHandler>();
const app: BrowserRouteRegistrar = {
get: (path, handler) => void getHandlers.set(path, handler),
post: (path, handler) => void postHandlers.set(path, handler),
delete: (path, handler) => void deleteHandlers.set(path, handler),
};
return { app, getHandlers };
}
function createResponse() {
let statusCode = 200;
let jsonBody: unknown;
const res: BrowserResponse = {
status(code) {
statusCode = code;
return res;
},
json(body) {
jsonBody = body;
},
};
return {
res,
get statusCode() {
return statusCode;
},
get body() {
return jsonBody;
},
};
}
describe("basic browser routes", () => { describe("basic browser routes", () => {
it("maps existing-session status failures to JSON browser errors", async () => { it("maps existing-session status failures to JSON browser errors", async () => {
const { app, getHandlers } = createApp(); const { app, getHandlers } = createBrowserRouteApp();
registerBrowserBasicRoutes(app, { registerBrowserBasicRoutes(app, {
state: () => ({ state: () => ({
resolved: { resolved: {
@ -71,7 +36,7 @@ describe("basic browser routes", () => {
const handler = getHandlers.get("/"); const handler = getHandlers.get("/");
expect(handler).toBeTypeOf("function"); expect(handler).toBeTypeOf("function");
const response = createResponse(); const response = createBrowserRouteResponse();
await handler?.({ params: {}, query: { profile: "chrome-live" } }, response.res); await handler?.({ params: {}, query: { profile: "chrome-live" } }, response.res);
expect(response.statusCode).toBe(409); expect(response.statusCode).toBe(409);

View File

@ -0,0 +1,36 @@
import type { BrowserResponse, BrowserRouteHandler, BrowserRouteRegistrar } from "./types.js";
export function createBrowserRouteApp() {
const getHandlers = new Map<string, BrowserRouteHandler>();
const postHandlers = new Map<string, BrowserRouteHandler>();
const deleteHandlers = new Map<string, BrowserRouteHandler>();
const app: BrowserRouteRegistrar = {
get: (path, handler) => void getHandlers.set(path, handler),
post: (path, handler) => void postHandlers.set(path, handler),
delete: (path, handler) => void deleteHandlers.set(path, handler),
};
return { app, getHandlers, postHandlers, deleteHandlers };
}
export function createBrowserRouteResponse() {
let statusCode = 200;
let jsonBody: unknown;
const res: BrowserResponse = {
status(code) {
statusCode = code;
return res;
},
json(body) {
jsonBody = body;
},
};
return {
res,
get statusCode() {
return statusCode;
},
get body() {
return jsonBody;
},
};
}