diff options
| author | amankumarsingh77 <amankumarsingh7702@gmail.com> | 2026-07-27 00:35:38 +0530 |
|---|---|---|
| committer | Aman Kumar <145339995+amankumarsingh77@users.noreply.github.com> | 2026-08-02 19:12:46 +0530 |
| commit | ae3a6dcdbe584a9131a514ea3d738abaec6460f3 (patch) | |
| tree | ce32fdb9560bb5b8cc3baa0ecbe5ad24ba06fff4 /test | |
| parent | 15a537a99efba614e6e108722462bcb78ec6c3c4 (diff) | |
feat(cdp): add typed command table with validated decoders
One typebox schema per CDP command is the source of both the TS types and
the runtime validator, so they cannot drift. Malformed responses become
invalid_response errors instead of TypeErrors several frames later.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'test')
| -rw-r--r-- | test/cdp/commands-test.ts | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/test/cdp/commands-test.ts b/test/cdp/commands-test.ts new file mode 100644 index 0000000..b316f68 --- /dev/null +++ b/test/cdp/commands-test.ts @@ -0,0 +1,45 @@ +import { test, describe } from "node:test"; +import assert from "node:assert/strict"; +import { COMMANDS, decodeResult } from "../../src/cdp/commands"; + +describe("cdp command table", () => { + test("decodes a well-formed response", () => { + const r = decodeResult("Target.attachToTarget", { sessionId: "s1" }); + assert.equal(r.success, true); + if (r.success) assert.equal(r.data.sessionId, "s1"); + }); + + test("rejects a response with a wrong field type", () => { + const r = decodeResult("Browser.getWindowForTarget", { windowId: "not-a-number" }); + assert.equal(r.success, false); + if (!r.success) { + assert.equal(r.error.kind, "invalid_response"); + assert.equal(r.error.method, "Browser.getWindowForTarget"); + assert.match(r.error.message, /must be number/); + } + }); + + test("rejects a response missing a required field", () => { + const r = decodeResult("Target.attachToTarget", {}); + assert.equal(r.success, false); + }); + + test("rejects a non-object response", () => { + const r = decodeResult("Target.attachToTarget", null); + assert.equal(r.success, false); + }); + + test("every table entry has both params and result schemas", () => { + for (const [method, spec] of Object.entries(COMMANDS)) { + assert.ok(spec.params, `${method} missing params schema`); + assert.ok(spec.result, `${method} missing result schema`); + assert.ok(spec.validate, `${method} missing compiled validator`); + } + }); + + test("an unknown method decodes to an error rather than throwing", () => { + // Types prevent this, but a daemon could echo an unexpected method name. + const r = decodeResult("Nope.method" as "Page.enable", {}); + assert.equal(r.success, false); + }); +}); |
