In Handstage, every open browser tab is represented by aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/l-xiaoshen/handstage/llms.txt
Use this file to discover all available pages before exploring further.
Page object. A Page maps one-to-one with a top-level CDP target — the Chrome concept for a navigable document. You create pages through a V3Context, navigate them with familiar browser-history methods, and query their current URL or title at any time.
Pages as browser tabs
EachPage instance owns the CDP session for its target, tracks all child frames (including out-of-process iframes), and exposes the high-level automation API you use day-to-day. OOPIF (out-of-process iframe) targets are adopted by the owning Page automatically — you interact with them through the same locator and frame APIs without any extra setup.
Opening a new page
Callcontext.newPage() to create a new tab. You can pass a URL to navigate immediately, or omit it to open about:blank.
Handstage always creates the tab at
about:blank first, then navigates to the requested URL after the target attaches. This ensures init scripts registered on the context run on the first real document.Listing open pages
context.pages() returns all top-level pages sorted from oldest to newest. OOPIF targets are not included — only top-level tabs appear in this list.
Active page
Handstage tracks which page was most recently interacted with as the “active” page.context.activePage() returns that page, or falls back to the newest tab if the recency list is empty.
context.setActivePage(page). This also brings the tab to the foreground in headful Chrome.
Navigation methods
EveryPage provides four navigation methods that mirror the browser’s own controls.
page.goto(url, options?)
page.goto(url, options?)
Navigate to a URL. By default waits for
"domcontentloaded" before resolving. Returns the HTTP response for the main document, or null if there was no network response (for example, about:blank).page.reload(options?)
page.reload(options?)
Reload the current page. Optionally pass
ignoreCache: true to bypass the browser cache.page.goBack(options?)
page.goBack(options?)
Navigate to the previous entry in the browser’s history. Returns
null if there is nothing to go back to.page.goForward(options?)
page.goForward(options?)
Navigate to the next entry in the browser’s history. Returns
null if there is nothing to go forward to.Load states
All navigation methods accept awaitUntil option that controls which lifecycle event Handstage waits for before resolving.
| Value | Description |
|---|---|
"load" | Waits for the load event — all resources including images and stylesheets have finished loading. |
"domcontentloaded" | Waits for the DOMContentLoaded event — the HTML has been parsed and the DOM is ready. This is the default for goto(). |
"networkidle" | Waits until there have been no new network requests for at least 500ms. Useful for pages with deferred data fetching. |
page.waitForLoadState():
Reading page URL and title
page.url() is synchronous and returns the cached URL from the most recent navigation event. page.title() is async and reads directly from the live document.
OOPIF support
Chrome renders cross-origin iframes in separate renderer processes called out-of-process iframes (OOPIFs). Handstage adopts OOPIF child sessions automatically as they attach and routes their frame events to the owningPage. You do not need to handle OOPIFs differently — locators and frame APIs work the same way whether an iframe is in-process or out-of-process.
Init scripts
Usecontext.addInitScript() to register a JavaScript snippet that runs at document start on every page in the context — including pages that are opened later. This is the right place to install polyfills, mock browser APIs, or seed test data before the page’s own scripts execute.