mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
test(browser): reject unmodeled CDP commands in protocol fixtures
This commit is contained in:
1 parent
ffd9611308
commit
017297c40c
5 files changed
+71
-10
No files matched your search
@@ -30,6 +30,10 @@ one golden malformed-input case and a real filesystem lifecycle that proves
|
||||
configure, update, readback, and removal; an add-only journey does not cover the
|
||||
whole lifecycle.
|
||||
|
||||
Protocol fixtures must model the commands they support and their producer reply
|
||||
shapes. Reject unmodeled commands instead of returning a generic success; an
|
||||
empty result is appropriate only for a supported command with no result fields.
|
||||
|
||||
Keep transport-only in-memory MCP sessions in the MCP boundary lane and direct
|
||||
filesystem workflows in the filesystem boundary lane. Real process-tree capture
|
||||
belongs in the serial process boundary lane, including captures invoked through
|
||||
|
||||
@@ -62,6 +62,28 @@ describe("CDP connection", () => {
|
||||
await connection.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("surfaces an unmodeled fake command as a CDP method rejection", async () => {
|
||||
const browser = await startFakeCdpBrowser();
|
||||
browsers.push(browser);
|
||||
const connection = await CdpConnection.connect(
|
||||
browser.browserWebSocketUrl,
|
||||
"observe_web_session",
|
||||
);
|
||||
try {
|
||||
await expect(
|
||||
connection.send("Fixture.unmodeledMethod"),
|
||||
).rejects.toMatchObject({
|
||||
_tag: "BrowserObservationError",
|
||||
command: "Fixture.unmodeledMethod",
|
||||
code: -32_601,
|
||||
reportedMessage: "Method not found: Fixture.unmodeledMethod",
|
||||
});
|
||||
} finally {
|
||||
await connection.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves the selected payload limit reason for pending and subsequent commands", async () => {
|
||||
const browser = await startFakeCdpBrowser({
|
||||
commandResult: () => ({ oversized: "x".repeat(2_048) }),
|
||||
|
||||
Vendored
+19
-6
@@ -178,15 +178,28 @@ const replyToCommand = (
|
||||
options: FakeOptions,
|
||||
frameTreeReads: number,
|
||||
): void => {
|
||||
const result =
|
||||
options.commandResult?.(
|
||||
command,
|
||||
`http://127.0.0.1:${String(port)}`,
|
||||
frameTreeReads,
|
||||
) ?? resultFor(command, port, options, frameTreeReads);
|
||||
if (result === undefined) {
|
||||
socket.send(
|
||||
JSON.stringify({
|
||||
id: command.id,
|
||||
error: {
|
||||
code: -32_601,
|
||||
message: `Method not found: ${command.method}`,
|
||||
},
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
socket.send(
|
||||
JSON.stringify({
|
||||
id: command.id,
|
||||
result:
|
||||
options.commandResult?.(
|
||||
command,
|
||||
`http://127.0.0.1:${String(port)}`,
|
||||
frameTreeReads,
|
||||
) ?? resultFor(command, port, options, frameTreeReads),
|
||||
result,
|
||||
}),
|
||||
);
|
||||
if (options.malformedEventOnMethod === command.method)
|
||||
|
||||
+19
-2
@@ -6,7 +6,7 @@ export const resultFor = (
|
||||
port: number,
|
||||
options: FakeOptions,
|
||||
frameTreeReads: number,
|
||||
): Readonly<Record<string, unknown>> => {
|
||||
): Readonly<Record<string, unknown>> | undefined => {
|
||||
switch (command.method) {
|
||||
case "Target.attachToTarget":
|
||||
return attachToTargetResult(options);
|
||||
@@ -44,8 +44,25 @@ export const resultFor = (
|
||||
return cacheEntriesResult(port);
|
||||
case "CacheStorage.requestCachedResponse":
|
||||
return cachedResponseResult(options);
|
||||
default:
|
||||
case "Page.enable":
|
||||
case "Page.disable":
|
||||
case "Page.setLifecycleEventsEnabled":
|
||||
case "Network.enable":
|
||||
case "Network.disable":
|
||||
case "Debugger.disable":
|
||||
case "Runtime.enable":
|
||||
case "Runtime.disable":
|
||||
case "Runtime.releaseObjectGroup":
|
||||
case "DOM.enable":
|
||||
case "DOM.disable":
|
||||
return {};
|
||||
case "Debugger.enable":
|
||||
return { debuggerId: "fake-debugger" };
|
||||
case "Target.detachFromTarget":
|
||||
case "WebMCP.enable":
|
||||
return {};
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Vendored
+7
-2
@@ -21,6 +21,13 @@ const runtimeResult = (
|
||||
origin: string,
|
||||
): Readonly<Record<string, unknown>> | undefined => {
|
||||
switch (command.method) {
|
||||
case "Profiler.enable":
|
||||
case "Profiler.disable":
|
||||
return {};
|
||||
case "Profiler.startPreciseCoverage":
|
||||
return { timestamp: 12 };
|
||||
case "Profiler.stopPreciseCoverage":
|
||||
return {};
|
||||
case "Page.getFrameTree":
|
||||
return {
|
||||
frameTree: {
|
||||
@@ -31,8 +38,6 @@ const runtimeResult = (
|
||||
},
|
||||
},
|
||||
};
|
||||
case "Profiler.startPreciseCoverage":
|
||||
return { timestamp: 12 };
|
||||
case "Profiler.takePreciseCoverage":
|
||||
return {
|
||||
timestamp: 13,
|
||||
|
||||
Reference in new issue
Block a user