import { describe, expect, test } from "bun:test"; import { pickElectronTarget } from "@oh-my-pi/pi-coding-agent/tools/browser/attach"; import { normalizeConnectedCdpUrl } from "@oh-my-pi/pi-coding-agent/tools/browser/registry"; import type { Browser, Page, Target } from "puppeteer-core"; interface FakePageOptions { url: string; title: string; } function fakePage(options: FakePageOptions): Page { return { url: () => options.url, title: async () => options.title, } as unknown as Page; } function fakeTarget(type: string, page: Page | null): Target { return { type: () => type, page: async () => page, } as unknown as Target; } describe("pickElectronTarget", () => { test("uses discovered CDP page targets when browser.pages is empty", async () => { const page = fakePage({ url: "https://www.google.com/", title: "Google" }); let pagesCalled = false; const browser = { targets: () => [fakeTarget("browser", null), fakeTarget("page", page)], pages: async () => { pagesCalled = true; return []; }, } as unknown as Browser; await expect(pickElectronTarget(browser, "google")).resolves.toBe(page); expect(pagesCalled).toBe(false); }); test("falls back to browser.pages when discovered targets have no usable page", async () => { const page = fakePage({ url: "https://example.com/", title: "Example" }); const browser = { targets: () => [fakeTarget("browser", null), fakeTarget("service_worker", null)], pages: async () => [page], } as unknown as Browser; await expect(pickElectronTarget(browser)).resolves.toBe(page); }); test("reports available pages when the matcher misses", async () => { const page = fakePage({ url: "https://example.com/", title: "Example" }); const browser = { targets: () => [fakeTarget("page", page)], pages: async () => [], } as unknown as Browser; await expect(pickElectronTarget(browser, "missing")).rejects.toThrow( 'No page target matched "missing". Available pages:\n- Example https://example.com/', ); }); test("rejects websocket cdp_url values with an actionable diagnostic", () => { expect(() => normalizeConnectedCdpUrl("ws://127.0.0.1:9222/devtools/browser/id")).toThrow( "browser app.cdp_url must be the HTTP CDP discovery endpoint", ); expect(normalizeConnectedCdpUrl("http://127.0.0.1:9222/")).toBe("http://127.0.0.1:9222"); }); });