diff --git a/docs/src/api/class-browsertype.md b/docs/src/api/class-browsertype.md index 25f89d2130..d282912882 100644 --- a/docs/src/api/class-browsertype.md +++ b/docs/src/api/class-browsertype.md @@ -90,38 +90,33 @@ class BrowserTypeExamples This methods attaches Playwright to an existing browser instance. -### param: BrowserType.connect.params -* langs: js -- `params` <[Object]> - - `wsEndpoint` <[string]> A browser websocket endpoint to connect to. - - `headers` <[Object]<[string], [string]>> Additional HTTP headers to be sent with web socket connect request. Optional. - - `slowMo` <[float]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you - can see what is going on. Defaults to 0. - - `logger` <[Logger]> Logger sink for Playwright logging. Optional. - - `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to - `30000` (30 seconds). Pass `0` to disable timeout. - ### param: BrowserType.connect.wsEndpoint -* langs: java, python +* langs: java, python, js - `wsEndpoint` <[string]> A browser websocket endpoint to connect to. ### option: BrowserType.connect.headers -* langs: java, python +* langs: java, python, js - `headers` <[Object]<[string], [string]>> Additional HTTP headers to be sent with web socket connect request. Optional. ### option: BrowserType.connect.slowMo -* langs: java, python +* langs: java, python, js - `slowMo` <[float]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. Defaults to 0. +### option: BrowserType.connect.logger +* langs: js +- `logger` <[Logger]> + +Logger sink for Playwright logging. Optional. + ### option: BrowserType.connect.timeout -* langs: java, python +* langs: java, python, js - `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to @@ -139,38 +134,39 @@ The default browser context is accessible via [`method: Browser.contexts`]. Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers. ::: -### param: BrowserType.connectOverCDP.params -* langs: js -- `params` <[Object]> - - `endpointURL` <[string]> A CDP websocket endpoint or http url to connect to. For example `http://localhost:9222/` or `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`. - - `headers` <[Object]<[string], [string]>> Additional HTTP headers to be sent with connect request. Optional. - - `slowMo` <[float]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you - can see what is going on. Defaults to 0. - - `logger` <[Logger]> Logger sink for Playwright logging. Optional. - - `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to - `30000` (30 seconds). Pass `0` to disable timeout. - ### param: BrowserType.connectOverCDP.endpointURL -* langs: java, python +* langs: java, python, js - `endpointURL` <[string]> A CDP websocket endpoint or http url to connect to. For example `http://localhost:9222/` or `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`. +### option: BrowserType.connectOverCDP.endpointURL +* langs: js +- `endpointURL` <[string]> + +Deprecated, use the first argument instead. Optional. + ### option: BrowserType.connectOverCDP.headers -* langs: java, python +* langs: java, python, js - `headers` <[Object]<[string], [string]>> Additional HTTP headers to be sent with connect request. Optional. ### option: BrowserType.connectOverCDP.slowMo -* langs: java, python +* langs: java, python, js - `slowMo` <[float]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. Defaults to 0. +### option: BrowserType.connectOverCDP.logger +* langs: js +- `logger` <[Logger]> + +Logger sink for Playwright logging. Optional. + ### option: BrowserType.connectOverCDP.timeout -* langs: java, python +* langs: java, python, js - `timeout` <[float]> Maximum time in milliseconds to wait for the connection to be established. Defaults to diff --git a/src/client/browserType.ts b/src/client/browserType.ts index 7bcb977da1..beab7ac261 100644 --- a/src/client/browserType.ts +++ b/src/client/browserType.ts @@ -107,11 +107,19 @@ export class BrowserType extends ChannelOwner { + connect(options: api.ConnectOptions & { wsEndpoint?: string }): Promise; + connect(wsEndpoint: string, options?: api.ConnectOptions): Promise; + async connect(optionsOrWsEndpoint: string|(api.ConnectOptions & { wsEndpoint?: string }), options?: api.ConnectOptions): Promise{ + if (typeof optionsOrWsEndpoint === 'string') + return this._connect(optionsOrWsEndpoint, options); + assert(optionsOrWsEndpoint.wsEndpoint, 'options.wsEndpoint is required'); + return this._connect(optionsOrWsEndpoint.wsEndpoint, optionsOrWsEndpoint); + } + async _connect(wsEndpoint: string, params: Partial = {}): Promise { const logger = params.logger; const paramsHeaders = Object.assign({'User-Agent': getUserAgent()}, params.headers); return this._wrapApiCall(async () => { - const ws = new WebSocket(params.wsEndpoint, [], { + const ws = new WebSocket(wsEndpoint, [], { perMessageDeflate: false, maxPayload: 256 * 1024 * 1024, // 256Mb, handshakeTimeout: this._timeoutSettings.timeout(params), @@ -215,9 +223,17 @@ export class BrowserType extends ChannelOwner - async connectOverCDP(params: api.ConnectOptions): Promise - async connectOverCDP(params: api.ConnectOverCDPOptions | api.ConnectOptions): Promise { + connectOverCDP(options: api.ConnectOverCDPOptions & { wsEndpoint?: string }): Promise; + connectOverCDP(endpointURL: string, options?: api.ConnectOverCDPOptions): Promise; + connectOverCDP(endpointURLOrOptions: (api.ConnectOverCDPOptions & { wsEndpoint?: string })|string, options?: api.ConnectOverCDPOptions) { + if (typeof endpointURLOrOptions === 'string') + return this._connectOverCDP(endpointURLOrOptions, options); + const endpointURL = 'endpointURL' in endpointURLOrOptions ? endpointURLOrOptions.endpointURL : endpointURLOrOptions.wsEndpoint; + assert(endpointURL, 'Cannot connect over CDP without wsEndpoint.'); + return this.connectOverCDP(endpointURL, endpointURLOrOptions); + } + + async _connectOverCDP(endpointURL: string, params: api.ConnectOverCDPOptions = {}): Promise { if (this.name() !== 'chromium') throw new Error('Connecting over CDP is only supported in Chromium.'); const logger = params.logger; @@ -226,7 +242,7 @@ export class BrowserType extends ChannelOwner e)).message).toContain('has been closed'); expect((await page.waitForNavigation().catch(e => e)).message).toContain('Navigation failed because page was closed'); }); + +test('should be able to connect when the wsEndpont is passed as the first argument', async ({browserType, startRemoteServer}) => { + const remoteServer = await startRemoteServer(); + const browser = await browserType.connect(remoteServer.wsEndpoint()); + const page = await browser.newPage(); + expect(await page.evaluate('1 + 2')).toBe(3); + await browser.close(); +}); diff --git a/tests/chromium/chromium.spec.ts b/tests/chromium/chromium.spec.ts index 23e83a2daf..48ebdac696 100644 --- a/tests/chromium/chromium.spec.ts +++ b/tests/chromium/chromium.spec.ts @@ -331,3 +331,19 @@ test('should report an expected error when the endpoint URL JSON webSocketDebugg endpointURL: server.PREFIX, })).rejects.toThrowError('browserType.connectOverCDP: Invalid URL'); }); + +playwrightTest('should connect to an existing cdp session when passed as a first argument', async ({ browserType, browserOptions }, testInfo) => { + const port = 9339 + testInfo.workerIndex; + const browserServer = await browserType.launch({ + ...browserOptions, + args: ['--remote-debugging-port=' + port] + }); + try { + const cdpBrowser = await browserType.connectOverCDP(`http://localhost:${port}/`); + const contexts = cdpBrowser.contexts(); + expect(contexts.length).toBe(1); + await cdpBrowser.close(); + } finally { + await browserServer.close(); + } +}); diff --git a/types/types.d.ts b/types/types.d.ts index ea9f4c7fd4..038adb8265 100644 --- a/types/types.d.ts +++ b/types/types.d.ts @@ -6636,20 +6636,28 @@ export interface BrowserType { * [browser.contexts()](https://playwright.dev/docs/api/class-browser#browser-contexts). * * > NOTE: Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers. - * @param params + * @param endpointURL A CDP websocket endpoint or http url to connect to. For example `http://localhost:9222/` or `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`. + * @param options */ - connectOverCDP(options: ConnectOverCDPOptions): Promise; + connectOverCDP(endpointURL: string, options?: ConnectOverCDPOptions): Promise; /** * Option `wsEndpoint` is deprecated. Instead use `endpointURL`. * @deprecated */ - connectOverCDP(options: ConnectOptions): Promise; + connectOverCDP(options: ConnectOverCDPOptions & { wsEndpoint?: string }): Promise; /** * This methods attaches Playwright to an existing browser instance. - * @param params + * @param wsEndpoint A browser websocket endpoint to connect to. + * @param options */ - connect(params: ConnectOptions): Promise; - + connect(wsEndpoint: string, options?: ConnectOptions): Promise; + /** + * wsEndpoint in options is deprecated. Instead use `wsEndpoint`. + * @param wsEndpoint A browser websocket endpoint to connect to. + * @param options + * @deprecated + */ + connect(options: ConnectOptions & { wsEndpoint?: string }): Promise; /** * A path where Playwright expects to find a bundled browser executable. */ @@ -9020,8 +9028,8 @@ export interface BrowserServer { * Browser websocket url. * * Browser websocket endpoint which can be used as an argument to - * [browserType.connect(params)](https://playwright.dev/docs/api/class-browsertype#browser-type-connect) to establish - * connection to the browser. + * [browserType.connect(wsEndpoint[, options])](https://playwright.dev/docs/api/class-browsertype#browser-type-connect) to + * establish connection to the browser. */ wsEndpoint(): string; } @@ -11196,27 +11204,26 @@ export interface LaunchOptions { export interface ConnectOverCDPOptions { /** - * A CDP websocket endpoint or http url to connect to. For example `http://localhost:9222/` or - * `ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4`. + * Deprecated, use the first argument instead. Optional. */ - endpointURL: string; + endpointURL?: string; /** * Additional HTTP headers to be sent with connect request. Optional. */ headers?: { [key: string]: string; }; + /** + * Logger sink for Playwright logging. Optional. + */ + logger?: Logger; + /** * Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. * Defaults to 0. */ slowMo?: number; - /** - * Logger sink for Playwright logging. Optional. - */ - logger?: Logger; - /** * Maximum time in milliseconds to wait for the connection to be established. Defaults to `30000` (30 seconds). Pass `0` to * disable timeout. @@ -11225,27 +11232,22 @@ export interface ConnectOverCDPOptions { } export interface ConnectOptions { - /** - * A browser websocket endpoint to connect to. - */ - wsEndpoint: string; - /** * Additional HTTP headers to be sent with web socket connect request. Optional. */ headers?: { [key: string]: string; }; + /** + * Logger sink for Playwright logging. Optional. + */ + logger?: Logger; + /** * Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. * Defaults to 0. */ slowMo?: number; - /** - * Logger sink for Playwright logging. Optional. - */ - logger?: Logger; - /** * Maximum time in milliseconds to wait for the connection to be established. Defaults to `30000` (30 seconds). Pass `0` to * disable timeout. diff --git a/utils/generate_types/exported.json b/utils/generate_types/exported.json index fd8584e644..8bc1d72515 100644 --- a/utils/generate_types/exported.json +++ b/utils/generate_types/exported.json @@ -1,7 +1,7 @@ { "BrowserTypeLaunchOptions": "LaunchOptions", - "BrowserTypeConnectParams": "ConnectOptions", - "BrowserTypeConnectOverCDPParams": "ConnectOverCDPOptions", + "BrowserTypeConnectOptions": "ConnectOptions", + "BrowserTypeConnectOverCDPOptions": "ConnectOverCDPOptions", "BrowserContextCookies": "Cookie", "BrowserNewContextOptions": "BrowserContextOptions", "BrowserNewContextOptionsViewport": "ViewportSize", diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 75a76c27e5..831343ab5e 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -141,12 +141,20 @@ export interface ElementHandle extends JSHandle { } export interface BrowserType { - connectOverCDP(options: ConnectOverCDPOptions): Promise; + connectOverCDP(endpointURL: string, options?: ConnectOverCDPOptions): Promise; /** * Option `wsEndpoint` is deprecated. Instead use `endpointURL`. * @deprecated */ - connectOverCDP(options: ConnectOptions): Promise; + connectOverCDP(options: ConnectOverCDPOptions & { wsEndpoint?: string }): Promise; + connect(wsEndpoint: string, options?: ConnectOptions): Promise; + /** + * wsEndpoint in options is deprecated. Instead use `wsEndpoint`. + * @param wsEndpoint A browser websocket endpoint to connect to. + * @param options + * @deprecated + */ + connect(options: ConnectOptions & { wsEndpoint?: string }): Promise; } export interface CDPSession {