Skip to content

Conversation

seanmcguire12
Copy link
Member

@seanmcguire12 seanmcguire12 commented Jun 27, 2025

why

  • when a new tab is opened, we call page.goto() with the URL of the new tab, and immediately close the old tab
  • this is problematic, because on some websites you are required to keep the old tab open in order to continue browsing in the new tab
  • this PR removes that behaviour: we no longer close tabs implicitly

what changed

  • added a live page proxy in index.ts which always points to the focused page/tab
  • added a listener in StagehandContext.ts which listens for new pages, and initializes them as Stagehand pages
    • this means that you can call act/extract/observe on all open pages, even if they are not the focused page
  • preserved expected behaviour when users define const page = stagehand.page and then use page throughout their code, they expect page to always point to the "focused" page

test plan

  • added two new act evals that open & close tabs
  • run act, regression and combination evals

Copy link

changeset-bot bot commented Jun 27, 2025

🦋 Changeset detected

Latest commit: 5ae360d

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@seanmcguire12 seanmcguire12 marked this pull request as ready for review June 30, 2025 22:40
@seanmcguire12 seanmcguire12 added act These changes pertain to the act function combination These changes affect multiple Stagehand functions labels Jun 30, 2025
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

Major update to tab management in Stagehand that stops automatically closing new tabs, essential for websites requiring original tabs to remain open during navigation.

  • Added live page proxy in lib/index.ts that dynamically tracks the focused page/tab
  • New page event listener in lib/StagehandContext.ts automatically initializes new tabs as StagehandPages
  • Removed automatic tab closure from lib/handlers/actHandlerUtils.ts and lib/handlers/agentHandler.ts
  • Added comprehensive tab handling tests with evals/tasks/tab_handling.ts, multi_tab.ts, and agent/kayak.ts
  • Memory management consideration: tabs must now be manually closed as they're no longer automatically cleaned up

11 files reviewed, 7 comments
Edit PR Review Bot Settings | Greptile

Comment on lines +408 to +423
const handler: ProxyHandler<T> = {
get: (_t, prop, receiver) => {
const real = this.stagehandPage.page as unknown as T;
const value = Reflect.get(real, prop, receiver);
return typeof value === "function" ? value.bind(real) : value;
},
set: (_t, prop, value) => {
const real = this.stagehandPage.page as unknown as T;
Reflect.set(real, prop, value);
return true;
},
has: (_t, prop) => prop in (this.stagehandPage.page as unknown as T),
getPrototypeOf: () => proto,
};

return new Proxy(target, handler);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The proxy handler doesn't implement deleteProperty, defineProperty, or ownKeys. This could cause issues with property deletion and object property enumeration.

if (!this._livePageProxy) {
this._livePageProxy = this.createLivePageProxy<Page>();
}
return this._livePageProxy;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v nice

@miguelg719 miguelg719 added the parity To note required feature parity in client SDKs label Jun 30, 2025
@the-roaring the-roaring added parity To note required feature parity in client SDKs and removed parity To note required feature parity in client SDKs labels Jun 30, 2025
@the-roaring the-roaring added parity To note required feature parity in client SDKs and removed parity To note required feature parity in client SDKs labels Jul 1, 2025
@seanmcguire12 seanmcguire12 merged commit 64c1072 into main Jul 1, 2025
15 checks passed
@miguelg719 miguelg719 added parity To note required feature parity in client SDKs and removed parity To note required feature parity in client SDKs labels Jul 1, 2025
@stagehand-parity-bot
Copy link

🔄 Feature Parity Issue Created

An issue has been automatically created in the Python SDK repository to track parity implementation:
browserbase/stagehand-python#131

seanmcguire12 pushed a commit that referenced this pull request Jul 4, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @browserbasehq/[email protected]

### Patch Changes

