Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/optional/chrome-cdp/scripts/cdp.unit.test.mjs

Raw
import assert from "node:assert/strict";
import { EventEmitter } from "node:events";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { __test } from "./cdp.mjs";

const PNG_1X1 =
	"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=";

function fakeCdp(handler) {
	const events = new Map();
	return {
		send(method, params = {}, sid) {
			return handler(method, params, sid, events);
		},
		waitForEvent(method) {
			let cancel = false;
			return {
				promise: new Promise((resolve, reject) => {
					events.set(method, { resolve, reject, isCanceled: () => cancel });
				}),
				cancel() {
					cancel = true;
				},
			};
		},
	};
}

test("envInt accepts finite values above min and rejects bad input", () => {
	process.env.PI_TMP_INT = "42";
	assert.equal(__test.envInt("PI_TMP_INT", 7), 42);
	process.env.PI_TMP_INT = "0";
	assert.equal(__test.envInt("PI_TMP_INT", 7), 7);
	assert.equal(__test.envInt("PI_TMP_INT", 7, { min: 0 }), 0);
	process.env.PI_TMP_INT = "nope";
	assert.equal(__test.envInt("PI_TMP_INT", 7), 7);
	delete process.env.PI_TMP_INT;
	assert.equal(__test.envInt("PI_TMP_INT", 7), 7);
});

test("resolvePrefix reports no match, ambiguity, and exact match", () => {
	assert.equal(__test.resolvePrefix("abc", ["ABC123"], "target"), "ABC123");
	assert.throws(
		() => __test.resolvePrefix("zzz", ["ABC123"], "target", "Run list."),
		/No target matching prefix "zzz"\. Run list\./,
	);
	assert.throws(
		() => __test.resolvePrefix("abc", ["ABC123", "ABCD99"], "target"),
		/Ambiguous prefix/,
	);
});

test("getDisplayPrefixLength finds shortest unique uppercase-insensitive prefix", () => {
	assert.equal(__test.getDisplayPrefixLength([]), 8);
	assert.equal(__test.getDisplayPrefixLength(["ABCDEF120", "abcdef12F"]), 9);
	assert.equal(__test.getDisplayPrefixLength(["SAME", "same"]), 4);
});

test("middle limiters preserve small input and mark truncated large input", () => {
	assert.equal(__test.limitTextMiddle("short", 10, "text"), "short");
	assert.match(
		__test.limitTextMiddle("abcdefghijklmnopqrstuvwxyz", 20, "text"),
		/text truncated/,
	);
	assert.deepEqual(__test.limitLinesMiddle(["a", "b"], 3, "lines"), ["a", "b"]);
	assert.deepEqual(__test.limitLinesMiddle(["a", "b", "c", "d", "e"], 3, "lines"), [
		"a",
		"b",
		"… (lines truncated: 5 lines > 3; set limit env to 0 to disable)",
	]);
});

test("evalStr renders objects, nulls, and exception descriptions", async () => {
	assert.equal(
		await __test.evalStr(fakeCdp((method) => method === "Runtime.evaluate" ? { result: { value: { ok: true } } } : {}), "sid", "obj"),
		'{\n  "ok": true\n}',
	);
	assert.equal(
		await __test.evalStr(fakeCdp((method) => method === "Runtime.evaluate" ? { result: { value: null } } : {}), "sid", "nil"),
		"",
	);
	await assert.rejects(
		() => __test.evalStr(fakeCdp((method) => method === "Runtime.evaluate" ? { exceptionDetails: { exception: { description: "Error: boom" } } } : {}), "sid", "bad"),
		/Error: boom/,
	);
});

