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
1 change: 0 additions & 1 deletion packages/isomorphic/protocolMetainfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ export const methodMetainfo = new Map<string, MethodMetainfo>([
['BrowserType.launch', { title: 'Launch browser', }],
['BrowserType.launchPersistentContext', { title: 'Launch persistent context', }],
['BrowserType.connectOverCDP', { title: 'Connect over CDP', }],
['BrowserType.connectOverCDPTransport', { title: 'Connect over CDP transport', }],
['BrowserType.connectToWorker', { title: 'Connect to worker', }],
['Disposable.dispose', { internal: true, potentiallyClosesScope: true, }],
['Electron.launch', { title: 'Launch electron', }],
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-client/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15439,7 +15439,8 @@ export interface BrowserType<Unused = {}> {
* `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`.
* @param options
*/
connectOverCDP(transport: ConnectionTransport): Promise<Browser>;
connectOverCDP(transport: ConnectionTransport, options?: ConnectOverCDPOptions): Promise<Browser>;

/**
* This method attaches Playwright to an existing browser instance created via `BrowserType.launchServer` in Node.js.
*
Expand Down
48 changes: 24 additions & 24 deletions packages/playwright-core/src/client/browserType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,24 +138,33 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple

async connectOverCDP(options: api.ConnectOverCDPOptions & { wsEndpoint?: string }): Promise<api.Browser>;
async connectOverCDP(endpointURL: string, options?: api.ConnectOverCDPOptions): Promise<api.Browser>;
async connectOverCDP(transport: api.ConnectionTransport): Promise<api.Browser>;
async connectOverCDP(endpointURLOrOptions: (api.ConnectOverCDPOptions & { wsEndpoint?: string })|string|api.ConnectionTransport, options?: api.ConnectOverCDPOptions) {
if (typeof endpointURLOrOptions === 'string')
return await this._connectOverCDP(endpointURLOrOptions, options);
if (isConnectionTransport(endpointURLOrOptions))
return await this._connectOverCDPTransport(endpointURLOrOptions);
const endpointURL = 'endpointURL' in endpointURLOrOptions ? endpointURLOrOptions.endpointURL : endpointURLOrOptions.wsEndpoint;
assert(endpointURL, 'Cannot connect over CDP without wsEndpoint.');
return await this._connectOverCDP(endpointURL, endpointURLOrOptions);
}

async _connectOverCDP(endpointURL: string, params: api.ConnectOverCDPOptions = {}): Promise<Browser> {
if (this.name() !== 'chromium' && this.name() !== 'webkit')
async connectOverCDP(transport: api.ConnectionTransport, options?: api.ConnectOverCDPOptions): Promise<api.Browser>;
async connectOverCDP(overloaded: (api.ConnectOverCDPOptions & { wsEndpoint?: string }) | string | api.ConnectionTransport, options?: api.ConnectOverCDPOptions): Promise<Browser> {
let endpointURL: string | undefined;
let transport: api.ConnectionTransport | undefined;
let params: api.ConnectOverCDPOptions;
if (typeof overloaded === 'string') {
endpointURL = overloaded;
params = options ?? {};
} else if (isConnectionTransport(overloaded)) {
if (this.name() !== 'chromium' && this.name() !== 'webkit')
throw new Error('Connecting over CDP is only supported in Chromium and WebKit.');
if (this._connection.isRemote())
throw new Error('Passing a ConnectionTransport to connectOverCDP is not supported when connecting remotely.');
transport = overloaded;
params = options ?? {};
} else {
endpointURL = 'endpointURL' in overloaded ? (overloaded as any).endpointURL : overloaded.wsEndpoint;
assert(endpointURL, 'Cannot connect over CDP without wsEndpoint.');
params = overloaded;
}
if (endpointURL && this.name() !== 'chromium' && this.name() !== 'webkit')
throw new Error('Connecting over CDP is only supported in Chromium and WebKit.');
const headers = params.headers ? headersObjectToArray(params.headers) : undefined;

const result = await this._channel.connectOverCDP({
endpointURL,
headers,
transport: transport as any,
headers: params.headers ? headersObjectToArray(params.headers) : undefined,
slowMo: params.slowMo,
timeout: new TimeoutSettings(this._platform).timeout(params),
isLocal: params.isLocal,
Expand All @@ -165,15 +174,6 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
return await this._browserFromConnectResult(result);
}

async _connectOverCDPTransport(transport: api.ConnectionTransport): Promise<Browser> {
if (this.name() !== 'chromium')
throw new Error('Connecting over CDP is only supported in Chromium.');
if (this._connection.isRemote())
throw new Error('Passing a ConnectionTransport to connectOverCDP is not supported when connecting remotely.');
const result = await this._channel.connectOverCDPTransport({ transport: transport as any });
return await this._browserFromConnectResult(result);
}

private async _browserFromConnectResult(result: { browser: channels.BrowserChannel, defaultContext?: channels.BrowserContextChannel }): Promise<Browser> {
const browser = Browser.from(result.browser);
browser._connectToBrowserType(this, {}, undefined);
Expand Down
10 changes: 2 additions & 8 deletions packages/playwright-core/src/protocol/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1087,25 +1087,19 @@ scheme.BrowserTypeLaunchPersistentContextResult = tObject({
context: tChannel(['BrowserContext']),
});
scheme.BrowserTypeConnectOverCDPParams = tObject({
endpointURL: tString,
endpointURL: tOptional(tString),
headers: tOptional(tArray(tType('NameValue'))),
slowMo: tOptional(tFloat),
timeout: tFloat,
isLocal: tOptional(tBoolean),
noDefaults: tOptional(tBoolean),
artifactsDir: tOptional(tString),
transport: tOptional(tBinary),
});
scheme.BrowserTypeConnectOverCDPResult = tObject({
browser: tChannel(['Browser']),
defaultContext: tOptional(tChannel(['BrowserContext'])),
});
scheme.BrowserTypeConnectOverCDPTransportParams = tObject({
transport: tBinary,
});
scheme.BrowserTypeConnectOverCDPTransportResult = tObject({
browser: tChannel(['Browser']),
defaultContext: tOptional(tChannel(['BrowserContext'])),
});
scheme.BrowserTypeConnectToWorkerParams = tObject({
endpoint: tString,
timeout: tFloat,
Expand Down
6 changes: 1 addition & 5 deletions packages/playwright-core/src/server/browserType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,7 @@ export abstract class BrowserType extends SdkObject {
}
}

async connectOverCDP(progress: Progress, endpointURL: string, options: { slowMo?: number, timeout?: number, headers?: types.HeadersArray, isLocal?: boolean, noDefaults?: boolean, artifactsDir?: string }): Promise<Browser> {
throw new Error('CDP connections are only supported by Chromium');
}

async connectOverCDPTransport(progress: Progress, transport: ConnectionTransport): Promise<Browser> {
async connectOverCDP(progress: Progress, params: channels.BrowserTypeConnectOverCDPParams): Promise<Browser> {
throw new Error('CDP connections are only supported by Chromium');
}

Expand Down
11 changes: 4 additions & 7 deletions packages/playwright-core/src/server/chromium/chromium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ export class Chromium extends BrowserType {
return super.launchPersistentContext(progress, userDataDir, options);
}

override async connectOverCDP(progress: Progress, endpointURL: string, options: { slowMo?: number, headers?: types.HeadersArray, isLocal?: boolean, noDefaults?: boolean, artifactsDir?: string }) {
return await this._connectOverCDPInternal(progress, endpointURL, options);
override async connectOverCDP(progress: Progress, params: channels.BrowserTypeConnectOverCDPParams) {
if (params.transport)
return this._connectOverCDPImpl(progress, params.transport as any, async () => (params.transport as any).close(), { ...params, isLocal: true });
return await this._connectOverCDPInternal(progress, params.endpointURL!, params);
}

async _connectOverCDPInternal(progress: Progress, endpointURL: string, options: types.LaunchOptions & { headers?: types.HeadersArray, isLocal?: boolean, noDefaults?: boolean, artifactsDir?: string }, onClose?: () => Promise<void>) {
Expand Down Expand Up @@ -166,11 +168,6 @@ export class Chromium extends BrowserType {
}
}

override async connectOverCDPTransport(progress: Progress, transport: ConnectionTransport) {
const closeAndWait = async () => transport.close();
return this._connectOverCDPImpl(progress, transport, closeAndWait, { isLocal: true });
}

override async connectToWorker(progress: Progress, endpoint: string) {
const wsEndpoint = await urlToWSEndpoint(progress, endpoint, {});
const transport = await WebSocketTransport.connect(progress, wsEndpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,14 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, channels.Brow
if (this._denyLaunch)
throw new Error(`Launching more browsers is not allowed.`);

const browser = await this._object.connectOverCDP(progress, params.endpointURL, params);
const browser = await this._object.connectOverCDP(progress, params);
const browserDispatcher = new BrowserDispatcher(this, browser);
return {
browser: browserDispatcher,
defaultContext: browser._defaultContext ? BrowserContextDispatcher.from(browserDispatcher, browser._defaultContext) : undefined,
};
}

async connectOverCDPTransport(params: channels.BrowserTypeConnectOverCDPTransportParams, progress: Progress): Promise<channels.BrowserTypeConnectOverCDPTransportResult> {
if (this._denyLaunch)
throw new Error(`Launching more browsers is not allowed.`);

const browser = await this._object.connectOverCDPTransport(progress, params.transport as any);
const browserDispatcher = new BrowserDispatcher(this, browser);
return { browser: browserDispatcher, defaultContext: browser._defaultContext ? BrowserContextDispatcher.from(browserDispatcher, browser._defaultContext) : undefined };
}

async connectToWorker(params: channels.BrowserTypeConnectToWorkerParams, progress: Progress): Promise<channels.BrowserTypeConnectToWorkerResult> {
if (this._denyLaunch)
throw new Error(`Launching more browsers is not allowed.`);
Expand Down
5 changes: 3 additions & 2 deletions packages/playwright-core/src/server/webkit/webkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type { SdkObject } from '../instrumentation';
import type { Progress } from '../progress';
import type { ConnectionTransport } from '../transport';
import type * as types from '../types';
import type * as channels from '@protocol/channels';

export class WebKit extends BrowserType {
constructor(parent: SdkObject) {
Expand All @@ -40,8 +41,8 @@ export class WebKit extends BrowserType {
return WKBrowser.connect(this.attribution.playwright, transport, options);
}

override async connectOverCDP(progress: Progress, endpointURL: string, options: { slowMo?: number, headers?: types.HeadersArray, isLocal?: boolean, noDefaults?: boolean }): Promise<Browser> {
return connectOverRDP(progress, this, endpointURL, options);
override async connectOverCDP(progress: Progress, params: channels.BrowserTypeConnectOverCDPParams): Promise<Browser> {
return connectOverRDP(progress, this, params.endpointURL!, params);
}

override amendEnvironment(env: NodeJS.ProcessEnv, userDataDir: string, isPersistent: boolean, options: types.LaunchOptions): NodeJS.ProcessEnv {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15439,7 +15439,8 @@ export interface BrowserType<Unused = {}> {
* `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`.
* @param options
*/
connectOverCDP(transport: ConnectionTransport): Promise<Browser>;
connectOverCDP(transport: ConnectionTransport, options?: ConnectOverCDPOptions): Promise<Browser>;

/**
* This method attaches Playwright to an existing browser instance created via `BrowserType.launchServer` in Node.js.
*
Expand Down
11 changes: 2 additions & 9 deletions packages/protocol/spec/browserType.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ BrowserType:
connectOverCDP:
title: Connect over CDP
parameters:
endpointURL: string
endpointURL: string?
headers:
type: array?
items: NameValue
Expand All @@ -52,14 +52,7 @@ BrowserType:
isLocal: boolean?
noDefaults: boolean?
artifactsDir: string?
returns:
browser: Browser
defaultContext: BrowserContext?

connectOverCDPTransport:
title: Connect over CDP transport
parameters:
transport: binary
transport: binary?
returns:
browser: Browser
defaultContext: BrowserContext?
Expand Down
16 changes: 4 additions & 12 deletions packages/protocol/src/channels.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1822,7 +1822,6 @@ export interface BrowserTypeChannel extends BrowserTypeEventTarget, Channel {
launch(params: BrowserTypeLaunchParams, progress?: Progress): Promise<BrowserTypeLaunchResult>;
launchPersistentContext(params: BrowserTypeLaunchPersistentContextParams, progress?: Progress): Promise<BrowserTypeLaunchPersistentContextResult>;
connectOverCDP(params: BrowserTypeConnectOverCDPParams, progress?: Progress): Promise<BrowserTypeConnectOverCDPResult>;
connectOverCDPTransport(params: BrowserTypeConnectOverCDPTransportParams, progress?: Progress): Promise<BrowserTypeConnectOverCDPTransportResult>;
connectToWorker(params: BrowserTypeConnectToWorkerParams, progress?: Progress): Promise<BrowserTypeConnectToWorkerResult>;
}
export type BrowserTypeLaunchParams = {
Expand Down Expand Up @@ -2060,35 +2059,28 @@ export type BrowserTypeLaunchPersistentContextResult = {
context: BrowserContextChannel,
};
export type BrowserTypeConnectOverCDPParams = {
endpointURL: string,
endpointURL?: string,
headers?: NameValue[],
slowMo?: number,
timeout: number,
isLocal?: boolean,
noDefaults?: boolean,
artifactsDir?: string,
transport?: Binary,
};
export type BrowserTypeConnectOverCDPOptions = {
endpointURL?: string,
headers?: NameValue[],
slowMo?: number,
isLocal?: boolean,
noDefaults?: boolean,
artifactsDir?: string,
transport?: Binary,
};
export type BrowserTypeConnectOverCDPResult = {
browser: BrowserChannel,
defaultContext?: BrowserContextChannel,
};
export type BrowserTypeConnectOverCDPTransportParams = {
transport: Binary,
};
export type BrowserTypeConnectOverCDPTransportOptions = {

};
export type BrowserTypeConnectOverCDPTransportResult = {
browser: BrowserChannel,
defaultContext?: BrowserContextChannel,
};
export type BrowserTypeConnectToWorkerParams = {
endpoint: string,
timeout: number,
Expand Down
4 changes: 2 additions & 2 deletions tests/library/browsertype-basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ test('browserType.name should work', async ({ browserType, browserName }) => {
});

test('should throw when trying to connect with not-chromium', async ({ browserType, browserName }) => {
test.skip(browserName === 'chromium');
test.skip(browserName === 'chromium' || browserName === 'webkit');

const error = await browserType.connectOverCDP({ endpointURL: 'ws://foo' }).catch(e => e);
expect(error.message).toBe('Connecting over CDP is only supported in Chromium.');
expect(error.message).toBe('Connecting over CDP is only supported in Chromium and WebKit.');
});
24 changes: 12 additions & 12 deletions tests/playwright-test/stable-test-runner/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/playwright-test/stable-test-runner/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"dependencies": {
"@playwright/test": "^1.61.0-alpha-2026-05-18"
"@playwright/test": "^1.61.0-alpha-2026-05-27"
}
}
3 changes: 2 additions & 1 deletion utils/generate_types/overrides.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ export interface BrowserType<Unused = {}> {
* @deprecated
*/
connectOverCDP(options: ConnectOverCDPOptions & { wsEndpoint?: string }): Promise<Browser>;
connectOverCDP(transport: ConnectionTransport): Promise<Browser>;
connectOverCDP(transport: ConnectionTransport, options?: ConnectOverCDPOptions): Promise<Browser>;

connect(wsEndpoint: string, options?: ConnectOptions): Promise<Browser>;
/**
* wsEndpoint in options is deprecated. Instead use `wsEndpoint`.
Expand Down
Loading