From 53c828150b19b37a910f267995cf10f1af0b5714 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Tue, 10 Feb 2026 09:49:39 -0600 Subject: [PATCH] fix: auto-switch to externally opened tabs Update `setupContextTracking` in `BrowserManager` to auto-switch `activePageIndex` to newly opened tabs and invalidate the CDP session accordingly. This mirrors what `newTab()` and `newWindow()` already do for explicitly created tabs, and aligns CLI behavior with how real browsers focus newly opened tabs. Fixes #384 --- src/browser.test.ts | 27 +++++++++++++++++++++++++++ src/browser.ts | 13 ++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/browser.test.ts b/src/browser.test.ts index ae0ea0cd..4df6b61e 100644 --- a/src/browser.test.ts +++ b/src/browser.test.ts @@ -132,6 +132,33 @@ describe('BrowserManager', () => { expect(result.remaining).toBe(1); } }); + + it('should auto-switch to externally opened tab (window.open)', async () => { + // Ensure we start on tab 0 + const initialIndex = browser.getActiveIndex(); + expect(initialIndex).toBe(0); + + const page = browser.getPage(); + + // Use window.open to create a new tab externally (as a user/script would) + await page.evaluate(() => { + window.open('about:blank', '_blank'); + }); + + // Wait for the new page event to be processed + await new Promise((resolve) => setTimeout(resolve, 500)); + + // Active tab should now be the newly opened tab + const newIndex = browser.getActiveIndex(); + expect(newIndex).toBe(1); + + const tabs = await browser.listTabs(); + expect(tabs.length).toBe(2); + expect(tabs[1].active).toBe(true); + + // Clean up: close the new tab + await browser.closeTab(1); + }); }); describe('context operations', () => { diff --git a/src/browser.ts b/src/browser.ts index c60baacd..b6a64e47 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -1278,7 +1278,7 @@ export class BrowserManager { /** * Set up tracking for new pages in a context (for CDP connections and popups/new tabs) - * This handles pages created externally (e.g., via target="_blank" links) + * This handles pages created externally (e.g., via target="_blank" links, window.open) */ private setupContextTracking(context: BrowserContext): void { context.on('page', (page) => { @@ -1287,6 +1287,17 @@ export class BrowserManager { this.pages.push(page); this.setupPageTracking(page); } + + // Auto-switch to the newly opened tab so subsequent commands target it. + // For tabs created via newTab()/newWindow(), this is redundant (they set activePageIndex after), + // but for externally opened tabs (window.open, target="_blank"), this ensures the active tab + // stays in sync with the browser. + const newIndex = this.pages.indexOf(page); + if (newIndex !== -1 && newIndex !== this.activePageIndex) { + this.activePageIndex = newIndex; + // Invalidate CDP session since the active page changed + this.invalidateCDPSession().catch(() => {}); + } }); }