fix(browser): handle extension relay page selection

This commit is contained in:
Peter Steinberger
2026-01-15 11:16:48 +00:00
parent 8daab932a2
commit 0a5b1fbcd1
3 changed files with 62 additions and 1 deletions

View File

@@ -0,0 +1,54 @@
import { describe, expect, it, vi } from "vitest";
describe("pw-session getPageForTargetId", () => {
it("falls back to the only page when CDP session attachment is blocked (extension relays)", async () => {
vi.resetModules();
const pageOn = vi.fn();
const contextOn = vi.fn();
const browserOn = vi.fn();
const browserClose = vi.fn(async () => {});
const context = {
pages: () => [],
on: contextOn,
newCDPSession: vi.fn(async () => {
throw new Error("Not allowed");
}),
} as unknown as import("playwright-core").BrowserContext;
const page = {
on: pageOn,
context: () => context,
} as unknown as import("playwright-core").Page;
// Fill pages() after page exists.
(context as unknown as { pages: () => unknown[] }).pages = () => [page];
const browser = {
contexts: () => [context],
on: browserOn,
close: browserClose,
} as unknown as import("playwright-core").Browser;
vi.doMock("playwright-core", () => ({
chromium: {
connectOverCDP: vi.fn(async () => browser),
},
}));
vi.doMock("./chrome.js", () => ({
getChromeWebSocketUrl: vi.fn(async () => null),
}));
const mod = await import("./pw-session.js");
const resolved = await mod.getPageForTargetId({
cdpUrl: "http://127.0.0.1:18792",
targetId: "NOT_A_TAB",
});
expect(resolved).toBe(page);
await mod.closePlaywrightBrowserConnection();
expect(browserClose).toHaveBeenCalled();
});
});

View File

@@ -332,7 +332,13 @@ export async function getPageForTargetId(opts: {
const first = pages[0];
if (!opts.targetId) return first;
const found = await findPageByTargetId(browser, opts.targetId);
if (!found) throw new Error("tab not found");
if (!found) {
// Extension relays can block CDP attachment APIs (e.g. Target.attachToBrowserTarget),
// which prevents us from resolving a page's targetId via newCDPSession(). If Playwright
// only exposes a single Page, use it as a best-effort fallback.
if (pages.length === 1) return first;
throw new Error("tab not found");
}
return found;
}