Files
reverse-engineering-anything/tests/fixtures/fakeCdpSend.ts
T
morluto 3e0dc29041 fix(browser): type CDP command replies and parse frame trees once (#10604)
* fix(browser): type CDP command replies and parse frame trees once

CdpConnection.send is typed by method name. A command registered in
src/browser/protocol/CdpCommands.ts has its parameters typed from the
protocol table Playwright ships and its reply parsed once by its own result
schema; a mismatch rejects that command with CdpMalformedReply
(protocol_error, command, JSON pointer) without poisoning the connection.
Playwright storage sessions admit replies through the same table.

Page.getFrameTree and Page.getResourceTree are the first registered
commands. Their one parser keeps per-frame facts tolerant (malformed child
entries remain explicit omissions) and replaces the per-site readers:
observeMainFrameUrl, mainFrameUrl, walkFrameTrees, frameTreeResources,
runtimeFrameTreeSchema and the scenario storage frame schema.

A reply without a frame tree used to be retried for two seconds and
reported as target_not_allowed; it is now one protocol_error.

A guard test counts literal CDP command names without a result schema per
source file; the baseline can only shrink.

* fix(browser): consume parsed CDP facts across boundaries
2026-11-14 15:21:00 -05:00

36 lines
1.3 KiB
TypeScript

import type { CdpConnection } from "../../src/browser/CdpConnection.js";
import { admitCdpReply } from "../../src/browser/protocol/CdpCommands.js";
type RawCdpReply = (
method: string,
params: Readonly<Record<string, unknown>>,
sessionId: string | undefined,
signal: AbortSignal | undefined,
) => unknown;
/**
* A `CdpConnection.send` fake that answers with raw wire results. Registered
* commands are admitted by their result schemas exactly as the real connection
* admits them, so a fake cannot hand consumers an unparsed reply.
*/
export const fakeCdpSend = (reply: RawCdpReply): CdpConnection["send"] =>
(async (
method: string,
params?: Readonly<Record<string, unknown>>,
sessionId?: string,
signal?: AbortSignal,
) =>
admitCdpReply(
method,
await reply(method, params ?? {}, sessionId, signal),
"inspect_web_page",
)) as CdpConnection["send"];
/** Parse a raw `Page.getFrameTree` wire result as the connection would. */
export const frameTreeReply = (raw: unknown) =>
admitCdpReply("Page.getFrameTree", raw, "inspect_web_page");
/** Parse a raw `Page.getResourceTree` wire result as the connection would. */
export const resourceTreeReply = (raw: unknown) =>
admitCdpReply("Page.getResourceTree", raw, "inspect_web_page");