diff --git a/docs/api.md b/docs/api.md index eb8ab0b30f..81d49201a9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -41,12 +41,10 @@ * [browser.newPage()](#browsernewpage) * [browser.pages()](#browserpages) * [browser.process()](#browserprocess) - * [browser.target()](#browsertarget) * [browser.targets()](#browsertargets) * [browser.userAgent()](#browseruseragent) * [browser.version()](#browserversion) * [browser.waitForTarget(predicate[, options])](#browserwaitfortargetpredicate-options) - * [browser.wsEndpoint()](#browserwsendpoint) - [class: BrowserContext](#class-browsercontext) * [event: 'targetchanged'](#event-targetchanged-1) * [event: 'targetcreated'](#event-targetcreated-1) @@ -175,10 +173,12 @@ - [class: PDF](#class-pdf) * [pdf.generate([options])](#pdfgenerateoptions) - [class: Chromium](#class-chromium) + * [chromium.createBrowserCDPSession()](#chromiumcreatebrowsercdpsession) * [chromium.createCDPSession(target)](#chromiumcreatecdpsessiontarget) * [chromium.serviceWorker(target)](#chromiumserviceworkertarget) * [chromium.startTracing(page, [options])](#chromiumstarttracingpage-options) * [chromium.stopTracing()](#chromiumstoptracing) + * [chromium.wsEndpoint()](#chromiumwsendpoint) - [class: FileChooser](#class-filechooser) * [fileChooser.accept(filePaths)](#filechooseracceptfilepaths) * [fileChooser.cancel()](#filechoosercancel) @@ -684,11 +684,6 @@ the method will return an array with all the pages in all browser contexts. #### browser.process() - returns: Spawned browser process. Returns `null` if the browser instance was created with [`playwright.connect`](#playwrightconnectoptions) method. -#### browser.target() -- returns: <[Target]> - -A target associated with the browser. - #### browser.targets() - returns: <[Array]<[Target]>> @@ -719,14 +714,6 @@ await page.evaluate(() => window.open('https://www.example.com/')); const newWindowTarget = await browser.waitForTarget(target => target.url() === 'https://www.example.com/'); ``` -#### browser.wsEndpoint() -- returns: <[string]> Browser websocket url. - -Browser websocket endpoint which can be used as an argument to -[playwright.connect](#playwrightconnectoptions). The format is `ws://${host}:${port}/devtools/browser/` - -You can find the `webSocketDebuggerUrl` from `http://${host}:${port}/json/version`. Learn more about the [devtools protocol](https://chromedevtools.github.io/devtools-protocol) and the [browser endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target). - ### class: BrowserContext * extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) @@ -2408,6 +2395,11 @@ await page.goto('https://www.google.com'); await page.chromium.stopTracing(); ``` +#### chromium.createBrowserCDPSession() +- returns: <[Promise]<[CDPSession]>> + +Creates a Chrome Devtools Protocol session attached to the browser. + #### chromium.createCDPSession(target) - `target` <[Target]> Target to return CDP connection for. - returns: <[Promise]<[CDPSession]>> @@ -2433,6 +2425,14 @@ Only one trace can be active at a time per browser. #### chromium.stopTracing() - returns: <[Promise]<[Buffer]>> Promise which resolves to buffer with trace data. +#### chromium.wsEndpoint() +- returns: <[string]> Browser websocket url. + +Browser websocket endpoint which can be used as an argument to +[playwright.connect](#playwrightconnectoptions). The format is `ws://${host}:${port}/devtools/browser/` + +You can find the `webSocketDebuggerUrl` from `http://${host}:${port}/json/version`. Learn more about the [devtools protocol](https://chromedevtools.github.io/devtools-protocol) and the [browser endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target). + ### class: FileChooser [FileChooser] objects are returned via the ['page.waitForFileChooser'](#pagewaitforfilechooseroptions) method. diff --git a/src/chromium/Browser.ts b/src/chromium/Browser.ts index d32dcc4107..15db04a22f 100644 --- a/src/chromium/Browser.ts +++ b/src/chromium/Browser.ts @@ -66,7 +66,7 @@ export class Browser extends EventEmitter { this._defaultViewport = defaultViewport; this._process = process; this._closeCallback = closeCallback || (() => Promise.resolve()); - this.chromium = new Chromium(this._client); + this.chromium = new Chromium(this._connection, this._client); this._defaultContext = new BrowserContext(this._client, this, null); for (const contextId of contextIds) @@ -140,10 +140,6 @@ export class Browser extends EventEmitter { } } - wsEndpoint(): string { - return this._connection.url(); - } - async newPage(): Promise { return this._defaultContext.newPage(); } @@ -164,10 +160,6 @@ export class Browser extends EventEmitter { return Array.from(this._targets.values()).filter(target => target._isInitialized); } - target(): Target { - return this.targets().find(target => target.type() === 'browser'); - } - async waitForTarget(predicate: (arg0: Target) => boolean, options: { timeout?: number; } | undefined = {}): Promise { const { timeout = 30000 diff --git a/src/chromium/features/chromium.ts b/src/chromium/features/chromium.ts index cb13aa194f..326c386b3b 100644 --- a/src/chromium/features/chromium.ts +++ b/src/chromium/features/chromium.ts @@ -15,22 +15,28 @@ * limitations under the License. */ import { assert } from '../../helper'; -import { CDPSession } from '../Connection'; +import { CDPSession, Connection } from '../Connection'; import { Page } from '../Page'; import { readProtocolStream } from '../protocolHelper'; import { Target } from '../Target'; import { Worker } from './workers'; export class Chromium { + private _connection: Connection; private _client: CDPSession; private _recording = false; private _path = ''; private _tracingClient: CDPSession | undefined; - constructor(client: CDPSession) { + constructor(connection: Connection, client: CDPSession) { + this._connection = connection; this._client = client; } + createBrowserCDPSession(): Promise { + return this._connection.createBrowserSession(); + } + createCDPSession(target: Target): Promise { return target._sessionFactory(); } @@ -77,4 +83,8 @@ export class Chromium { this._recording = false; return contentPromise; } + + wsEndpoint(): string { + return this._connection.url(); + } } diff --git a/src/firefox/Browser.ts b/src/firefox/Browser.ts index c292857834..84449410af 100644 --- a/src/firefox/Browser.ts +++ b/src/firefox/Browser.ts @@ -39,7 +39,6 @@ export class Browser extends EventEmitter { return browser; } - constructor(connection: Connection, browserContextIds: Array, defaultViewport: Viewport | null, process: import('child_process').ChildProcess | null, closeCallback: () => void) { super(); this._connection = connection; @@ -63,15 +62,10 @@ export class Browser extends EventEmitter { ]; } - wsEndpoint() { - return this._connection.url(); - } - disconnect() { this._connection.dispose(); } - isConnected(): boolean { return !this._connection._closed; } @@ -83,7 +77,6 @@ export class Browser extends EventEmitter { return context; } - browserContexts(): Array { return [this._defaultContext, ...Array.from(this._contexts.values())]; } @@ -97,24 +90,20 @@ export class Browser extends EventEmitter { this._contexts.delete(browserContextId); } - async userAgent(): Promise { const info = await this._connection.send('Browser.getInfo'); return info.userAgent; } - async version(): Promise { const info = await this._connection.send('Browser.getInfo'); return info.version; } - process(): import('child_process').ChildProcess | null { return this._process; } - async waitForTarget(predicate: (target: Target) => boolean, options: { timeout?: number; } = {}): Promise { const { timeout = 30000 @@ -141,12 +130,10 @@ export class Browser extends EventEmitter { } } - newPage(): Promise { return this._createPageInContext(this._defaultContext._browserContextId); } - async _createPageInContext(browserContextId: string | null): Promise { const {targetId} = await this._connection.send('Target.newPage', { browserContextId: browserContextId || undefined @@ -164,10 +151,6 @@ export class Browser extends EventEmitter { return Array.from(this._targets.values()); } - target() { - return this.targets().find(target => target.type() === 'browser'); - } - async _onTargetCreated({targetId, url, browserContextId, openerId, type}) { const context = browserContextId ? this._contexts.get(browserContextId) : this._defaultContext; const target = new Target(this._connection, this, context, targetId, type, url, openerId); @@ -200,7 +183,7 @@ export class Browser extends EventEmitter { async close() { helper.removeEventListeners(this._eventListeners); - await this._closeCallback(); + this._closeCallback(); } } diff --git a/src/webkit/Browser.ts b/src/webkit/Browser.ts index 802fc2a8c9..e56fd0c509 100644 --- a/src/webkit/Browser.ts +++ b/src/webkit/Browser.ts @@ -180,11 +180,19 @@ export class Browser extends EventEmitter { newTarget._pagePromise = oldTarget._pagePromise; } - _onTargetChanged(target) { + _onTargetChanged(target: Target) { this.emit(Events.BrowserContext.TargetChanged, target); target.browserContext().emit(Events.BrowserContext.TargetChanged, target); } + disconnect() { + throw new Error('Unsupported operation'); + } + + isConnected(): boolean { + return true; + } + async close() { helper.removeEventListeners(this._eventListeners); await this._closeCallback.call(null); diff --git a/src/webkit/events.ts b/src/webkit/events.ts index 6185fe61f4..b29cc6da20 100644 --- a/src/webkit/events.ts +++ b/src/webkit/events.ts @@ -34,6 +34,7 @@ export const Events = { TargetCreated: 'targetcreated', TargetDestroyed: 'targetdestroyed', TargetChanged: 'targetchanged', + Disconnected: 'disconnected' }, BrowserContext: {