all repos — sz-chrome-remote-cdp @ master

pi-browser-harness, patched to drive a Chrome on another host over CDP, with castle_cdp_search web search

test/cdp/events-test.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 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);
  });
});