* fix(browser): name web-bundle budgets and recover web deadlines Name the existing heap, per-script, and total web-bundle phases, and reject a per-script deadline above the total. Promote capture, CDP command, source-map decode, and source-map fetch deadlines at today's defaults. Name DevTools timeoutMs, and state that discovery, cleanup grace, byte budgets, and Electron hook retention have no runtime override. Refs #5910 Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): apply selected web deadlines to the owning phase Keep HTTP and browser-socket discovery on the fixed discovery deadline so a short command_timeout_ms starts at the handshake. Apply scenario command_timeout_ms to launch startup and the primary connect session, and keep service-worker restoration on the fixed 5000 ms grace. Omit command_timeout_ms from recovery text when the operation does not accept it. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): retain scenario commands that finish after their deadline A timed-out scenario command stays owned so cleanup can close a late browser or context and restore a mutation that lands after the deadline. Child storage replies use that deadline, scenario recovery names command_timeout_ms in the capture JSON, and the session test connection implements beginCleanupGrace. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): keep child command timeouts as the public failure A nested command such as Page.enable that is delivered but never answered was stored as protocol_error, hiding the command name, selected deadline, and recovery. Store the typed timeout and assert that public error. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): keep runtime cleanup on the fixed grace Switch runtime restoration to the cleanup grace before the first send so a short command_timeout_ms cannot fail an otherwise successful observation. Stop advertising command_timeout_ms on list_browser_targets, which never bounds a post-discovery command. Co-authored-by: morluto <morluto@users.noreply.github.com> * test(browser): prove a short command deadline cannot fail runtime cleanup Drive restoration through the runtime fixture. A cleanup command that outlives command_timeout_ms still succeeds, and a stalled restoration names the fixed 5000 ms grace. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): name the effective source-map decode deadline codecBudgetLimitation reported a fixed 20-second deadline after a caller selected decode_timeout_ms. Result and Evidence limitations now name that effective millisecond deadline. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): separate handshake and target-attach deadlines A browser-level Target.attachToTarget no longer shares the WebSocket handshake budget. Blocked service-worker attachment keeps discovery on its fixed deadline and applies command_timeout_ms to the later handshake and attach. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): name the web-bundle resource each runtime exhausts Bun ignores the V8 old-space flag. A Windows Job reports the process commit limit, and other Bun hosts no longer suggest raising max_heap_mb. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): cite the browser-socket discovery message budget WebSocket discovery enforces the 64 MiB protocol budget. Timeout recovery no longer advertises the 8 MiB HTTP document budget. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): bound the blocked service-worker check before discovery The first registration check has its own fixed 10s deadline. Discovery, handshake, and Target.attachToTarget stay on their separate deadlines. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(browser): name the operand that stopped web-bundle admission Host heap pressure no longer claims the fixed result budget is exhausted. A Windows Bun allocation before the commit limit still names that limit. Co-authored-by: morluto <morluto@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com>
132 lines
5.6 KiB
TypeScript
132 lines
5.6 KiB
TypeScript
import type { JsonValue } from "../../src/domain/jsonValue.js";
|
|
import type { CdpEvent } from "../../src/browser/CdpConnection.js";
|
|
export interface FakeCdpCommand {
|
|
readonly id: number;
|
|
readonly method: string;
|
|
readonly params: Readonly<Record<string, unknown>>;
|
|
readonly sessionId?: string;
|
|
}
|
|
|
|
export interface FakeCdpBrowser {
|
|
readonly endpoint: string;
|
|
readonly browserWebSocketUrl: string;
|
|
readonly allowedOrigin: string;
|
|
readonly commands: readonly FakeCdpCommand[];
|
|
/** Actual WebSocket connections still held by the wire fixture. */
|
|
activeConnectionCount(): number;
|
|
/** WebSocket upgrades accepted over the fixture's lifetime. */
|
|
openedConnectionCount(): number;
|
|
/** Deliver actual malformed wire data without bypassing the production transport parser. */
|
|
emitRawMessage(message: string): void;
|
|
emitEvent(event: CdpEvent): void;
|
|
readonly httpRequests: readonly {
|
|
readonly url: string;
|
|
readonly authorization: string | undefined;
|
|
readonly cookie: string | undefined;
|
|
readonly referer: string | undefined;
|
|
}[];
|
|
close(): Promise<void>;
|
|
}
|
|
|
|
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,
|
|
) => { readonly code: number; readonly message: string } | undefined;
|
|
/** Producer reply seam preserves the real HTTP/WebSocket transport and command parser. */
|
|
readonly commandResult?: (
|
|
command: FakeCdpCommand,
|
|
origin: string,
|
|
frameReads: number,
|
|
) => Readonly<Record<string, unknown>> | undefined;
|
|
/** Return undefined to use the stock producer events; an empty array suppresses them. */
|
|
readonly commandEvents?: (
|
|
command: FakeCdpCommand,
|
|
origin: string,
|
|
) => readonly CdpEvent[] | undefined;
|
|
/** Delay each HTTP discovery document so a short command deadline can be observed separately. */
|
|
readonly discoveryDelayMs?: number;
|
|
/** Delay WebSocket upgrade acceptance so handshake and attach deadlines stay distinct. */
|
|
readonly handshakeDelayMs?: number;
|
|
readonly malformedDiscovery?: boolean;
|
|
readonly oversizedDiscovery?: boolean;
|
|
readonly invalidBrowserWebSocket?: boolean;
|
|
readonly pageScopedVersionWebSocket?: boolean;
|
|
readonly omitTargetWebSocket?: boolean;
|
|
readonly additionalPageWithWebSocket?: boolean;
|
|
readonly additionalPageWithoutWebSocket?: boolean;
|
|
readonly additionalPageCount?: number;
|
|
readonly additionalElectronPageCount?: number;
|
|
readonly invalidAttachedSession?: boolean;
|
|
readonly malformedMessageOnMethod?: string;
|
|
readonly malformedEventOnMethod?: string;
|
|
readonly malformedEventShapeOnMethod?: string;
|
|
readonly closeOnMethod?: string;
|
|
readonly hangOnMethod?: string;
|
|
readonly unsupportedMethods?: readonly string[];
|
|
readonly transitionalFrameReads?: number;
|
|
readonly attachedFrameUrl?: string;
|
|
readonly frameUrlAfterFirstRead?: string;
|
|
readonly navigateDuringObservationUrl?: string;
|
|
readonly navigateDuringCaptureUrl?: string;
|
|
readonly navigateDuringScreenshotUrl?: string;
|
|
readonly screenshotDocumentLoader?: string;
|
|
readonly extraCollections?: boolean;
|
|
readonly indexedDbDateKeys?: boolean;
|
|
readonly foreignSessionEvents?: boolean;
|
|
readonly redirectToDisallowedOrigin?: boolean;
|
|
readonly redirectFromDisallowedOrigin?: boolean;
|
|
readonly redirectWithinOrigin?: boolean;
|
|
readonly malformedRedirectResponse?: boolean;
|
|
readonly omitRedirectResponse?: boolean;
|
|
readonly redirectResponseUrl?: string;
|
|
readonly redirectResponseEnvelope?: unknown;
|
|
readonly responseAfterMalformedUrl?: string;
|
|
readonly unrelatedWorker?: boolean;
|
|
readonly binaryWebSocketEvent?: boolean;
|
|
/** Emit an allowed WebSocket creation without any frames in the capture window. */
|
|
readonly webSocketWithoutFrames?: boolean;
|
|
readonly invalidBinaryWebSocketEvent?: boolean;
|
|
readonly sourceMapBody?: string;
|
|
/** Accept a source-map request and leave the response open. */
|
|
readonly hangSourceMap?: boolean;
|
|
readonly sourceMapRedirect?: string;
|
|
readonly sessionTimeline?:
|
|
| "same_origin"
|
|
| "outside_policy"
|
|
| "target_detached"
|
|
| "target_crashed";
|
|
readonly sessionTimelineEventCount?: number;
|
|
readonly sessionRedirectResourceType?: "Document" | "Fetch" | "Script";
|
|
readonly closeAfterMethod?: string;
|
|
readonly sensitiveShapes?: boolean;
|
|
/** Deliver a console argument the protocol spells as `{ type: "object", subtype: "null" }`. */
|
|
readonly nullConsoleArgument?: boolean;
|
|
readonly cachedResponseBody?: string;
|
|
readonly invalidResponseBodyBase64?: boolean;
|
|
readonly webMcpTools?: boolean;
|
|
readonly webMcpConsequential?: JsonValue;
|
|
/** Replaces the primary tool's registration stack; returning `undefined` omits it. */
|
|
readonly webMcpStackTrace?: (origin: string) => JsonValue | undefined;
|
|
readonly webMcpSameUrlRegistrations?: "retain" | "remove-second";
|
|
readonly webMcpFrameCount?: number;
|
|
readonly webMcpSchemaPropertyCount?: number;
|
|
readonly webMcpInputSchema?: JsonValue;
|
|
readonly webMcpChildLeavesScope?: boolean;
|
|
readonly webMcpChildTransientBlank?: boolean;
|
|
readonly webMcpChildRecoversAfterTransient?: boolean;
|
|
readonly webMcpChildNavigatesAllowed?: boolean;
|
|
readonly electronFileUrl?: string;
|
|
/** Omit attached from the Electron page's HTTP discovery target. */
|
|
readonly omitElectronTargetAttachmentState?: boolean;
|
|
readonly duplicateElectronInventory?: boolean;
|
|
readonly electronInventoryCount?: number;
|
|
readonly urlShapedAllowedTitle?:
|
|
| boolean
|
|
| "host-path"
|
|
| "root-relative"
|
|
| "prefixed";
|
|
}
|