Skip to content

feat: support ConnectOptions in remoteEndpoint for exposeNetwork#40388

Open
Ek03ansh wants to merge 10 commits intomicrosoft:mainfrom
Ek03ansh:fix/expose-network-remote-browser
Open

feat: support ConnectOptions in remoteEndpoint for exposeNetwork#40388
Ek03ansh wants to merge 10 commits intomicrosoft:mainfrom
Ek03ansh:fix/expose-network-remote-browser

Conversation

@Ek03ansh
Copy link
Copy Markdown

@Ek03ansh Ek03ansh commented Apr 23, 2026

Fixes #40478

Problem

When using playwright-cli with a remote browser endpoint via config, exposeNetwork (and other ConnectOptions) cannot be passed through to the connectToBrowser call. This prevents users from accessing localhost on the client machine from the remote browser (via SOCKS proxy tunneling).

Solution

Per @dgozman's suggestion, change remoteEndpoint from string to string | playwright.ConnectOptions & { endpoint: string }:

remoteEndpoint?: string | playwright.ConnectOptions & { endpoint: string };
// Expands to: string | { endpoint: string; exposeNetwork?: string; headers?: Record<string, string>; slowMo?: number; timeout?: number }

This removes the previously proposed separate exposeNetwork field and instead mirrors the existing ConnectOptions shape from Playwright's API (same pattern as browserType.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 separate exposeNetwork field
  • browserFactory.ts: Extracts endpoint string for serverRegistry.find(), then builds connectOptions from the union — if string, wraps as { endpoint }, otherwise passes as-is to connectToBrowser
  • tests/mcp/config.spec.ts: Added test for remoteEndpoint as ConnectOptions object with exposeNetwork: '*' — connects to a remote browser, navigates to a local server route, and verifies content is accessible

@github-actions

This comment has been minimized.

@dgozman
Copy link
Copy Markdown
Collaborator

dgozman commented Apr 24, 2026

@Ek03ansh Thank you for the PR! Could you please file an issue first, as per the contributing guide?

@dgozman
Copy link
Copy Markdown
Collaborator

dgozman commented Apr 24, 2026

As for the fix, I suggest remoteEndpoint?: string | ConnectOptions, mirroring ConnectOptions from our API.

@Ek03ansh Ek03ansh changed the title fix: pass exposeNetwork from config to connectToBrowser in createRemoteBrowser feat: support ConnectOptions in remoteEndpoint for exposeNetwork Apr 29, 2026
@github-actions

This comment has been minimized.

@Ek03ansh
Copy link
Copy Markdown
Author

@dgozman Thanks for the feedback! Here's what I've done:

  1. Issue filed: [Feature] exposeNetwork not supported for remote browser connections in CLI config #40478
  2. Approach updated: Changed to remoteEndpoint?: string | playwright.ConnectOptions & { endpoint: string } as you suggested — mirrors the existing ConnectOptions API shape, with endpoint added since it's required for the remote connection (same pattern as browserType.connect(options: api.ConnectOptions & { wsEndpoint: string }) elsewhere in the codebase).
  3. Test added: Added a test in tests/mcp/config.spec.ts that verifies the object form of remoteEndpoint with exposeNetwork: '*' — connects to a remote browser, navigates to a local server route, and verifies the content is accessible through the SOCKS proxy tunnel.

The CI failures (dashboard.spec.ts, cli-devtools.spec.ts, autowait.spec.ts, cli-session.spec.ts) appear to be pre-existing and unrelated to this change.

Note: The microsoft/playwright-cli repo README documents remoteEndpoint as string in its config schema — that would need a follow-up update once this lands.

@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Collaborator

@dgozman dgozman left a comment

Choose a reason for hiding this comment

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

The implementation looks good, but the test is failing. Could you please take a look?

@Ek03ansh Ek03ansh force-pushed the fix/expose-network-remote-browser branch from 4fcb08d to 351cd40 Compare April 29, 2026 22:12
@github-actions

This comment has been minimized.

Ek03ansh and others added 6 commits April 30, 2026 05:56
…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.
@Ek03ansh Ek03ansh force-pushed the fix/expose-network-remote-browser branch from 351cd40 to dc5b4a0 Compare April 30, 2026 00:26
@github-actions

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.
@github-actions

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.
@github-actions
Copy link
Copy Markdown
Contributor

Test results for "MCP"

7 failed
❌ [chrome] › mcp/autowait.spec.ts:19 › racy navigation destroys context @mcp-windows-latest-chrome
❌ [chromium] › mcp/dashboard.spec.ts:231 › should switch screencast to -s session on show --annotate @mcp-windows-latest-chromium
❌ [firefox] › mcp/tracing.spec.ts:54 › check that trace is saved with browser_start_tracing (no output dir) @mcp-windows-latest-firefox
❌ [msedge] › mcp/config.spec.ts:138 › browser_get_config returns merged config from file, env and cli @mcp-windows-latest-msedge
❌ [msedge] › mcp/dashboard.spec.ts:207 › should enter annotate mode on fresh dashboard.tsx mount with -s --annotate @mcp-windows-latest-msedge
❌ [msedge] › mcp/dashboard.spec.ts:231 › should switch screencast to -s session on show --annotate @mcp-windows-latest-msedge
❌ [webkit] › mcp/dashboard.spec.ts:185 › should start dashboard and annotate when no dashboard is running @mcp-macos-latest-webkit

6245 passed, 924 skipped


Merge workflow run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] exposeNetwork not supported for remote browser connections in CLI config

3 participants