feat(cdp): replace wsEndpoint with protocol neutral endpointURL (#6141)
This commit is contained in:
parent
53d50f9b72
commit
63d0d466e3
|
|
@ -116,7 +116,7 @@ Connecting over the Chrome DevTools Protocol is only supported for Chromium-base
|
|||
### param: BrowserType.connectOverCDP.params
|
||||
* langs: js
|
||||
- `params` <[Object]>
|
||||
- `wsEndpoint` <[string]> A CDP websocket endpoint to connect to.
|
||||
- `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`.
|
||||
- `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.
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@ page.navigate("https://www.w3.org/");
|
|||
playwright.close();
|
||||
```
|
||||
|
||||
### param: BrowserType.connectOverCDP.wsEndpoint
|
||||
### param: BrowserType.connectOverCDP.endpointURL
|
||||
* langs: java
|
||||
- `wsEndpoint` <[string]>
|
||||
- `endpointURL` <[string]>
|
||||
|
||||
A CDP websocket endpoint to connect to.
|
||||
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: BrowserContext.waitForPage.callback = %%-java-wait-for-event-callback-%%
|
||||
|
||||
|
|
|
|||
|
|
@ -187,14 +187,16 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
|
|||
}, logger);
|
||||
}
|
||||
|
||||
async connectOverCDP(params: ConnectOptions): Promise<Browser> {
|
||||
async connectOverCDP(params: api.ConnectOverCDPOptions): Promise<Browser>
|
||||
async connectOverCDP(params: api.ConnectOptions): Promise<Browser>
|
||||
async connectOverCDP(params: api.ConnectOverCDPOptions | api.ConnectOptions): Promise<Browser> {
|
||||
if (this.name() !== 'chromium')
|
||||
throw new Error('Connecting over CDP is only supported in Chromium.');
|
||||
const logger = params.logger;
|
||||
return this._wrapApiCall('browserType.connectOverCDP', async (channel: channels.BrowserTypeChannel) => {
|
||||
const result = await channel.connectOverCDP({
|
||||
sdkLanguage: 'javascript',
|
||||
wsEndpoint: params.wsEndpoint,
|
||||
endpointURL: 'endpointURL' in params ? params.endpointURL : params.wsEndpoint,
|
||||
slowMo: params.slowMo,
|
||||
timeout: params.timeout
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, channels.Brow
|
|||
}
|
||||
|
||||
async connectOverCDP(params: channels.BrowserTypeConnectOverCDPParams, metadata: CallMetadata): Promise<channels.BrowserTypeConnectOverCDPResult> {
|
||||
const browser = await this._object.connectOverCDP(metadata, params.wsEndpoint, params, params.timeout);
|
||||
const browser = await this._object.connectOverCDP(metadata, params.endpointURL, params, params.timeout);
|
||||
return {
|
||||
browser: new BrowserDispatcher(this._scope, browser),
|
||||
defaultContext: browser._defaultContext ? new BrowserContextDispatcher(this._scope, browser._defaultContext) : undefined,
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ export type BrowserTypeLaunchPersistentContextResult = {
|
|||
};
|
||||
export type BrowserTypeConnectOverCDPParams = {
|
||||
sdkLanguage: string,
|
||||
wsEndpoint: string,
|
||||
endpointURL: string,
|
||||
slowMo?: number,
|
||||
timeout?: number,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ BrowserType:
|
|||
connectOverCDP:
|
||||
parameters:
|
||||
sdkLanguage: string
|
||||
wsEndpoint: string
|
||||
endpointURL: string
|
||||
slowMo: number?
|
||||
timeout: number?
|
||||
returns:
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
|||
});
|
||||
scheme.BrowserTypeConnectOverCDPParams = tObject({
|
||||
sdkLanguage: tString,
|
||||
wsEndpoint: tString,
|
||||
endpointURL: tString,
|
||||
slowMo: tOptional(tNumber),
|
||||
timeout: tOptional(tNumber),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ export abstract class BrowserType extends SdkObject {
|
|||
return { browserProcess, downloadsPath, transport };
|
||||
}
|
||||
|
||||
async connectOverCDP(metadata: CallMetadata, wsEndpoint: string, options: { slowMo?: number, sdkLanguage: string }, timeout?: number): Promise<Browser> {
|
||||
async connectOverCDP(metadata: CallMetadata, endpointURL: string, options: { slowMo?: number, sdkLanguage: string }, timeout?: number): Promise<Browser> {
|
||||
throw new Error('CDP connections are only supported by Chromium');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import { TimeoutSettings } from '../../utils/timeoutSettings';
|
|||
import { helper } from '../helper';
|
||||
import { CallMetadata } from '../instrumentation';
|
||||
import { findChromiumChannel } from './findChromiumChannel';
|
||||
import http from 'http';
|
||||
|
||||
export class Chromium extends BrowserType {
|
||||
private _devtools: CRDevTools | undefined;
|
||||
|
|
@ -49,12 +50,12 @@ export class Chromium extends BrowserType {
|
|||
return super.executablePath(options);
|
||||
}
|
||||
|
||||
async connectOverCDP(metadata: CallMetadata, wsEndpoint: string, options: { slowMo?: number, sdkLanguage: string }, timeout?: number) {
|
||||
async connectOverCDP(metadata: CallMetadata, endpointURL: string, options: { slowMo?: number, sdkLanguage: string }, timeout?: number) {
|
||||
const controller = new ProgressController(metadata, this);
|
||||
controller.setLogName('browser');
|
||||
const browserLogsCollector = new RecentLogsCollector();
|
||||
return controller.run(async progress => {
|
||||
const chromeTransport = await WebSocketTransport.connect(progress, wsEndpoint);
|
||||
const chromeTransport = await WebSocketTransport.connect(progress, await urlToWSEndpoint(endpointURL));
|
||||
const browserProcess: BrowserProcess = {
|
||||
close: async () => {
|
||||
await chromeTransport.closeAndWait();
|
||||
|
|
@ -192,3 +193,17 @@ const DEFAULT_ARGS = [
|
|||
'--password-store=basic',
|
||||
'--use-mock-keychain',
|
||||
];
|
||||
|
||||
async function urlToWSEndpoint(endpointURL: string) {
|
||||
if (endpointURL.startsWith('ws'))
|
||||
return endpointURL;
|
||||
const httpURL = endpointURL.endsWith('/') ? `${endpointURL}json/version/` : `${endpointURL}/json/version/`;
|
||||
const json = await new Promise<string>((resolve, reject) => {
|
||||
http.get(httpURL, resp => {
|
||||
let data = '';
|
||||
resp.on('data', chunk => data += chunk);
|
||||
resp.on('end', () => resolve(data));
|
||||
}).on('error', reject);
|
||||
});
|
||||
return JSON.parse(json).webSocketDebuggerUrl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ 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');
|
||||
|
||||
const error = await browserType.connectOverCDP({wsEndpoint: 'foo'}).catch(e => e);
|
||||
const error = await browserType.connectOverCDP({endpointURL: 'ws://foo'}).catch(e => e);
|
||||
expect(error.message).toBe('Connecting over CDP is only supported in Chromium.');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -112,15 +112,8 @@ playwrightTest.describe('chromium', () => {
|
|||
args: ['--remote-debugging-port=' + port]
|
||||
});
|
||||
try {
|
||||
const json = await new Promise<string>((resolve, reject) => {
|
||||
http.get(`http://localhost:${port}/json/version/`, resp => {
|
||||
let data = '';
|
||||
resp.on('data', chunk => data += chunk);
|
||||
resp.on('end', () => resolve(data));
|
||||
}).on('error', reject);
|
||||
});
|
||||
const cdpBrowser = await browserType.connectOverCDP({
|
||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
||||
endpointURL: `http://localhost:${port}/`,
|
||||
});
|
||||
const contexts = cdpBrowser.contexts();
|
||||
expect(contexts.length).toBe(1);
|
||||
|
|
@ -137,18 +130,11 @@ playwrightTest.describe('chromium', () => {
|
|||
args: ['--remote-debugging-port=' + port]
|
||||
});
|
||||
try {
|
||||
const json = await new Promise<string>((resolve, reject) => {
|
||||
http.get(`http://localhost:${port}/json/version/`, resp => {
|
||||
let data = '';
|
||||
resp.on('data', chunk => data += chunk);
|
||||
resp.on('end', () => resolve(data));
|
||||
}).on('error', reject);
|
||||
});
|
||||
const cdpBrowser1 = await browserType.connectOverCDP({
|
||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
||||
endpointURL: `http://localhost:${port}/`,
|
||||
});
|
||||
const cdpBrowser2 = await browserType.connectOverCDP({
|
||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
||||
endpointURL: `http://localhost:${port}/`,
|
||||
});
|
||||
const contexts1 = cdpBrowser1.contexts();
|
||||
expect(contexts1.length).toBe(1);
|
||||
|
|
@ -179,15 +165,8 @@ playwrightTest.describe('chromium', () => {
|
|||
args: ['--remote-debugging-port=' + port]
|
||||
});
|
||||
try {
|
||||
const json = await new Promise<string>((resolve, reject) => {
|
||||
http.get(`http://localhost:${port}/json/version/`, resp => {
|
||||
let data = '';
|
||||
resp.on('data', chunk => data += chunk);
|
||||
resp.on('end', () => resolve(data));
|
||||
}).on('error', reject);
|
||||
});
|
||||
const cdpBrowser1 = await browserType.connectOverCDP({
|
||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
||||
endpointURL: `http://localhost:${port}`,
|
||||
});
|
||||
const context = cdpBrowser1.contexts()[0];
|
||||
const page = await cdpBrowser1.contexts()[0].newPage();
|
||||
|
|
@ -199,7 +178,7 @@ playwrightTest.describe('chromium', () => {
|
|||
await cdpBrowser1.close();
|
||||
|
||||
const cdpBrowser2 = await browserType.connectOverCDP({
|
||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
||||
endpointURL: `http://localhost:${port}`,
|
||||
});
|
||||
const context2 = cdpBrowser2.contexts()[0];
|
||||
expect(context2.serviceWorkers().length).toBe(1);
|
||||
|
|
@ -208,4 +187,36 @@ playwrightTest.describe('chromium', () => {
|
|||
await browserServer.close();
|
||||
}
|
||||
});
|
||||
playwrightTest('should connect over a ws endpoint', async ({browserType, browserOptions, server}, testInfo) => {
|
||||
const port = 9339 + testInfo.workerIndex;
|
||||
const browserServer = await browserType.launch({
|
||||
...browserOptions,
|
||||
args: ['--remote-debugging-port=' + port]
|
||||
});
|
||||
try {
|
||||
const json = await new Promise<string>((resolve, reject) => {
|
||||
http.get(`http://localhost:${port}/json/version/`, resp => {
|
||||
let data = '';
|
||||
resp.on('data', chunk => data += chunk);
|
||||
resp.on('end', () => resolve(data));
|
||||
}).on('error', reject);
|
||||
});
|
||||
const cdpBrowser = await browserType.connectOverCDP({
|
||||
endpointURL: JSON.parse(json).webSocketDebuggerUrl,
|
||||
});
|
||||
const contexts = cdpBrowser.contexts();
|
||||
expect(contexts.length).toBe(1);
|
||||
await cdpBrowser.close();
|
||||
|
||||
// also connect with the depercreated wsEndpoint option
|
||||
const cdpBrowser2 = await browserType.connectOverCDP({
|
||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
||||
});
|
||||
const contexts2 = cdpBrowser.contexts();
|
||||
expect(contexts2.length).toBe(1);
|
||||
await cdpBrowser2.close();
|
||||
} finally {
|
||||
await browserServer.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6460,13 +6460,6 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
|||
*
|
||||
*/
|
||||
export interface BrowserType<Unused = {}> {
|
||||
|
||||
/**
|
||||
* This methods attaches Playwright to an existing browser instance.
|
||||
* @param params
|
||||
*/
|
||||
connect(params: ConnectOptions): Promise<Browser>;
|
||||
|
||||
/**
|
||||
* This methods attaches Playwright to an existing browser instance using the Chrome DevTools Protocol.
|
||||
*
|
||||
|
|
@ -6476,29 +6469,17 @@ export interface BrowserType<Unused = {}> {
|
|||
* > NOTE: Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers.
|
||||
* @param params
|
||||
*/
|
||||
connectOverCDP(params: {
|
||||
/**
|
||||
* A CDP websocket endpoint to connect to.
|
||||
*/
|
||||
wsEndpoint: string;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<Browser>;
|
||||
connectOverCDP(options: ConnectOverCDPOptions): Promise<Browser>;
|
||||
/**
|
||||
* Option `wsEndpoint` is deprecated. Instead use `endpointURL`.
|
||||
* @deprecated
|
||||
*/
|
||||
connectOverCDP(options: ConnectOptions): Promise<Browser>;
|
||||
/**
|
||||
* This methods attaches Playwright to an existing browser instance.
|
||||
* @param params
|
||||
*/
|
||||
connect(params: ConnectOptions): Promise<Browser>;
|
||||
|
||||
/**
|
||||
* A path where Playwright expects to find a bundled browser executable.
|
||||
|
|
@ -10687,6 +10668,31 @@ export interface LaunchOptions {
|
|||
timeout?: number;
|
||||
}
|
||||
|
||||
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`.
|
||||
*/
|
||||
endpointURL: string;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
export interface ConnectOptions {
|
||||
/**
|
||||
* A browser websocket endpoint to connect to.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"BrowserTypeLaunchOptions": "LaunchOptions",
|
||||
"BrowserTypeConnectParams": "ConnectOptions",
|
||||
"BrowserTypeConnectOverCDPParams": "ConnectOverCDPOptions",
|
||||
"BrowserContextCookies": "Cookie",
|
||||
"BrowserNewContextOptions": "BrowserContextOptions",
|
||||
"BrowserNewContextOptionsViewport": "ViewportSize",
|
||||
|
|
|
|||
|
|
@ -141,7 +141,12 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
|||
}
|
||||
|
||||
export interface BrowserType<Unused = {}> {
|
||||
|
||||
connectOverCDP(options: ConnectOverCDPOptions): Promise<Browser>;
|
||||
/**
|
||||
* Option `wsEndpoint` is deprecated. Instead use `endpointURL`.
|
||||
* @deprecated
|
||||
*/
|
||||
connectOverCDP(options: ConnectOptions): Promise<Browser>;
|
||||
}
|
||||
|
||||
export interface CDPSession {
|
||||
|
|
|
|||
Loading…
Reference in New Issue