fix(ci): synchronize browser fixture events before inspection (#1534)

This commit is contained in:
Ysopwnable authored and GitHub committed 2026-10-10 18:44:49 +08:00
1 parent 3059d8a40f
commit 9964af6b79
3 files changed
+165 -158

No files matched your search

+147 -148
View File
@@ -32,157 +32,156 @@ afterEach(async () => {
await Promise.all(browsers.splice(0).map(async (browser) => browser.close()));
});
describe("browser CLI parity", () => {
it(
"returns the same Evidence discovery and inspection contracts",
async () => {
const browser = await startFakeCdpBrowser({
sessionTimeline: "same_origin",
webMcpTools: true,
sensitiveShapes: true,
commandEvents: partialScriptEvents,
});
browsers.push(browser);
const listed = await runCli(
["list-browser-targets", browser.endpoint, "--json"],
process.env,
);
expect(listed).toMatchObject({
operation: "list_browser_targets",
provider: { id: "rea-cdp-browser" },
normalized_result: {
targets: expect.arrayContaining([
expect.objectContaining({ target_id: "allowed-page" }),
expect.objectContaining({ target_id: "disallowed-page" }),
]),
it(
"browser CLI parity returns the same Evidence discovery and inspection contracts",
async () => {
const browser = await startFakeCdpBrowser({
sessionTimeline: "same_origin",
webMcpTools: true,
sensitiveShapes: true,
commandEvents: partialScriptEvents,
eventsBeforeReply: ["Network.enable"],
});
browsers.push(browser);
const listed = await runCli(
["list-browser-targets", browser.endpoint, "--json"],
process.env,
);
expect(listed).toMatchObject({
operation: "list_browser_targets",
provider: { id: "rea-cdp-browser" },
normalized_result: {
targets: expect.arrayContaining([
expect.objectContaining({ target_id: "allowed-page" }),
expect.objectContaining({ target_id: "disallowed-page" }),
]),
},
});
const inspected = await runCli(
[
"inspect-web-page",
browser.endpoint,
"allowed-page",
"--observation-ms",
"0",
"--include-console-text",
"--include-json-body-shapes",
"--include-websocket-shapes",
"--json",
],
process.env,
);
expect(inspected).toMatchObject({
operation: "inspect_web_page",
provider: { id: "rea-cdp-browser" },
normalized_result: {
target: { target_id: "allowed-page" },
scripts: {
items: [{ cdp_hash: null, length: null, is_module: null }],
},
});
const inspected = await runCli(
[
"inspect-web-page",
browser.endpoint,
"allowed-page",
"--observation-ms",
"0",
"--include-console-text",
"--include-json-body-shapes",
"--include-websocket-shapes",
"--json",
],
process.env,
);
expect(inspected).toMatchObject({
operation: "inspect_web_page",
provider: { id: "rea-cdp-browser" },
normalized_result: {
target: { target_id: "allowed-page" },
scripts: {
items: [{ cdp_hash: null, length: null, is_module: null }],
},
network: {
prior_activity_available: false,
requests: [
expect.objectContaining({
body_shapes: expect.objectContaining({ status: "included" }),
}),
],
},
},
});
const inspection = normalizedResult(inspected);
const compared = await runCli(
[
"compare-web-captures",
JSON.stringify({ inspection }),
JSON.stringify({ inspection }),
"--json",
],
process.env,
);
expect(compared).toMatchObject({
operation: "compare_web_captures",
normalized_result: {
overall_status: "unknown",
dimensions: {
network: { status: "unknown", total_changes: 0 },
},
},
});
const scenarioCapture = completeScenarioCapture();
const scenarioCompared = await runCli(
[
"compare-web-captures",
JSON.stringify(scenarioCapture),
JSON.stringify(scenarioCapture),
"--normalization-json",
'{"rules":[]}',
"--json",
],
process.env,
);
expect(scenarioCompared).toMatchObject({
operation: "compare_web_captures",
normalized_result: {
comparison_kind: "browser_scenario",
overall_status: "unchanged",
alignment: { status: "aligned", aligned_steps: 2 },
},
});
const intentionalPolicy = await runCli(
[
"compare-web-captures",
JSON.stringify(scenarioCapture),
JSON.stringify(scenarioCapture),
"--normalization-json",
JSON.stringify({
rules: [
{
rule_id: "domain",
artifacts: ["url"],
match: "app.example.test",
replacement: "normalized.test",
},
],
}),
"--json",
],
process.env,
);
expect(intentionalPolicy).toMatchObject({
normalized_result: {
normalization: { rules: [{ rule_id: "domain" }] },
},
});
const malformedPolicy = await runCli(
[
"compare-web-captures",
JSON.stringify(scenarioCapture),
JSON.stringify(scenarioCapture),
"--normalization-json",
"{invalid-policy",
"--json",
],
process.env,
);
expect(malformedPolicy).toMatchObject({
error: "Browser observation failed",
code: "invalid_request",
details: {
operation: "compare_web_captures",
issues: [
{
path: ["normalization"],
reason: "invalid_format",
expected: "JSON",
},
network: {
prior_activity_available: false,
requests: [
expect.objectContaining({
body_shapes: expect.objectContaining({ status: "included" }),
}),
],
},
});
},
INTEGRATION_TEST_TIMEOUT_MS,
);
});
},
});
const inspection = normalizedResult(inspected);
const compared = await runCli(
[
"compare-web-captures",
JSON.stringify({ inspection }),
JSON.stringify({ inspection }),
"--json",
],
process.env,
);
expect(compared).toMatchObject({
operation: "compare_web_captures",
normalized_result: {
overall_status: "unknown",
dimensions: {
network: { status: "unknown", total_changes: 0 },
},
},
});
const scenarioCapture = completeScenarioCapture();
const scenarioCompared = await runCli(
[
"compare-web-captures",
JSON.stringify(scenarioCapture),
JSON.stringify(scenarioCapture),
"--normalization-json",
'{"rules":[]}',
"--json",
],
process.env,
);
expect(scenarioCompared).toMatchObject({
operation: "compare_web_captures",
normalized_result: {
comparison_kind: "browser_scenario",
overall_status: "unchanged",
alignment: { status: "aligned", aligned_steps: 2 },
},
});
const intentionalPolicy = await runCli(
[
"compare-web-captures",
JSON.stringify(scenarioCapture),
JSON.stringify(scenarioCapture),
"--normalization-json",
JSON.stringify({
rules: [
{
rule_id: "domain",
artifacts: ["url"],
match: "app.example.test",
replacement: "normalized.test",
},
],
}),
"--json",
],
process.env,
);
expect(intentionalPolicy).toMatchObject({
normalized_result: {
normalization: { rules: [{ rule_id: "domain" }] },
},
});
const malformedPolicy = await runCli(
[
"compare-web-captures",
JSON.stringify(scenarioCapture),
JSON.stringify(scenarioCapture),
"--normalization-json",
"{invalid-policy",
"--json",
],
process.env,
);
expect(malformedPolicy).toMatchObject({
error: "Browser observation failed",
code: "invalid_request",
details: {
operation: "compare_web_captures",
issues: [
{
path: ["normalization"],
reason: "invalid_format",
expected: "JSON",
},
],
},
});
},
INTEGRATION_TEST_TIMEOUT_MS,
);
describe("browser CLI capture parity", () => {
it(
+16 -10
View File
@@ -196,22 +196,28 @@ const replyToCommand = (
);
return;
}
socket.send(
JSON.stringify({
id: command.id,
result,
}),
);
if (options.malformedEventOnMethod === command.method)
socket.send("{not-json");
if (options.malformedEventShapeOnMethod === command.method)
socket.send(JSON.stringify({ method: 42 }));
const reply = () => {
socket.send(
JSON.stringify({
id: command.id,
result,
}),
);
if (options.malformedEventOnMethod === command.method)
socket.send("{not-json");
if (options.malformedEventShapeOnMethod === command.method)
socket.send(JSON.stringify({ method: 42 }));
};
const eventsFirst =
options.eventsBeforeReply?.includes(command.method) === true;
if (!eventsFirst) reply();
const customEvents = options.commandEvents?.(
command,
`http://127.0.0.1:${String(port)}`,
);
if (customEvents === undefined) emitEvents(socket, command, port, options);
else for (const event of customEvents) socket.send(JSON.stringify(event));
if (eventsFirst) reply();
if (options.closeAfterMethod === command.method)
setImmediate(() => socket.close());
};
+2
View File
@@ -28,6 +28,8 @@ export interface FakeCdpBrowser {
}
export interface FakeOptions {
/** Send these commands' producer events before acknowledging completion, as a wire barrier. */
readonly eventsBeforeReply?: readonly string[];
/** Return a native-shaped command rejection through the actual wire parser. */
readonly commandError?: (
command: FakeCdpCommand,