mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
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
|
### param: BrowserType.connectOverCDP.params
|
||||||
* langs: js
|
* langs: js
|
||||||
- `params` <[Object]>
|
- `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
|
- `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.
|
can see what is going on. Defaults to 0.
|
||||||
- `logger` <[Logger]> Logger sink for Playwright logging. Optional.
|
- `logger` <[Logger]> Logger sink for Playwright logging. Optional.
|
||||||
|
|||||||
@ -58,11 +58,11 @@ page.navigate("https://www.w3.org/");
|
|||||||
playwright.close();
|
playwright.close();
|
||||||
```
|
```
|
||||||
|
|
||||||
### param: BrowserType.connectOverCDP.wsEndpoint
|
### param: BrowserType.connectOverCDP.endpointURL
|
||||||
* langs: java
|
* 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-%%
|
### param: BrowserContext.waitForPage.callback = %%-java-wait-for-event-callback-%%
|
||||||
|
|
||||||
|
|||||||
@ -187,14 +187,16 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel, chann
|
|||||||
}, logger);
|
}, 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')
|
if (this.name() !== 'chromium')
|
||||||
throw new Error('Connecting over CDP is only supported in Chromium.');
|
throw new Error('Connecting over CDP is only supported in Chromium.');
|
||||||
const logger = params.logger;
|
const logger = params.logger;
|
||||||
return this._wrapApiCall('browserType.connectOverCDP', async (channel: channels.BrowserTypeChannel) => {
|
return this._wrapApiCall('browserType.connectOverCDP', async (channel: channels.BrowserTypeChannel) => {
|
||||||
const result = await channel.connectOverCDP({
|
const result = await channel.connectOverCDP({
|
||||||
sdkLanguage: 'javascript',
|
sdkLanguage: 'javascript',
|
||||||
wsEndpoint: params.wsEndpoint,
|
endpointURL: 'endpointURL' in params ? params.endpointURL : params.wsEndpoint,
|
||||||
slowMo: params.slowMo,
|
slowMo: params.slowMo,
|
||||||
timeout: params.timeout
|
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> {
|
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 {
|
return {
|
||||||
browser: new BrowserDispatcher(this._scope, browser),
|
browser: new BrowserDispatcher(this._scope, browser),
|
||||||
defaultContext: browser._defaultContext ? new BrowserContextDispatcher(this._scope, browser._defaultContext) : undefined,
|
defaultContext: browser._defaultContext ? new BrowserContextDispatcher(this._scope, browser._defaultContext) : undefined,
|
||||||
|
|||||||
@ -408,7 +408,7 @@ export type BrowserTypeLaunchPersistentContextResult = {
|
|||||||
};
|
};
|
||||||
export type BrowserTypeConnectOverCDPParams = {
|
export type BrowserTypeConnectOverCDPParams = {
|
||||||
sdkLanguage: string,
|
sdkLanguage: string,
|
||||||
wsEndpoint: string,
|
endpointURL: string,
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -422,7 +422,7 @@ BrowserType:
|
|||||||
connectOverCDP:
|
connectOverCDP:
|
||||||
parameters:
|
parameters:
|
||||||
sdkLanguage: string
|
sdkLanguage: string
|
||||||
wsEndpoint: string
|
endpointURL: string
|
||||||
slowMo: number?
|
slowMo: number?
|
||||||
timeout: number?
|
timeout: number?
|
||||||
returns:
|
returns:
|
||||||
|
|||||||
@ -249,7 +249,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
|||||||
});
|
});
|
||||||
scheme.BrowserTypeConnectOverCDPParams = tObject({
|
scheme.BrowserTypeConnectOverCDPParams = tObject({
|
||||||
sdkLanguage: tString,
|
sdkLanguage: tString,
|
||||||
wsEndpoint: tString,
|
endpointURL: tString,
|
||||||
slowMo: tOptional(tNumber),
|
slowMo: tOptional(tNumber),
|
||||||
timeout: tOptional(tNumber),
|
timeout: tOptional(tNumber),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -248,7 +248,7 @@ export abstract class BrowserType extends SdkObject {
|
|||||||
return { browserProcess, downloadsPath, transport };
|
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');
|
throw new Error('CDP connections are only supported by Chromium');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import { TimeoutSettings } from '../../utils/timeoutSettings';
|
|||||||
import { helper } from '../helper';
|
import { helper } from '../helper';
|
||||||
import { CallMetadata } from '../instrumentation';
|
import { CallMetadata } from '../instrumentation';
|
||||||
import { findChromiumChannel } from './findChromiumChannel';
|
import { findChromiumChannel } from './findChromiumChannel';
|
||||||
|
import http from 'http';
|
||||||
|
|
||||||
export class Chromium extends BrowserType {
|
export class Chromium extends BrowserType {
|
||||||
private _devtools: CRDevTools | undefined;
|
private _devtools: CRDevTools | undefined;
|
||||||
@ -49,12 +50,12 @@ export class Chromium extends BrowserType {
|
|||||||
return super.executablePath(options);
|
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);
|
const controller = new ProgressController(metadata, this);
|
||||||
controller.setLogName('browser');
|
controller.setLogName('browser');
|
||||||
const browserLogsCollector = new RecentLogsCollector();
|
const browserLogsCollector = new RecentLogsCollector();
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
const chromeTransport = await WebSocketTransport.connect(progress, wsEndpoint);
|
const chromeTransport = await WebSocketTransport.connect(progress, await urlToWSEndpoint(endpointURL));
|
||||||
const browserProcess: BrowserProcess = {
|
const browserProcess: BrowserProcess = {
|
||||||
close: async () => {
|
close: async () => {
|
||||||
await chromeTransport.closeAndWait();
|
await chromeTransport.closeAndWait();
|
||||||
@ -192,3 +193,17 @@ const DEFAULT_ARGS = [
|
|||||||
'--password-store=basic',
|
'--password-store=basic',
|
||||||
'--use-mock-keychain',
|
'--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('should throw when trying to connect with not-chromium', async ({ browserType, browserName }) => {
|
||||||
test.skip(browserName === 'chromium');
|
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.');
|
expect(error.message).toBe('Connecting over CDP is only supported in Chromium.');
|
||||||
});
|
});
|
||||||
|
|||||||
@ -112,15 +112,8 @@ playwrightTest.describe('chromium', () => {
|
|||||||
args: ['--remote-debugging-port=' + port]
|
args: ['--remote-debugging-port=' + port]
|
||||||
});
|
});
|
||||||
try {
|
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({
|
const cdpBrowser = await browserType.connectOverCDP({
|
||||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
endpointURL: `http://localhost:${port}/`,
|
||||||
});
|
});
|
||||||
const contexts = cdpBrowser.contexts();
|
const contexts = cdpBrowser.contexts();
|
||||||
expect(contexts.length).toBe(1);
|
expect(contexts.length).toBe(1);
|
||||||
@ -137,18 +130,11 @@ playwrightTest.describe('chromium', () => {
|
|||||||
args: ['--remote-debugging-port=' + port]
|
args: ['--remote-debugging-port=' + port]
|
||||||
});
|
});
|
||||||
try {
|
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({
|
const cdpBrowser1 = await browserType.connectOverCDP({
|
||||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
endpointURL: `http://localhost:${port}/`,
|
||||||
});
|
});
|
||||||
const cdpBrowser2 = await browserType.connectOverCDP({
|
const cdpBrowser2 = await browserType.connectOverCDP({
|
||||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
endpointURL: `http://localhost:${port}/`,
|
||||||
});
|
});
|
||||||
const contexts1 = cdpBrowser1.contexts();
|
const contexts1 = cdpBrowser1.contexts();
|
||||||
expect(contexts1.length).toBe(1);
|
expect(contexts1.length).toBe(1);
|
||||||
@ -179,15 +165,8 @@ playwrightTest.describe('chromium', () => {
|
|||||||
args: ['--remote-debugging-port=' + port]
|
args: ['--remote-debugging-port=' + port]
|
||||||
});
|
});
|
||||||
try {
|
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({
|
const cdpBrowser1 = await browserType.connectOverCDP({
|
||||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
endpointURL: `http://localhost:${port}`,
|
||||||
});
|
});
|
||||||
const context = cdpBrowser1.contexts()[0];
|
const context = cdpBrowser1.contexts()[0];
|
||||||
const page = await cdpBrowser1.contexts()[0].newPage();
|
const page = await cdpBrowser1.contexts()[0].newPage();
|
||||||
@ -199,7 +178,7 @@ playwrightTest.describe('chromium', () => {
|
|||||||
await cdpBrowser1.close();
|
await cdpBrowser1.close();
|
||||||
|
|
||||||
const cdpBrowser2 = await browserType.connectOverCDP({
|
const cdpBrowser2 = await browserType.connectOverCDP({
|
||||||
wsEndpoint: JSON.parse(json).webSocketDebuggerUrl,
|
endpointURL: `http://localhost:${port}`,
|
||||||
});
|
});
|
||||||
const context2 = cdpBrowser2.contexts()[0];
|
const context2 = cdpBrowser2.contexts()[0];
|
||||||
expect(context2.serviceWorkers().length).toBe(1);
|
expect(context2.serviceWorkers().length).toBe(1);
|
||||||
@ -208,4 +187,36 @@ playwrightTest.describe('chromium', () => {
|
|||||||
await browserServer.close();
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
58
types/types.d.ts
vendored
58
types/types.d.ts
vendored
@ -6460,13 +6460,6 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export interface BrowserType<Unused = {}> {
|
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.
|
* 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.
|
* > NOTE: Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers.
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
connectOverCDP(params: {
|
connectOverCDP(options: ConnectOverCDPOptions): Promise<Browser>;
|
||||||
/**
|
/**
|
||||||
* A CDP websocket endpoint to connect to.
|
* Option `wsEndpoint` is deprecated. Instead use `endpointURL`.
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
wsEndpoint: string;
|
connectOverCDP(options: ConnectOptions): Promise<Browser>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
|
* This methods attaches Playwright to an existing browser instance.
|
||||||
* Defaults to 0.
|
* @param params
|
||||||
*/
|
*/
|
||||||
slowMo?: number;
|
connect(params: ConnectOptions): Promise<Browser>;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A path where Playwright expects to find a bundled browser executable.
|
* A path where Playwright expects to find a bundled browser executable.
|
||||||
@ -10687,6 +10668,31 @@ export interface LaunchOptions {
|
|||||||
timeout?: number;
|
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 {
|
export interface ConnectOptions {
|
||||||
/**
|
/**
|
||||||
* A browser websocket endpoint to connect to.
|
* A browser websocket endpoint to connect to.
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"BrowserTypeLaunchOptions": "LaunchOptions",
|
"BrowserTypeLaunchOptions": "LaunchOptions",
|
||||||
"BrowserTypeConnectParams": "ConnectOptions",
|
"BrowserTypeConnectParams": "ConnectOptions",
|
||||||
|
"BrowserTypeConnectOverCDPParams": "ConnectOverCDPOptions",
|
||||||
"BrowserContextCookies": "Cookie",
|
"BrowserContextCookies": "Cookie",
|
||||||
"BrowserNewContextOptions": "BrowserContextOptions",
|
"BrowserNewContextOptions": "BrowserContextOptions",
|
||||||
"BrowserNewContextOptionsViewport": "ViewportSize",
|
"BrowserNewContextOptionsViewport": "ViewportSize",
|
||||||
|
|||||||
7
utils/generate_types/overrides.d.ts
vendored
7
utils/generate_types/overrides.d.ts
vendored
@ -141,7 +141,12 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BrowserType<Unused = {}> {
|
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 {
|
export interface CDPSession {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user