Files
rea/tests/acceptance/webSessionRedirectContext.test.ts
gensokyo-dev 4b0ff68e2e fix(browser): retain prior-hop response facts in session timelines (#7807)
* fix(browser): retain prior-hop response facts in session timelines

* fix(browser): share response URL classification

* fix(browser): preserve malformed response status failures

* fix(browser): account for filtered redirect response coverage

* test(browser): supply prior response URLs in redirect fixtures

* fix(browser): retain malformed orphan response status coverage
2026-10-29 02:04:15 +08:00

101 lines
3.5 KiB
TypeScript

import { expect, onTestFinished } from "vitest";
import { z } from "zod";
import { toolContract } from "../../src/contracts/toolContracts.js";
import { webObservationSessionSchema } from "../../src/domain/browserSession.js";
import { startFakeCdpBrowser } from "../fixtures/fakeCdpBrowser.js";
import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { cliTest } from "../support/cli/cliFixture.js";
cliTest.for(["CLI", "stdio MCP"] as const)(
"retains admitted redirect response facts and historical omission through %s",
async (surface, { cli }) => {
const browser = await startFakeCdpBrowser({
eventsBeforeReply: ["Page.setLifecycleEventsEnabled"],
commandResult: (command) =>
command.method === "Performance.getMetrics"
? { metrics: [{ name: "Timestamp", value: 20 }] }
: undefined,
commandEvents: (command, origin) =>
command.method === "Page.setLifecycleEventsEnabled"
? [
{
method: "Network.requestWillBeSent",
sessionId: command.sessionId,
params: {
requestId: "redirect-chain",
frameId: "frame-main",
type: "Document",
timestamp: 21,
request: { url: `${origin}/after`, method: "GET" },
redirectResponse: {
url: `${origin}/before?token=visible`,
status: 302,
headers: { Authorization: "discard-redirect-header" },
body: "discard-redirect-body",
},
},
},
]
: undefined,
});
onTestFinished(() => browser.close());
let evidence: unknown;
if (surface === "CLI") {
const reply = await cli.run({
arguments: [
"observe-web-session",
browser.endpoint,
"allowed-page",
"--allowed-origins",
browser.allowedOrigin,
"--observation-ms",
"5",
"--json",
],
});
expect(reply.exitCode, reply.stderr).toBe(0);
evidence = reply.json;
} else {
const { call } = await connectLocalToolsMcp();
const reply = await call("observe_web_session", {
cdp_endpoint: browser.endpoint,
allowed_origins: [browser.allowedOrigin],
target_id: "allowed-page",
observation_ms: 5,
});
expect(reply.isError, JSON.stringify(reply.content)).not.toBe(true);
evidence = reply.structuredContent;
}
const source = toolContract("observe_web_session").outputSchema.parse(
evidence,
);
const result = z
.object({ normalized_result: webObservationSessionSchema })
.parse(source).normalized_result;
expect(result.timeline).toContainEqual(
expect.objectContaining({
type: "redirect",
request_id: "redirect-chain",
timestamp: 21,
url: `${browser.allowedOrigin}/after`,
redirect_response: {
url: `${browser.allowedOrigin}/before?token=visible`,
status: 302,
scope: "approved",
},
}),
);
expect(JSON.stringify(source)).not.toContain("discard-redirect-");
const historical = {
...result,
timeline: result.timeline.map(({ redirect_response, ...row }) => {
void redirect_response;
return row;
}),
};
expect(webObservationSessionSchema.parse(historical)).toStrictEqual(
historical,
);
},
);