Skip to content

Commit 1913cc7

Browse files
committed
cleanups
1 parent 6679996 commit 1913cc7

File tree

13 files changed

+61
-99
lines changed

13 files changed

+61
-99
lines changed

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,6 @@ Playwright MCP server supports following arguments. They can be provided in the
188188
example "1280, 720"
189189
--vision Run server that uses screenshots (Aria snapshots
190190
are used by default)
191-
--extension Allow connecting to a running browser instance
192-
(Edge/Chrome only). Requires the 'Playwright MCP'
193-
browser extension to be installed.
194191
```
195192

196193
<!--- End of options generated section -->

config.d.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,6 @@ export type Config = {
104104
*/
105105
saveTrace?: boolean;
106106

107-
/**
108-
* Run server that is able to connect to the 'Playwright MCP' Chrome extension.
109-
*/
110-
extension?: boolean;
111-
112107
/**
113108
* The directory to save output files.
114109
*/

extension/background.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
function debugLog(...args) {
8-
const enabled = true;
8+
const enabled = false;
99
if (enabled) {
1010
console.log('[Extension]', ...args);
1111
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"ctest": "playwright test --project=chrome",
2525
"ftest": "playwright test --project=firefox",
2626
"wtest": "playwright test --project=webkit",
27+
"etest": "playwright test --project=chromium-extension",
2728
"run-server": "node lib/browserServer.js",
2829
"clean": "rm -rf lib",
2930
"npm-publish": "npm run clean && npm run build && npm run test && npm publish"

src/browserContextFactory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ import type { BrowserInfo, LaunchBrowserRequest } from './browserServer.js';
2828

2929
const testDebug = debug('pw:mcp:test');
3030

31-
export function contextFactory(browserConfig: FullConfig['browser']): BrowserContextFactory {
31+
export function contextFactory(browserConfig: FullConfig['browser'], { forceCdp }: { forceCdp?: boolean } = {}): BrowserContextFactory {
3232
if (browserConfig.remoteEndpoint)
3333
return new RemoteContextFactory(browserConfig);
34-
if (browserConfig.cdpEndpoint)
34+
if (browserConfig.cdpEndpoint || forceCdp)
3535
return new CdpContextFactory(browserConfig);
3636
if (browserConfig.isolated)
3737
return new IsolatedContextFactory(browserConfig);

src/cdp-relay.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ export class CDPBridgeServer extends EventEmitter {
3838
sessionId: string;
3939
} | undefined;
4040

41-
public readonly CDP_PATH = '/cdp';
42-
public readonly EXTENSION_PATH = '/extension';
41+
public static readonly CDP_PATH = '/cdp';
42+
public static readonly EXTENSION_PATH = '/extension';
4343

4444
constructor(server: http.Server) {
4545
super();
@@ -57,9 +57,9 @@ export class CDPBridgeServer extends EventEmitter {
5757

5858
debugLogger(`New connection to ${url.pathname}`);
5959

60-
if (url.pathname === this.CDP_PATH) {
60+
if (url.pathname === CDPBridgeServer.CDP_PATH) {
6161
this._handlePlaywrightConnection(ws);
62-
} else if (url.pathname === this.EXTENSION_PATH) {
62+
} else if (url.pathname === CDPBridgeServer.EXTENSION_PATH) {
6363
this._handleExtensionConnection(ws);
6464
} else {
6565
debugLogger(`Invalid path: ${url.pathname}`);
@@ -293,8 +293,8 @@ if (import.meta.url === `file://${process.argv[1]}`) {
293293
const server = new CDPBridgeServer(httpServer);
294294

295295
console.error(`CDP Bridge Server listening on ws://localhost:${port}`);
296-
console.error(`- Playwright MCP: ws://localhost:${port}${server.CDP_PATH}`);
297-
console.error(`- Extension: ws://localhost:${port}${server.EXTENSION_PATH}`);
296+
console.error(`- Playwright MCP: ws://localhost:${port}${CDPBridgeServer.CDP_PATH}`);
297+
console.error(`- Extension: ws://localhost:${port}${CDPBridgeServer.EXTENSION_PATH}`);
298298

