aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-27 23:46:25 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commit753c2ad615fa9827e168be256e1a7c7384605855 (patch)
tree03d62eb1816f4ad0ad3b634b87c4dcdb6fdbd83c /test
parentd54d8e9e2dfbd31358b1f48e17338d74f5d270c0 (diff)
refactor(cdp): validate event params against a typed table
Malformed or unknown events are now dropped rather than hand-narrowed; consumers get typed params. Unknown methods are ignored, since the transport delivers every event Chrome emits. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'test')
-rw-r--r--test/cdp/events-test.ts94
1 files changed, 94 insertions, 0 deletions
diff --git a/test/cdp/events-test.ts b/test/cdp/events-test.ts
new file mode 100644
index 0000000..3699bce
--- /dev/null
+++ b/test/cdp/events-test.ts
@@ -0,0 +1,94 @@
+import { test, describe } from "node:test";
+import assert from "node:assert/strict";
+import { EVENTS, decodeEvent, isKnownEvent } from "../../src/cdp/events";
+import { createConsoleBuffer } from "../../src/cdp/console-buffer";
+import { createNetworkBuffer } from "../../src/cdp/network-buffer";
+
+describe("cdp events", () => {
+ test("decodes a dialog-opening event", () => {
+ const r = decodeEvent("Page.javascriptDialogOpening", { type: "confirm", message: "Sure?" });
+ assert.equal(r.success, true);
+ if (r.success) assert.equal(r.data.type, "confirm");
+ });
+
+ test("rejects a malformed event payload", () => {
+ const r = decodeEvent("Page.javascriptDialogOpening", { type: 5 });
+ assert.equal(r.success, false);
+ if (!r.success) {
+ assert.equal(r.error.kind, "invalid_response");
+ assert.equal(r.error.method, "Page.javascriptDialogOpening");
+ }
+ });
+
+ test("tolerates unknown extra fields Chrome may add", () => {
+ const r = decodeEvent("Target.targetDestroyed", { targetId: "t1", extra: true });
+ assert.equal(r.success, true);
+ });
+
+ test("isKnownEvent gates unrecognised methods", () => {
+ assert.equal(isKnownEvent("Page.loadEventFired"), true);
+ assert.equal(isKnownEvent("Fetch.requestPaused"), false);
+ });
+
+ test("the table covers exactly the events the codebase dispatches on", () => {
+ assert.deepEqual(Object.keys(EVENTS).sort(), [
+ "Inspector.detached",
+ "Log.entryAdded",
+ "Network.loadingFailed",
+ "Network.loadingFinished",
+ "Network.requestWillBeSent",
+ "Network.responseReceived",
+ "Page.frameNavigated",
+ "Page.javascriptDialogOpening",
+ "Page.loadEventFired",
+ "Runtime.consoleAPICalled",
+ "Target.targetCreated",
+ "Target.targetDestroyed",
+ ]);
+ });
+
+ test("a non-object payload decodes to an error rather than throwing", () => {
+ assert.equal(decodeEvent("Target.targetDestroyed", null).success, false);
+ assert.equal(decodeEvent("Log.entryAdded", undefined).success, false);
+ });
+
+ test("targetCreated keeps openerId optional", () => {
+ const r = decodeEvent("Target.targetCreated", {
+ targetInfo: { targetId: "t1", type: "page", title: "x", url: "about:blank" },
+ });
+ assert.equal(r.success, true);
+ if (r.success) assert.equal(r.data.targetInfo.openerId, undefined);
+ });
+});
+
+describe("cdp events dropped payloads", () => {
+ test("console buffer ignores a malformed Log.entryAdded without throwing", () => {
+ const buf = createConsoleBuffer();
+ buf.ingestLogEntry({ entry: { level: "error", text: 42 } });
+ assert.deepEqual(buf.drain({}).records, []);
+ });
+
+ test("console buffer still records a well-formed Log.entryAdded", () => {
+ const buf = createConsoleBuffer();
+ buf.ingestLogEntry({ entry: { level: "error", text: "boom" } });
+ const drained = buf.drain({});
+ assert.equal(drained.records.length, 1);
+ assert.equal(drained.records[0]?.text, "boom");
+ assert.equal(drained.records[0]?.level, "error");
+ });
+
+ test("network buffer ignores a malformed requestWillBeSent without throwing", () => {
+ const buf = createNetworkBuffer();
+ buf.ingestRequestWillBeSent({ requestId: "r1", request: { url: 7, method: "GET" } });
+ assert.deepEqual(buf.drain({}).records, []);
+ });
+
+ test("network buffer keeps an existing record when a later event is malformed", () => {
+ const buf = createNetworkBuffer();
+ buf.ingestRequestWillBeSent({ requestId: "r1", request: { url: "https://a/", method: "GET" } });
+ buf.ingestResponseReceived({ requestId: "r1", response: { status: "200" } });
+ const drained = buf.drain({});
+ assert.equal(drained.records.length, 1);
+ assert.equal(drained.records[0]?.status, undefined);
+ });
+});