feat: support ConnectOptions in remoteEndpoint for exposeNetwork#40388
feat: support ConnectOptions in remoteEndpoint for exposeNetwork#40388Ek03ansh wants to merge 10 commits intomicrosoft:mainfrom
Conversation
This comment has been minimized.
This comment has been minimized.
|
@Ek03ansh Thank you for the PR! Could you please file an issue first, as per the contributing guide? |
|
As for the fix, I suggest |
This comment has been minimized.
This comment has been minimized.
|
@dgozman Thanks for the feedback! Here's what I've done:
The CI failures ( Note: The |
This comment has been minimized.
This comment has been minimized.
dgozman
left a comment
There was a problem hiding this comment.
The implementation looks good, but the test is failing. Could you please take a look?
4fcb08d to
351cd40
Compare
This comment has been minimized.
This comment has been minimized.
…teBrowser When using a remote browser endpoint via cli.config.json, the `createRemoteBrowser` function only passes `endpoint` to `connectToBrowser`, ignoring `config.browser.exposeNetwork`. This means `exposeNetwork: '<loopback>'` in the config has no effect, and the remote browser cannot access localhost on the client machine. The fix forwards `config.browser.exposeNetwork` to the connect call, enabling SOCKS proxy tunneling for loopback traffic — matching the behavior of Playwright's test runner `connectOptions.exposeNetwork`.
Adds the `exposeNetwork` property to the browser config type so it can be set via cli.config.json and passed to connectToBrowser.
Instead of a separate exposeNetwork field, allow remoteEndpoint to accept either a plain URL string or a full ConnectOptions object. This mirrors the existing ConnectOptions type from Playwright's API and enables passing exposeNetwork, headers, slowMo, and timeout for remote connections. Fixes microsoft#40478
- Define ConnectOptions as playwright.ConnectOptions & { endpoint: string }
instead of inlining the full object type
- Fix serverRegistry.find() call to extract endpoint string from the union
type (was passing object to a string param)
- Hoist remoteEndpoint extraction to top of createRemoteBrowser() to avoid
duplicate declaration
Remove the separate exported ConnectOptions type. Use
playwright.ConnectOptions & { endpoint: string } inline,
matching how the codebase uses playwright.LaunchOptions
and playwright.BrowserContextOptions directly.
351cd40 to
dc5b4a0
Compare
This comment has been minimized.
This comment has been minimized.
Remove exposeNetwork from the test to focus on verifying the object form of remoteEndpoint works correctly. exposeNetwork is a connectToBrowser feature that works independently - testing the config type union is the goal of this test, not end-to-end SOCKS proxy tunneling. Use the same assertion pattern (server.PREFIX + Hello world snapshot) as the existing config tests.
This comment has been minimized.
This comment has been minimized.
… page content The remote browser (launched via chromium.launchServer()) cannot reach the test process's local HTTP server since there is no exposeNetwork tunneling. Instead of navigating and checking page content, verify the object form of remoteEndpoint works by taking a snapshot of the default blank page - this proves the MCP server correctly parsed the ConnectOptions object and connected to the remote browser. Verified locally: passes on chromium and chrome projects.
… content The server doesn't serve Hello world by default - need server.setContent() like the other config tests do (line 24). Also restored server fixture and navigate + snapshot assertion to properly verify the remote browser can load content through the object form of remoteEndpoint. The wsEndpoint fixture (chromium.launchServer()) creates a local browser server on the same machine, so localhost is reachable without exposeNetwork. Verified locally: passes on chromium and chrome projects.
Two tests for the object form of remoteEndpoint: 1. Basic object with just endpoint - verifies config type union works 2. Object with exposeNetwork: '*' - verifies the main use case (issue microsoft#40478) Both use server.setContent() + navigate + snapshot assertion matching the pattern of existing config tests. Verified locally: both pass on chromium and chrome projects.
Test results for "MCP"7 failed 6245 passed, 924 skipped Merge workflow run. |
Fixes #40478
Problem
When using
playwright-cliwith a remote browser endpoint via config,exposeNetwork(and otherConnectOptions) cannot be passed through to theconnectToBrowsercall. This prevents users from accessinglocalhoston the client machine from the remote browser (via SOCKS proxy tunneling).Solution
Per @dgozman's suggestion, change
remoteEndpointfromstringtostring | playwright.ConnectOptions & { endpoint: string }:This removes the previously proposed separate
exposeNetworkfield and instead mirrors the existingConnectOptionsshape from Playwright's API (same pattern asbrowserType.connect(options: api.ConnectOptions & { wsEndpoint: string })elsewhere in the codebase).Usage
Simple (existing behavior):
{ "browser": { "remoteEndpoint": "wss://..." } }With options:
{ "browser": { "remoteEndpoint": { "endpoint": "wss://...", "exposeNetwork": "*", "headers": { "x-custom": "value" } } } }Changes
config.d.ts:remoteEndpoint?: string | playwright.ConnectOptions & { endpoint: string }(inline intersection), removed separateexposeNetworkfieldbrowserFactory.ts: Extractsendpointstring forserverRegistry.find(), then buildsconnectOptionsfrom the union — if string, wraps as{ endpoint }, otherwise passes as-is toconnectToBrowsertests/mcp/config.spec.ts: Added test forremoteEndpointas ConnectOptions object withexposeNetwork: '*'— connects to a remote browser, navigates to a local server route, and verifies content is accessible