rea/tests/boundary/cli/browserRedirectShapeCompleteness.test.ts
Kaoru0822 6875d4a64c
fix(cli): accept JSON files for web capture and screenshot comparisons (#1397)
compare-web-captures and compare-web-screenshots parsed their arguments as
inline JSON only, unlike every other JSON-input command. Screenshot
artifacts and scenario captures embed base64 PNG bytes, so a typical
viewport screenshot exceeds the command-line length limit (128 KiB per
argument on Linux, 1 MiB total on macOS) and could not be compared from
the CLI at all, while MCP accepts it. A file path was reported as
malformed JSON, and screenshot schema failures returned no issues.

Each argument now accepts inline JSON or a JSON file path through
parseCliJsonInput; file failures keep its path diagnostics, malformed
inline JSON keeps the field issue, and screenshot validation reports
projected schema issues. The tests share one CLI JSON process fixture.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:42 -07:00

86 lines
2.3 KiB
TypeScript

import { afterEach, expect, it } from "vitest";
import { runCliJson as runCli } from "../../fixtures/cliJsonProcess.js";
import {
startFakeCdpBrowser,
type FakeCdpBrowser,
} from "../../fixtures/fakeCdpBrowser.js";
const browsers: FakeCdpBrowser[] = [];
afterEach(async () => {
await Promise.all(browsers.splice(0).map(async (browser) => browser.close()));
});
it("reports missing JSON shapes only when body shapes are selected", async () => {
const browser = await startFakeCdpBrowser({
malformedRedirectResponse: true,
redirectResponseEnvelope: null,
});
browsers.push(browser);
const commonArgs = [
"inspect-web-page",
browser.endpoint,
"allowed-page",
"--allowed-origins",
browser.allowedOrigin,
"--observation-ms",
"0",
];
const selected = normalizedResult(
await runCli([...commonArgs, "--include-json-body-shapes", "--json"]),
);
expect(selected).toMatchObject({
network: {
requests: [
{
body_shapes: {
status: "partial",
request: expect.any(Object),
response: null,
},
},
],
},
completeness: {
unavailable_sections: expect.arrayContaining([
"network_requests",
"json_body_shapes",
]),
excluded: expect.arrayContaining([
{
section: "json_body_shapes",
reason: "invalid_protocol_value",
count: expect.any(Number),
},
]),
},
});
const defaulted = normalizedResult(await runCli([...commonArgs, "--json"]));
expect(defaulted).toMatchObject({
network: {
requests: [
{
body_shapes: {
status: "not_approved",
request: null,
response: null,
},
},
],
},
});
expect(defaulted.completeness).toMatchObject({
unavailable_sections: expect.not.arrayContaining(["json_body_shapes"]),
});
});
const normalizedResult = (value: unknown): Record<string, unknown> => {
if (!isRecord(value) || !isRecord(value.normalized_result))
throw new TypeError("Missing CLI normalized result");
return value.normalized_result;
};
const isRecord = (value: unknown): value is Record<string, unknown> =>
typeof value === "object" && value !== null && !Array.isArray(value);