- [#856](#856)
[`8a43c5a`](8a43c5a)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - set
download behaviour by default

- [#857](#857)
[`890ffcc`](890ffcc)
Thanks [@miguelg719](https://github.com/miguelg719)! - return
"not-supported" for elements inside the shadow-dom

- [#844](#844)
[`64c1072`](64c1072)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - don't
automatically close tabs

- [#860](#860)
[`b077d3f`](b077d3f)
Thanks [@miguelg719](https://github.com/miguelg719)! - Set default
schema on extract options with no schema

- [#842](#842)
[`8bcb5d7`](8bcb5d7)
Thanks [@seanmcguire12](https://github.com/seanmcguire12)! - improved
handling for OS level dropdowns

- [#846](#846)
[`7bf10c5`](7bf10c5)
Thanks [@miguelg719](https://github.com/miguelg719)! - Filter attaching
to target worker / shared_worker

## @browserbasehq/[email protected]

### Patch Changes

- Updated dependencies
\[[`8a43c5a`](8a43c5a),
[`890ffcc`](890ffcc),
[`64c1072`](64c1072),
[`b077d3f`](b077d3f),
[`8bcb5d7`](8bcb5d7),
[`7bf10c5`](7bf10c5)]:
    -   @browserbasehq/[email protected]

## @browserbasehq/[email protected]

### Patch Changes

- Updated dependencies
\[[`8a43c5a`](8a43c5a),
[`890ffcc`](890ffcc),
[`64c1072`](64c1072),
[`b077d3f`](b077d3f),
[`8bcb5d7`](8bcb5d7),
[`7bf10c5`](7bf10c5)]:
    -   @browserbasehq/[email protected]

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
arunpatro pushed a commit to arunpatro/stagehand-python that referenced this pull request Jul 22, 2025
- Add live page proxy that dynamically tracks the focused page
- Implement context event listener to initialize new pages automatically
- Remove automatic tab closing behavior in act_handler_utils and cua_handler
- Keep both original and new tabs open when new pages are created
- Ensure stagehand.page always references the current active page

This implementation matches the behavior of browserbase/stagehand#844
miguelg719 added a commit to browserbase/stagehand-python that referenced this pull request Jul 26, 2025
* feat: port new page handling from JS Stagehand PR #844

- Add live page proxy that dynamically tracks the focused page
- Implement context event listener to initialize new pages automatically
- Remove automatic tab closing behavior in act_handler_utils and cua_handler
- Keep both original and new tabs open when new pages are created
- Ensure stagehand.page always references the current active page

This implementation matches the behavior of browserbase/stagehand#844

* Update stagehand/handlers/cua_handler.py

* Update stagehand/handlers/act_handler_utils.py

---------

Co-authored-by: Arun Patro <[email protected]>
Co-authored-by: Miguel <[email protected]>
miguelg719 added a commit to browserbase/stagehand-python that referenced this pull request Aug 9, 2025
* feat: don't close new opened tabs (#161)

* feat: port new page handling from JS Stagehand PR #844

- Add live page proxy that dynamically tracks the focused page
- Implement context event listener to initialize new pages automatically
- Remove automatic tab closing behavior in act_handler_utils and cua_handler
- Keep both original and new tabs open when new pages are created
- Ensure stagehand.page always references the current active page

This implementation matches the behavior of browserbase/stagehand#844

* Update stagehand/handlers/cua_handler.py

* Update stagehand/handlers/act_handler_utils.py

---------

Co-authored-by: Arun Patro <[email protected]>
Co-authored-by: Miguel <[email protected]>

* formatting, logs

* changeset

* fix: update mock_stagehand_client fixture to set internal page properties

The page property is now read-only (returns LivePageProxy), so tests need to set the internal _original_page and _active_page properties instead

* feat: add page stability check to LivePageProxy for async operations

Ensures async operations wait for any pending page switches to complete

* formatting

* fix: prevent deadlock in page navigation and add page stability tests

- Initialize _page_switch_lock in Stagehand constructor
- Skip page stability check for navigation methods (goto, reload, go_back, go_forward)
- Use lock when switching active pages in context
- Add comprehensive tests for LivePageProxy functionality

* consolidate original and active page to just one page

* Update stagehand/context.py

* Update .changeset/gorilla-of-strongest-novelty.md

* timeouts

* python 3.10 or less compatibility

---------

Co-authored-by: Arun Patro <[email protected]>
Co-authored-by: Arun Patro <[email protected]>
Co-authored-by: Filip Michalsky <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
act These changes pertain to the act function combination These changes affect multiple Stagehand functions parity To note required feature parity in client SDKs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants