fix(browser): handle extension relay page selection
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
- Browser: add `snapshot refs=aria` (Playwright aria-ref ids) for self-resolving refs across `snapshot` → `act`.
|
||||
- Browser: `profile="chrome"` now defaults to host control and returns clearer “attach a tab” errors.
|
||||
- Browser: extension mode recovers when only one tab is attached (stale targetId fallback).
|
||||
- Browser: fix `tab not found` for extension relay snapshots/actions when Playwright blocks `newCDPSession` (use the single available Page).
|
||||
- Control UI: show raw any-map entries in config views; move Docs link into the left nav.
|
||||
|
||||
#### Plugins
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user