page.changeTab() — Multi-Tab Support
Switch the active Donobu context to another open browser tab while maintaining a single shared flow ID and cache.
Switches the active Donobu context to another open browser tab, returning a new DonobuExtendedPage for that tab. All tabs in the same browser context share a single flow — the AI treats cross-tab navigation as one continuous session.
Signature
page.changeTab(url: string): Promise<DonobuExtendedPage>
Parameters
| Parameter | Type | Description |
|---|---|---|
url | string | Exact URL or a distinctive substring of the tab's current URL |
Return value
A DonobuExtendedPage pointing to the matched tab. The returned page has the same flow ID and shared state as the original page.
Usage
import { test } from 'donobu';
test('open a link in a new tab and verify it', async ({ page }) => {
await page.goto('https://app.example.com/dashboard');
// Trigger an action that opens a new tab
await page.ai('Click the "Open report" link');
// Switch Donobu context to the new tab
const reportTab = await page.changeTab('https://app.example.com/report');
await reportTab.ai.assert('A data table is visible with at least one row');
});
Shared flow context
All tabs opened from the same browser context automatically share one flow ID and one cache. This means:
page.aicalls on any tab are recorded as part of the same flow and are visible together in Donobu Studio- The
.cache-lock/cache is shared — an instruction cached on one tab is reused if the same instruction is called on another tab at the same hostname
Constraint: you cannot assign two different flow IDs to tabs in the same browser context. If you need completely independent flows, create separate browser contexts.
Throws
Throws ToolCallFailedException if no open tab matches the provided URL. The exception has the following properties:
| Property | Type | Description |
|---|---|---|
toolName | string | The name of the tool that failed ('changeWebBrowserTab') |
result | ToolCallResult | The full result object, including isSuccessful: false and a forLlm description of why the tab was not found |
message | string | A human-readable description including the serialised result |
Make sure the URL you pass matches one of the tabs currently open in the browser context. Use a distinctive substring of the URL if the full URL is dynamic.
Comparison with vanilla Playwright
In standard Playwright, you switch between tabs by getting all pages from the browser context and finding the one you want:
// Vanilla Playwright
const pages = page.context().pages();
const reportPage = pages.find((p) => p.url().includes('/report'));
await reportPage.bringToFront();
page.changeTab() does the same thing but also wires the new tab into Donobu's flow tracking, so tool calls on the new tab are recorded as part of the same flow and appear in Donobu Studio under the same run.