Skip to content

Commit 5ab8a9f

Browse files
committed
Unify CDP headers parsing and improve error messages
- Remove duplicate CDP headers documentation from README - Replace manual JSON parsing with parseJsonObject function - Use InvalidArgumentError for user-friendly error messages - Maintain consistency with other option parsers like commaSeparatedList Addresses review feedback on standardizing parse methods.
1 parent 83bbf89 commit 5ab8a9f

File tree

4 files changed

+12
-32
lines changed

4 files changed

+12
-32
lines changed

README.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -233,20 +233,6 @@ state [here](https://playwright.dev/docs/auth).
233233
}
234234
```
235235

236-
#### CDP Headers
237-
238-
When connecting to a CDP endpoint that requires authentication, you can pass headers:
239-
240-
```bash
241-
npx @playwright/mcp --cdp-endpoint=http://localhost:9222 --cdp-headers='{"Authorization": "Bearer your-token"}'
242-
```
243-
244-
Or via environment variable:
245-
```bash
246-
export PLAYWRIGHT_MCP_CDP_HEADERS='{"Authorization": "Bearer your-token"}'
247-
npx @playwright/mcp --cdp-endpoint=http://localhost:9222
248-
```
249-
250236
### Configuration file
251237

252238
The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file

src/config.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import fs from 'fs';
1818
import os from 'os';
1919
import path from 'path';
2020
import { devices } from 'playwright';
21+
import { InvalidArgumentError } from 'commander';
2122
import { sanitizeForFilePath } from './utils.js';
2223

2324
import type { Config, ToolCapability } from '../config.js';
@@ -207,7 +208,7 @@ function configFromEnv(): Config {
207208
options.browser = envToString(process.env.PLAYWRIGHT_MCP_BROWSER);
208209
options.caps = commaSeparatedList(process.env.PLAYWRIGHT_MCP_CAPS);
209210
options.cdpEndpoint = envToString(process.env.PLAYWRIGHT_MCP_CDP_ENDPOINT);
210-
options.cdpHeaders = parseJsonEnv(process.env.PLAYWRIGHT_MCP_CDP_HEADERS);
211+
options.cdpHeaders = parseJsonObject(process.env.PLAYWRIGHT_MCP_CDP_HEADERS);
211212
options.config = envToString(process.env.PLAYWRIGHT_MCP_CONFIG);
212213
options.device = envToString(process.env.PLAYWRIGHT_MCP_DEVICE);
213214
options.executablePath = envToString(process.env.PLAYWRIGHT_MCP_EXECUTABLE_PATH);
@@ -298,17 +299,21 @@ export function semicolonSeparatedList(value: string | undefined): string[] | un
298299
return value.split(';').map(v => v.trim());
299300
}
300301

301-
function parseJsonEnv(value: string | undefined): Record<string, string> | undefined {
302+
export function parseJsonObject(value: string | undefined): Record<string, string> | undefined {
302303
if (!value)
303304
return undefined;
304305
try {
305306
const parsed = JSON.parse(value);
306307
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
307-
throw new Error('Expected JSON object');
308+
throw new InvalidArgumentError('Expected JSON object');
308309
}
309310
return parsed;
310311
} catch (error) {
311-
throw new Error(`Invalid JSON in environment variable: ${error}`);
312+
if (error instanceof InvalidArgumentError) {
313+
throw error;
314+
}
315+
const errorMessage = error instanceof Error ? error.message : String(error);
316+
throw new InvalidArgumentError(`Invalid JSON format: ${errorMessage}`);
312317
}
313318
}
314319

src/program.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { program, Option } from 'commander';
1919
import { startTraceViewerServer } from 'playwright-core/lib/server';
2020

2121
import * as mcpTransport from './mcp/transport.js';
22-
import { commaSeparatedList, resolveCLIConfig, semicolonSeparatedList } from './config.js';
22+
import { commaSeparatedList, parseJsonObject, resolveCLIConfig, semicolonSeparatedList } from './config.js';
2323
import { packageJSON } from './package.js';
2424
import { createExtensionContextFactory, runWithExtension } from './extension/main.js';
2525
import { BrowserServerBackend, FactoryList } from './browserServerBackend.js';
@@ -36,7 +36,7 @@ program
3636
.option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
3737
.option('--caps <caps>', 'comma-separated list of additional capabilities to enable, possible values: vision, pdf.', commaSeparatedList)
3838
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
39-
.option('--cdp-headers <headers>', 'JSON string of headers to send with CDP connection, e.g. \'{"Authorization": "Bearer token"}\'')
39+
.option('--cdp-headers <headers>', 'JSON string of headers to send with CDP connection, e.g. \'{"Authorization": "Bearer token"}\'', parseJsonObject)
4040
.option('--config <path>', 'path to the configuration file.')
4141
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
4242
.option('--executable-path <path>', 'path to the browser executable.')
@@ -69,17 +69,6 @@ program
6969
options.caps = 'vision';
7070
}
7171

72-
// Parse CDP headers if provided
73-
if (options.cdpHeaders) {
74-
try {
75-
options.cdpHeaders = JSON.parse(options.cdpHeaders);
76-
} catch (error) {
77-
// eslint-disable-next-line no-console
78-
console.error('Invalid JSON format for --cdp-headers:', error);
79-
process.exit(1);
80-
}
81-
}
82-
8372
const config = await resolveCLIConfig(options);
8473

8574
if (options.extension) {

tests/cdp.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ test('cdp server with invalid headers JSON', async () => {
106106
]);
107107
expect(result.error).toBeUndefined();
108108
expect(result.status).toBe(1);
109-
expect(result.stderr.toString()).toContain('Invalid JSON format for --cdp-headers');
109+
expect(result.stderr.toString()).toContain('option \'--cdp-headers <headers>\' argument \'invalid-json\' is invalid');
110110
});
111111

112112
// NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename.

0 commit comments

Comments
 (0)