fix(extension): support multiple tabs opened by Playwright#1478
Draft
snomiao wants to merge 10 commits intomicrosoft:mainfrom
Draft
fix(extension): support multiple tabs opened by Playwright#1478snomiao wants to merge 10 commits intomicrosoft:mainfrom
snomiao wants to merge 10 commits intomicrosoft:mainfrom
Conversation
…multiple tabs - Add createTab command: extension creates real Chrome tab via chrome.tabs.create() - Forward CDP events from all Playwright-opened tabs (not just the initial tab) - Route forwardCDPCommand by tabId to correct debuggee - attachToTab now returns tabId for session tracking - Update manifest name to 'Playwright MCP Bridge (multi-tab)' and version to 0.0.68.1
- status.html now shows a 'Playwright managed tabs' section listing all tabs opened by Playwright - Extension icon shows blue ✓ badge on Playwright-managed tabs - background.ts tracks playwright tab IDs via relay callbacks - relayConnection.ts fires onPlaywrightTabCreated/onPlaywrightTabRemoved callbacks - Bump version to 0.0.68.2
- Use inferred Set type: Set<number> = new Set() -> = new Set<number>() - Use nullish coalescing for url default (|| -> ??) - Fix ternary indentation to 4-space continuation - Remove stale comment on forwardCDPCommand - Fix double space in import
Contributor
Author
|
@microsoft-github-policy-service agree |
…olated - background.ts: replace single _activeConnection with _connections Map keyed by relay URL - Each relay URL (UUID-based) gets its own ConnectionState with its own tab set - Multiple simultaneous MCP instances no longer conflict - status.html shows all active connections, each with their own tab lists - disconnect accepts optional mcpRelayUrl to target specific instance - getConnectionStatus returns full connections array (with legacy compat fields) - Bump version to 0.0.68.3
When a .playwright/ marker directory exists in the project tree, default PLAYWRIGHT_MCP_OUTPUT_DIR to .playwright/mcp-output/ and PLAYWRIGHT_MCP_USER_DATA_DIR to .playwright/mcp-profile/. This gives each project automatic workspace-level isolation — different projects get different browser profiles and output dirs without any manual config. Falls back to upstream defaults when no workspace is found. Explicitly set env vars always take precedence.
In --extension mode the relay opens connect.html in the user's running Chrome by matching user-data-dir. Setting a workspace-local profile dir caused a new Chrome window to spawn instead of reusing the existing one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1317
Problem
When using
--extensionmode, Playwright can only control the single tab that was manually selected in the extension popup. Any tab Playwright opens viatab-new(i.e.Target.createTarget) is created but immediately uncontrollable.Root cause:
_onDebuggerEventinRelayConnectiononly forwards CDP events wheresource.tabId === this._debuggee.tabId. New tabs never have a debugger attached and their events are never forwarded — so Playwright sees them intab-listbut cannot interact with them.Fix
relayConnection.tscreateTabcommand: creates a Chrome tab viachrome.tabs.create(), attaches the debugger, and returns{ tabId, targetInfo }to the relay_playwrightTabIds: Set<number>tabIdfor relay routing)forwardCDPCommandto the correct debuggee bytabIdattachToTabnow returnstabIdso the relay can build its session→tab mappingonPlaywrightTabCreated/onPlaywrightTabRemovedcallbacks for the background scriptbackground.ts✓badge on Playwright-managed tabs (distinct from the green✓on the initial connected tab)playwrightTabIdsviagetConnectionStatus_onTabRemovedstatus.tsxDemo: multi-tab control (playwright-cli)
Open two independent sessions in different workspaces simultaneously, each managing their own tabs:
Each session sees only its own tabs. Tab 1 in each was navigated externally by the user mid-test — and both sessions continued working independently without interfering.
Demo: MCP server (playwright-mcp)
Start the MCP server from a project directory, connect via HTTP, and call tools:
Initialize and list available tools:
Returns 21 registered tools:
For use with Claude Code or Cursor, add to your MCP config:
{ "mcpServers": { "playwright": { "command": "playwright-mcp", "args": ["--extension"], "env": { "PLAYWRIGHT_MCP_EXTENSION_ID": "<your-extension-id>", "PLAYWRIGHT_MCP_EXTENSION_TOKEN": "<your-token>" } } } }When started from a project directory containing a
.playwright/marker (created byplaywright-cli install), browser profiles and output are automatically stored in.playwright/mcp-profile/and.playwright/mcp-output/— no manual path config needed.