()
| 658 | } |
| 659 | |
| 660 | async #getAllPages(): Promise<{ |
| 661 | pages: Page[]; |
| 662 | isolatedContextNames: Map<Page, string>; |
| 663 | }> { |
| 664 | const defaultCtx = this.browser.defaultBrowserContext(); |
| 665 | const allPages = await this.browser.pages( |
| 666 | this.#options.experimentalIncludeAllPages, |
| 667 | ); |
| 668 | |
| 669 | const allTargets = this.browser.targets(); |
| 670 | const extensionTargets = allTargets.filter(target => { |
| 671 | return ( |
| 672 | target.url().startsWith('chrome-extension://') && |
| 673 | target.type() === 'page' |
| 674 | ); |
| 675 | }); |
| 676 | |
| 677 | for (const target of extensionTargets) { |
| 678 | // Right now target.page() returns null for popup and side panel pages. |
| 679 | let page = await target.page(); |
| 680 | if (!page) { |
| 681 | // We need to cache pages instances for targets because target.asPage() |
| 682 | // returns a new page instance every time. |
| 683 | page = this.#extensionPages.get(target) ?? null; |
| 684 | if (!page) { |
| 685 | try { |
| 686 | page = await target.asPage(); |
| 687 | this.#extensionPages.set(target, page); |
| 688 | } catch (e) { |
| 689 | this.logger?.('Failed to get page for extension target', e); |
| 690 | } |
| 691 | } |
| 692 | } |
| 693 | |
| 694 | if (page && !allPages.includes(page)) { |
| 695 | allPages.push(page); |
| 696 | } |
| 697 | } |
| 698 | |
| 699 | // Build a reverse lookup from BrowserContext instance → name. |
| 700 | const contextToName = new Map<BrowserContext, string>(); |
| 701 | for (const [name, ctx] of this.#isolatedContexts) { |
| 702 | contextToName.set(ctx, name); |
| 703 | } |
| 704 | |
| 705 | // Auto-discover BrowserContexts not in our mapping (e.g., externally |
| 706 | // created incognito contexts) and assign generated names. |
| 707 | const knownContexts = new Set(this.#isolatedContexts.values()); |
| 708 | for (const ctx of this.browser.browserContexts()) { |
| 709 | if (ctx !== defaultCtx && !ctx.closed && !knownContexts.has(ctx)) { |
| 710 | const name = `isolated-context-${this.#nextIsolatedContextId++}`; |
| 711 | this.#isolatedContexts.set(name, ctx); |
| 712 | contextToName.set(ctx, name); |
| 713 | } |
| 714 | } |
| 715 | |
| 716 | // Map each page to its isolated context name (if any). |
| 717 | const isolatedContextNames = new Map<Page, string>(); |
no test coverage detected