test("snapshotStr orders explicit and parent-linked children without duplicates", async () => {
	const out = await __test.snapshotStr(fakeCdp(() => ({
		nodes: [
			{ nodeId: "1", role: { value: "RootWebArea" }, name: { value: "Root" }, childIds: ["2"] },
			{ nodeId: "2", parentId: "1", role: { value: "button" }, name: { value: "Go" } },
			{ nodeId: "3", parentId: "1", role: { value: "checkbox" }, name: { value: "Remember" }, value: { value: true } },
			{ nodeId: "4", role: { value: "none" }, name: { value: "" } },
		],
	})), "sid", false);
	assert.match(out, /\[RootWebArea\] Root/);
	assert.match(out, /  \[button\] Go/);
	assert.match(out, /  \[checkbox\] Remember = true/);
	assert.doesNotMatch(out, /\[none\]/);
});

test("shotStr falls back to layout metrics when devicePixelRatio eval fails", async () => {
	const dir = await mkdtemp(join(tmpdir(), "cdp-shot-unit-"));
	const out = join(dir, "shot.png");
	try {
		const result = await __test.shotStr(fakeCdp((method) => {
			if (method === "Runtime.evaluate") throw new Error("no dpr");
			if (method === "Page.getLayoutMetrics") return { visualViewport: { clientWidth: 1600 }, cssVisualViewport: { clientWidth: 800 } };
			if (method === "Page.captureScreenshot") return { data: PNG_1X1 };
			return {};
		}), "sid", out);
		assert.match(result, /DPR\): 2/);
		assert.equal(await readFile(out, "base64"), PNG_1X1);
	} finally {
		await rm(dir, { recursive: true, force: true });
	}
});

test("navStr cancels immediately when no loaderId is returned", async () => {
	let canceled = false;
	const cdp = fakeCdp((method, _params, _sid, events) => {
		if (method === "Page.navigate") return { frameId: "same-document" };
		if (method === "Runtime.evaluate") return { result: { value: "complete" } };
		return {};
	});
	const originalWait = cdp.waitForEvent;
	cdp.waitForEvent = (method) => {
		const event = originalWait(method);
		const originalCancel = event.cancel;
		event.cancel = () => {
			canceled = true;
			originalCancel();
		};
		return event;
	};
	assert.equal(await __test.navStr(cdp, "sid", "https://example.test/hash"), "Navigated to https://example.test/hash");
	assert.equal(canceled, true);
});

test("sendCommand handles early end, early close, and socket errors", async () => {
	class FakeConn extends EventEmitter {
		write() {}
		end() {}
	}

	const ended = new FakeConn();
	const endPromise = __test.sendCommand(ended, { cmd: "x" });
	ended.emit("end");
	await assert.rejects(() => endPromise, /Connection closed before response/);

	const closed = new FakeConn();
	const closePromise = __test.sendCommand(closed, { cmd: "x" });
	closed.emit("close");
	await assert.rejects(() => closePromise, /Connection closed before response/);

	const errored = new FakeConn();
	const errorPromise = __test.sendCommand(errored, { cmd: "x" });
	errored.emit("error", new Error("boom"));
	await assert.rejects(() => errorPromise, /boom/);
});

test("waitForDocumentReady reports timeout states and errors", async () => {
	await assert.rejects(
		() => __test.waitForDocumentReady(fakeCdp(() => ({ result: { value: "loading" } })), "sid", 1),
		/last readyState: loading/,
	);
	await assert.rejects(
		() => __test.waitForDocumentReady(fakeCdp(() => { throw new Error("runtime gone"); }), "sid", 1),
		/runtime gone/,
	);
	await assert.rejects(
		() => __test.waitForDocumentReady(fakeCdp(() => ({ result: { value: "" } })), "sid", 1),
		/Timed out waiting for navigation to finish$/,
	);
});

test("netStr formats missing sizes", async () => {
	const out = await __test.netStr(fakeCdp((method) => method === "Runtime.evaluate" ? { result: { value: JSON.stringify([{ name: "https://example.test/x", duration: 1 }]) } } : {}), "sid");
	assert.match(out, /\?B\s+\?\s+https:\/\/example\.test\/x/);
});