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

View File

@ -1,46 +1,11 @@
import { describe, expect, it } from "vitest";
import { BrowserProfileUnavailableError } from "../errors.js";
import { registerBrowserBasicRoutes } from "./basic.js";
import type { BrowserResponse, BrowserRouteHandler, BrowserRouteRegistrar } from "./types.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;
},
};
}
import { createBrowserRouteApp, createBrowserRouteResponse } from "./test-helpers.js";
describe("basic browser routes", () => {
it("maps existing-session status failures to JSON browser errors", async () => {
const { app, getHandlers } = createApp();
const { app, getHandlers } = createBrowserRouteApp();
registerBrowserBasicRoutes(app, {
state: () => ({
resolved: {
@ -71,7 +36,7 @@ describe("basic browser routes", () => {
const handler = getHandlers.get("/");
expect(handler).toBeTypeOf("function");
const response = createResponse();
const response = createBrowserRouteResponse();
await handler?.({ params: {}, query: { profile: "chrome-live" } }, response.res);
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;
},
};
}