299299
process.on('SIGINT', () => {
300300
debugLogger('\nShutting down bridge server...');

src/config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,18 @@ import os from 'os';
1919
import path from 'path';
2020
import { devices } from 'playwright';
2121

22-
import type { Config, ToolCapability } from '../config.js';
22+
import type { Config as PublicConfig, ToolCapability } from '../config.js';
2323
import type { BrowserContextOptions, LaunchOptions } from 'playwright';
2424
import { sanitizeForFilePath } from './tools/utils.js';
2525

26+
type Config = PublicConfig & {
27+
/**
28+
* TODO: Move to PublicConfig once we are ready to release this feature.
29+
* Run server that is able to connect to the 'Playwright MCP' Chrome extension.
30+
*/
31+
extension?: boolean;
32+
};
33+
2634
export type CLIOptions = {
2735
allowedOrigins?: string[];
2836
blockedOrigins?: string[];

src/program.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@
1515
*/
1616

1717
import type http from 'http';
18-
import { program } from 'commander';
18+
import { Option, program } from 'commander';
1919
// @ts-ignore
2020
import { startTraceViewerServer } from 'playwright-core/lib/server';
2121

22-
import { startHttpTransport, startStdioTransport } from './transport.js';
22+
import { httpAddressToString, startHttpTransport, startStdioTransport } from './transport.js';
2323
import { resolveCLIConfig } from './config.js';
2424
import { Server } from './server.js';
2525
import { packageJSON } from './package.js';
2626
import { CDPBridgeServer } from './cdp-relay.js';
27-
import { AddressInfo } from 'net';
2827

2928
program
3029
.version('Version ' + packageJSON.version)
@@ -55,14 +54,10 @@ program
5554
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
5655
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
5756
.option('--vision', 'Run server that uses screenshots (Aria snapshots are used by default)')
58-
.option('--extension', 'Allow connecting to a running browser instance (Edge/Chrome only). Requires the \'Playwright MCP\' browser extension to be installed.')
57+
.addOption(new Option('--extension', 'Allow connecting to a running browser instance (Edge/Chrome only). Requires the \'Playwright MCP\' browser extension to be installed.').hideHelp())
5958
.action(async options => {
6059
const config = await resolveCLIConfig(options);
61-
if (config.extension)
62-
// TODO: The issue is that inside 'new Server' we create the ContextFactory
63-
// instances based on if there is a CDP address given.
64-
config.browser.cdpEndpoint = '1';
65-
const server = new Server(config);
60+
const server = new Server(config, { forceCdp: !!config.extension });
6661
server.setupExitWatchdog();
6762

6863
let httpServer: http.Server | undefined = undefined;
@@ -79,12 +74,12 @@ program
7974
console.error('\nTrace viewer listening on ' + url);
8075
}
8176
if (config.extension && httpServer) {
82-
config.browser.cdpEndpoint = `ws://127.0.0.1:${(httpServer.address() as AddressInfo).port}/cdp`;
77+
const wsAddress = httpAddressToString(httpServer.address()).replace('http', 'ws');
78+
config.browser.cdpEndpoint = `${wsAddress}${CDPBridgeServer.CDP_PATH}`;
8379
const cdpRelayServer = new CDPBridgeServer(httpServer);
84-
// TODO: use watchdog to stop the server on exit
8580
process.on('exit', () => cdpRelayServer.stop());
8681
// eslint-disable-next-line no-console
87-
console.error(`CDP relay server started on ws://127.0.0.1:${(httpServer.address() as AddressInfo).port}/extension - Connect to it using the browser extension.`);
82+
console.error(`CDP relay server started on ${wsAddress}${CDPBridgeServer.EXTENSION_PATH} - Connect to it using the browser extension.`);
8883
}
8984
});
9085

src/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ export class Server {
2828
private _browserConfig: FullConfig['browser'];
2929
private _contextFactory: BrowserContextFactory;
3030

31-
constructor(config: FullConfig) {
31+
constructor(config: FullConfig, { forceCdp }: { forceCdp: boolean }) {
3232
this.config = config;
3333
this._browserConfig = config.browser;
34-
this._contextFactory = contextFactory(this._browserConfig);
34+
this._contextFactory = contextFactory(this._browserConfig, { forceCdp });
3535
}
3636

3737
async createConnection(transport: Transport): Promise<Connection> {

src/transport.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import http from 'node:http';
18+
import type { AddressInfo } from 'node:net';
1819
import assert from 'node:assert';
1920
import crypto from 'node:crypto';
2021

@@ -108,18 +109,7 @@ export async function startHttpTransport(server: Server): Promise<http.Server> {
108109
});
109110
const { host, port } = server.config.server;
110111
await new Promise<void>(resolve => httpServer.listen(port, host, resolve));
111-
const address = httpServer.address();
112-
assert(address, 'Could not bind server socket');
113-
let url: string;
114-
if (typeof address === 'string') {
115-
url = address;
116-
} else {
117-
const resolvedPort = address.port;
118-
let resolvedHost = address.family === 'IPv4' ? address.address : `[${address.address}]`;
119-
if (resolvedHost === '0.0.0.0' || resolvedHost === '[::]')
120-
resolvedHost = 'localhost';
121-
url = `http://${resolvedHost}:${resolvedPort}`;
122-
}
112+
const url = httpAddressToString(httpServer.address());
123113
const message = [
124114
`Listening on ${url}`,
125115
'Put this in your client config:',
@@ -136,3 +126,14 @@ export async function startHttpTransport(server: Server): Promise<http.Server> {
136126
console.error(message);
137127
return httpServer;
138128
}
129+
130+
export function httpAddressToString(address: string | AddressInfo | null): string {
131+
assert(address, 'Could not bind server socket');
132+
if (typeof address === 'string')
133+
return address;
134+
const resolvedPort = address.port;
135+
let resolvedHost = address.family === 'IPv4' ? address.address : `[${address.address}]`;
136+
if (resolvedHost === '0.0.0.0' || resolvedHost === '[::]')
137+
resolvedHost = 'localhost';
138+
return `http://${resolvedHost}:${resolvedPort}`;
139+
}

0 commit comments

Comments
 (0)