diff options
| author | amankumarsingh77 <amankumarsingh7702@gmail.com> | 2026-07-27 23:46:25 +0530 |
|---|---|---|
| committer | Aman Kumar <145339995+amankumarsingh77@users.noreply.github.com> | 2026-08-02 19:12:46 +0530 |
| commit | 753c2ad615fa9827e168be256e1a7c7384605855 (patch) | |
| tree | 03d62eb1816f4ad0ad3b634b87c4dcdb6fdbd83c /test | |
| parent | d54d8e9e2dfbd31358b1f48e17338d74f5d270c0 (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.ts | 94 |
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); + }); +}); |
