Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions packages/playwright-core/src/tools/mcp/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,19 +258,22 @@ function configFromCLIOptions(cliOptions: CLIOptions): Config & { configFile?: s
if (cliOptions.sandbox !== undefined)
launchOptions.chromiumSandbox = cliOptions.sandbox;

if (cliOptions.proxyServer) {
launchOptions.proxy = {
server: cliOptions.proxyServer
};
if (cliOptions.proxyBypass)
launchOptions.proxy.bypass = cliOptions.proxyBypass;
}

if (cliOptions.device && cliOptions.cdpEndpoint)
throw new Error('Device emulation is not supported with cdpEndpoint.');

// Context options
const contextOptions: playwrightTypes.BrowserContextOptions = cliOptions.device ? playwright.devices[cliOptions.device] : {};

if (cliOptions.proxyServer) {
const proxy: playwrightTypes.LaunchOptions['proxy'] = { server: cliOptions.proxyServer };
if (cliOptions.proxyBypass)
proxy.bypass = cliOptions.proxyBypass;
// Set on both to ensure CLI takes precedence over any proxy set in the config file
// (launchOptions.proxy applies at browser launch, contextOptions.proxy at context creation).
launchOptions.proxy = proxy;
contextOptions.proxy = proxy;
}

if (cliOptions.storageState)
contextOptions.storageState = cliOptions.storageState;

Expand Down
39 changes: 39 additions & 0 deletions tests/mcp/launch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,45 @@ test('isolated context with storage state', async ({ startClient, server }, test
});
});

test('--proxy-server routes browser traffic through the proxy', {
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/40204' },
}, async ({ startClient, server }) => {
server.setRoute('/target.html', (_req, res) => {
res.end('<html><title>Served by the proxy</title></html>');
});
const { client } = await startClient({
args: [`--proxy-server=${server.HOST}`],
});
expect(await client.callTool({
name: 'browser_navigate',
arguments: { url: 'http://non-existent.com/target.html' },
})).toHaveResponse({
page: expect.stringContaining('Served by the proxy'),
});
});

test('--proxy-server overrides contextOptions.proxy from config file', {
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/40204' },
}, async ({ startClient, server }) => {
server.setRoute('/target.html', (_req, res) => {
res.end('<html><title>Served by CLI proxy</title></html>');
});
const { client } = await startClient({
config: {
browser: {
contextOptions: { proxy: { server: 'http://unreachable-config-proxy:1' } },
},
},
args: [`--proxy-server=${server.HOST}`],
});
expect(await client.callTool({
name: 'browser_navigate',
arguments: { url: 'http://non-existent.com/target.html' },
})).toHaveResponse({
page: expect.stringContaining('Served by CLI proxy'),
});
});

test('proper launch error message for broken browser and persistent context', {
annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-mcp/issues/1305' }
}, async ({ startClient, server, mcpBrowser }, testInfo) => {
Expand Down
Loading