fix(api): BrowserServer -> BrowserApp, resuse it between browsers (#599)
This commit is contained in:
parent
b4209e9dc8
commit
ac2ba3cbd9
163
docs/api.md
163
docs/api.md
|
|
@ -7,6 +7,7 @@
|
||||||
<!-- GEN:toc-top-level -->
|
<!-- GEN:toc-top-level -->
|
||||||
- [class: Playwright](#class-playwright)
|
- [class: Playwright](#class-playwright)
|
||||||
- [class: Browser](#class-browser)
|
- [class: Browser](#class-browser)
|
||||||
|
- [class: BrowserApp](#class-browserapp)
|
||||||
- [class: BrowserContext](#class-browsercontext)
|
- [class: BrowserContext](#class-browsercontext)
|
||||||
- [class: ConsoleMessage](#class-consolemessage)
|
- [class: ConsoleMessage](#class-consolemessage)
|
||||||
- [class: Dialog](#class-dialog)
|
- [class: Dialog](#class-dialog)
|
||||||
|
|
@ -24,15 +25,12 @@
|
||||||
- [class: Worker](#class-worker)
|
- [class: Worker](#class-worker)
|
||||||
- [class: ChromiumPlaywright](#class-chromiumplaywright)
|
- [class: ChromiumPlaywright](#class-chromiumplaywright)
|
||||||
- [class: ChromiumBrowser](#class-chromiumbrowser)
|
- [class: ChromiumBrowser](#class-chromiumbrowser)
|
||||||
- [class: ChromiumBrowserServer](#class-chromiumbrowserserver)
|
|
||||||
- [class: ChromiumSession](#class-chromiumsession)
|
- [class: ChromiumSession](#class-chromiumsession)
|
||||||
- [class: ChromiumTarget](#class-chromiumtarget)
|
- [class: ChromiumTarget](#class-chromiumtarget)
|
||||||
- [class: FirefoxPlaywright](#class-firefoxplaywright)
|
- [class: FirefoxPlaywright](#class-firefoxplaywright)
|
||||||
- [class: FirefoxBrowser](#class-firefoxbrowser)
|
- [class: FirefoxBrowser](#class-firefoxbrowser)
|
||||||
- [class: FirefoxBrowserServer](#class-firefoxbrowserserver)
|
|
||||||
- [class: WebKitPlaywright](#class-webkitplaywright)
|
- [class: WebKitPlaywright](#class-webkitplaywright)
|
||||||
- [class: WebKitBrowser](#class-webkitbrowser)
|
- [class: WebKitBrowser](#class-webkitbrowser)
|
||||||
- [class: WebKitBrowserServer](#class-webkitbrowserserver)
|
|
||||||
- [Working with selectors](#working-with-selectors)
|
- [Working with selectors](#working-with-selectors)
|
||||||
- [Working with Chrome Extensions](#working-with-chrome-extensions)
|
- [Working with Chrome Extensions](#working-with-chrome-extensions)
|
||||||
- [Downloaded browsers](#downloaded-browsers)
|
- [Downloaded browsers](#downloaded-browsers)
|
||||||
|
|
@ -128,17 +126,17 @@ const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'.
|
||||||
})();
|
})();
|
||||||
```
|
```
|
||||||
|
|
||||||
An example of disconnecting from and reconnecting to a [Browser]:
|
An example of launching a browser executable and connecting to a [Browser] later:
|
||||||
```js
|
```js
|
||||||
const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'.
|
const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'.
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const browserServer = await playwright.launchServer();
|
const browserApp = await playwright.launchBrowserApp();
|
||||||
const browserWSEndpoint = browserServer.wsEndpoint();
|
const connectOptions = browserApp.connectOptions();
|
||||||
// Use the endpoint to establish a connection
|
// Use connect options later to establish a connection.
|
||||||
const browser = await playwright.connect({browserWSEndpoint});
|
const browser = await playwright.connect(connectOptions);
|
||||||
// Close Chromium
|
// Close browser instance.
|
||||||
await browser.close();
|
await browserApp.close();
|
||||||
})();
|
})();
|
||||||
```
|
```
|
||||||
<!-- GEN:toc -->
|
<!-- GEN:toc -->
|
||||||
|
|
@ -214,6 +212,38 @@ Creates a new browser context. It won't share cookies/cache with other browser c
|
||||||
})();
|
})();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### class: BrowserApp
|
||||||
|
|
||||||
|
<!-- GEN:toc -->
|
||||||
|
- [browserApp.close()](#browserappclose)
|
||||||
|
- [browserApp.connectOptions()](#browserappconnectoptions)
|
||||||
|
- [browserApp.process()](#browserappprocess)
|
||||||
|
- [browserApp.wsEndpoint()](#browserappwsendpoint)
|
||||||
|
<!-- GEN:stop -->
|
||||||
|
|
||||||
|
#### browserApp.close()
|
||||||
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
Closes the browser gracefully and makes sure the process is terminated.
|
||||||
|
|
||||||
|
#### browserApp.connectOptions()
|
||||||
|
- returns: <[Object]>
|
||||||
|
- `browserWSEndpoint` <?[string]> a [browser websocket endpoint](#browserwsendpoint) to connect to.
|
||||||
|
- `slowMo` <[number]>
|
||||||
|
- `transport` <[ConnectionTransport]> **Experimental** A custom transport object which should be used to connect.
|
||||||
|
|
||||||
|
This options object can be passed to [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions), [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions) or [webkitPlaywright.connect(options)](#webkitplaywrightconnectoptions) to establish connection to the browser.
|
||||||
|
|
||||||
|
#### browserApp.process()
|
||||||
|
- returns: <?[ChildProcess]> Spawned browser server process.
|
||||||
|
|
||||||
|
#### browserApp.wsEndpoint()
|
||||||
|
- returns: <?[string]> Browser websocket url.
|
||||||
|
|
||||||
|
Browser websocket endpoint which can be used as an argument to [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions), [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions) or [webkitPlaywright.connect(options)](#webkitplaywrightconnectoptions) to establish connection to the browser.
|
||||||
|
|
||||||
|
Learn more about [Chromium 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
|
### class: BrowserContext
|
||||||
|
|
||||||
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
|
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
|
||||||
|
|
@ -3191,7 +3221,7 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then
|
||||||
- [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions)
|
- [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions)
|
||||||
- [chromiumPlaywright.defaultArgs([options])](#chromiumplaywrightdefaultargsoptions)
|
- [chromiumPlaywright.defaultArgs([options])](#chromiumplaywrightdefaultargsoptions)
|
||||||
- [chromiumPlaywright.launch([options])](#chromiumplaywrightlaunchoptions)
|
- [chromiumPlaywright.launch([options])](#chromiumplaywrightlaunchoptions)
|
||||||
- [chromiumPlaywright.launchServer([options])](#chromiumplaywrightlaunchserveroptions)
|
- [chromiumPlaywright.launchBrowserApp([options])](#chromiumplaywrightlaunchbrowserappoptions)
|
||||||
<!-- GEN:stop -->
|
<!-- GEN:stop -->
|
||||||
|
|
||||||
#### chromiumPlaywright.connect(options)
|
#### chromiumPlaywright.connect(options)
|
||||||
|
|
@ -3248,7 +3278,7 @@ const browser = await playwright.launch({
|
||||||
>
|
>
|
||||||
> See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [`This article`](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users.
|
> See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [`This article`](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users.
|
||||||
|
|
||||||
#### chromiumPlaywright.launchServer([options])
|
#### chromiumPlaywright.launchBrowserApp([options])
|
||||||
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
||||||
- `headless` <[boolean]> Whether to run Chromium in [headless mode](https://developers.google.com/web/updates/2017/04/headless-chrome). Defaults to `true` unless the `devtools` option is `true`.
|
- `headless` <[boolean]> Whether to run Chromium in [headless mode](https://developers.google.com/web/updates/2017/04/headless-chrome). Defaults to `true` unless the `devtools` option is `true`.
|
||||||
- `executablePath` <[string]> Path to a Chromium or Chrome executable to run instead of the bundled Chromium. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only [guaranteed to work](https://github.com/Microsoft/playwright/#q-why-doesnt-playwright-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk.
|
- `executablePath` <[string]> Path to a Chromium or Chrome executable to run instead of the bundled Chromium. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only [guaranteed to work](https://github.com/Microsoft/playwright/#q-why-doesnt-playwright-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk.
|
||||||
|
|
@ -3264,7 +3294,7 @@ const browser = await playwright.launch({
|
||||||
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
|
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
|
||||||
- `devtools` <[boolean]> Whether to auto-open a DevTools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
|
- `devtools` <[boolean]> Whether to auto-open a DevTools panel for each tab. If this option is `true`, the `headless` option will be set `false`.
|
||||||
- `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`.
|
- `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`.
|
||||||
- returns: <[Promise]<[ChromiumBrowserServer]>> Promise which resolves to browser server instance.
|
- returns: <[Promise]<[BrowserApp]>> Promise which resolves to browser server instance.
|
||||||
|
|
||||||
### class: ChromiumBrowser
|
### class: ChromiumBrowser
|
||||||
|
|
||||||
|
|
@ -3363,39 +3393,6 @@ await page.evaluate(() => window.open('https://www.example.com/'));
|
||||||
const newWindowTarget = await browser.chromium.waitForTarget(target => target.url() === 'https://www.example.com/');
|
const newWindowTarget = await browser.chromium.waitForTarget(target => target.url() === 'https://www.example.com/');
|
||||||
```
|
```
|
||||||
|
|
||||||
### class: ChromiumBrowserServer
|
|
||||||
|
|
||||||
<!-- GEN:toc -->
|
|
||||||
- [chromiumBrowserServer.close()](#chromiumbrowserserverclose)
|
|
||||||
- [chromiumBrowserServer.connectOptions()](#chromiumbrowserserverconnectoptions)
|
|
||||||
- [chromiumBrowserServer.process()](#chromiumbrowserserverprocess)
|
|
||||||
- [chromiumBrowserServer.wsEndpoint()](#chromiumbrowserserverwsendpoint)
|
|
||||||
<!-- GEN:stop -->
|
|
||||||
|
|
||||||
#### chromiumBrowserServer.close()
|
|
||||||
- returns: <[Promise]>
|
|
||||||
|
|
||||||
Closes the browser gracefully and makes sure the process is terminated.
|
|
||||||
|
|
||||||
#### chromiumBrowserServer.connectOptions()
|
|
||||||
- returns: <[Object]>
|
|
||||||
- `browserWSEndpoint` <?[string]> a [browser websocket endpoint](#browserwsendpoint) to connect to.
|
|
||||||
- `browserURL` <?[string]> a browser url to connect to, in format `http://${host}:${port}`. Use interchangeably with `browserWSEndpoint` to let Playwright fetch it from [metadata endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target).
|
|
||||||
- `slowMo` <[number]>
|
|
||||||
- `transport` <[ConnectionTransport]> **Experimental** A custom transport object which should be used to connect.
|
|
||||||
|
|
||||||
This options object can be passed to [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions) to establish connection to the browser.
|
|
||||||
|
|
||||||
#### chromiumBrowserServer.process()
|
|
||||||
- returns: <?[ChildProcess]> Spawned browser server process.
|
|
||||||
|
|
||||||
#### chromiumBrowserServer.wsEndpoint()
|
|
||||||
- returns: <?[string]> Browser websocket url.
|
|
||||||
|
|
||||||
Browser websocket endpoint which can be used as an argument to [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions).
|
|
||||||
|
|
||||||
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: ChromiumSession
|
### class: ChromiumSession
|
||||||
|
|
||||||
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
|
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
|
||||||
|
|
@ -3484,7 +3481,7 @@ Identifies what kind of target this is. Can be `"page"`, [`"background_page"`](h
|
||||||
- [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions)
|
- [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions)
|
||||||
- [firefoxPlaywright.defaultArgs([options])](#firefoxplaywrightdefaultargsoptions)
|
- [firefoxPlaywright.defaultArgs([options])](#firefoxplaywrightdefaultargsoptions)
|
||||||
- [firefoxPlaywright.launch([options])](#firefoxplaywrightlaunchoptions)
|
- [firefoxPlaywright.launch([options])](#firefoxplaywrightlaunchoptions)
|
||||||
- [firefoxPlaywright.launchServer([options])](#firefoxplaywrightlaunchserveroptions)
|
- [firefoxPlaywright.launchBrowserApp([options])](#firefoxplaywrightlaunchbrowserappoptions)
|
||||||
<!-- GEN:stop -->
|
<!-- GEN:stop -->
|
||||||
|
|
||||||
#### firefoxPlaywright.connect(options)
|
#### firefoxPlaywright.connect(options)
|
||||||
|
|
@ -3529,7 +3526,7 @@ const browser = await playwright.launch({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### firefoxPlaywright.launchServer([options])
|
#### firefoxPlaywright.launchBrowserApp([options])
|
||||||
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
||||||
- `headless` <[boolean]> Whether to run Firefox in [headless mode](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true`.
|
- `headless` <[boolean]> Whether to run Firefox in [headless mode](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true`.
|
||||||
- `executablePath` <[string]> Path to a Firefox executable to run instead of the bundled Firefox. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled Firefox, use at your own risk.
|
- `executablePath` <[string]> Path to a Firefox executable to run instead of the bundled Firefox. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled Firefox, use at your own risk.
|
||||||
|
|
@ -3543,7 +3540,7 @@ const browser = await playwright.launch({
|
||||||
- `dumpio` <[boolean]> Whether to pipe the browser process stdout and stderr into `process.stdout` and `process.stderr`. Defaults to `false`.
|
- `dumpio` <[boolean]> Whether to pipe the browser process stdout and stderr into `process.stdout` and `process.stderr`. Defaults to `false`.
|
||||||
- `userDataDir` <[string]> Path to a [User Data Directory](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#User_Profile).
|
- `userDataDir` <[string]> Path to a [User Data Directory](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#User_Profile).
|
||||||
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
|
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
|
||||||
- returns: <[Promise]<[FirefoxBrowserServer]>> Promise which resolves to browser server instance.
|
- returns: <[Promise]<[BrowserApp]>> Promise which resolves to browser server instance.
|
||||||
|
|
||||||
### class: FirefoxBrowser
|
### class: FirefoxBrowser
|
||||||
|
|
||||||
|
|
@ -3551,35 +3548,6 @@ const browser = await playwright.launch({
|
||||||
|
|
||||||
Firefox browser instance does not expose Firefox-specific features.
|
Firefox browser instance does not expose Firefox-specific features.
|
||||||
|
|
||||||
### class: FirefoxBrowserServer
|
|
||||||
|
|
||||||
<!-- GEN:toc -->
|
|
||||||
- [firefoxBrowserServer.close()](#firefoxbrowserserverclose)
|
|
||||||
- [firefoxBrowserServer.connectOptions()](#firefoxbrowserserverconnectoptions)
|
|
||||||
- [firefoxBrowserServer.process()](#firefoxbrowserserverprocess)
|
|
||||||
- [firefoxBrowserServer.wsEndpoint()](#firefoxbrowserserverwsendpoint)
|
|
||||||
<!-- GEN:stop -->
|
|
||||||
|
|
||||||
#### firefoxBrowserServer.close()
|
|
||||||
- returns: <[Promise]>
|
|
||||||
|
|
||||||
Closes the browser gracefully and makes sure the process is terminated.
|
|
||||||
|
|
||||||
#### firefoxBrowserServer.connectOptions()
|
|
||||||
- returns: <[Object]>
|
|
||||||
- `browserWSEndpoint` <?[string]> a [browser websocket endpoint](#browserwsendpoint) to connect to.
|
|
||||||
- `slowMo` <[number]>
|
|
||||||
- `transport` <[ConnectionTransport]> **Experimental** A custom transport object which should be used to connect.
|
|
||||||
|
|
||||||
This options object can be passed to [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions) to establish connection to the browser.
|
|
||||||
|
|
||||||
#### firefoxBrowserServer.process()
|
|
||||||
- returns: <?[ChildProcess]> Spawned browser server process.
|
|
||||||
|
|
||||||
#### firefoxBrowserServer.wsEndpoint()
|
|
||||||
- returns: <?[string]> Browser websocket url.
|
|
||||||
|
|
||||||
Browser websocket endpoint which can be used as an argument to [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions).
|
|
||||||
|
|
||||||
### class: WebKitPlaywright
|
### class: WebKitPlaywright
|
||||||
|
|
||||||
|
|
@ -3589,7 +3557,7 @@ Browser websocket endpoint which can be used as an argument to [firefoxPlaywrigh
|
||||||
- [webkitPlaywright.connect(options)](#webkitplaywrightconnectoptions)
|
- [webkitPlaywright.connect(options)](#webkitplaywrightconnectoptions)
|
||||||
- [webkitPlaywright.defaultArgs([options])](#webkitplaywrightdefaultargsoptions)
|
- [webkitPlaywright.defaultArgs([options])](#webkitplaywrightdefaultargsoptions)
|
||||||
- [webkitPlaywright.launch([options])](#webkitplaywrightlaunchoptions)
|
- [webkitPlaywright.launch([options])](#webkitplaywrightlaunchoptions)
|
||||||
- [webkitPlaywright.launchServer([options])](#webkitplaywrightlaunchserveroptions)
|
- [webkitPlaywright.launchBrowserApp([options])](#webkitplaywrightlaunchbrowserappoptions)
|
||||||
<!-- GEN:stop -->
|
<!-- GEN:stop -->
|
||||||
|
|
||||||
#### webkitPlaywright.connect(options)
|
#### webkitPlaywright.connect(options)
|
||||||
|
|
@ -3635,7 +3603,7 @@ const browser = await playwright.launch({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### webkitPlaywright.launchServer([options])
|
#### webkitPlaywright.launchBrowserApp([options])
|
||||||
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
|
||||||
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
- `headless` <[boolean]> Whether to run WebKit in headless mode. Defaults to `true`.
|
||||||
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
|
- `executablePath` <[string]> Path to a WebKit executable to run instead of the bundled WebKit. If `executablePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). **BEWARE**: Playwright is only guaranteed to work with the bundled WebKit, use at your own risk.
|
||||||
|
|
@ -3650,7 +3618,7 @@ const browser = await playwright.launch({
|
||||||
- `dumpio` <[boolean]> Whether to pipe the browser process stdout and stderr into `process.stdout` and `process.stderr`. Defaults to `false`.
|
- `dumpio` <[boolean]> Whether to pipe the browser process stdout and stderr into `process.stdout` and `process.stderr`. Defaults to `false`.
|
||||||
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
|
- `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`.
|
||||||
- `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`.
|
- `pipe` <[boolean]> Connects to the browser over a pipe instead of a WebSocket. Defaults to `false`.
|
||||||
- returns: <[Promise]<[WebKitBrowserServer]>> Promise which resolves to browser server instance.
|
- returns: <[Promise]<[BrowserApp]>> Promise which resolves to browser server instance.
|
||||||
|
|
||||||
### class: WebKitBrowser
|
### class: WebKitBrowser
|
||||||
|
|
||||||
|
|
@ -3658,35 +3626,6 @@ const browser = await playwright.launch({
|
||||||
|
|
||||||
WebKit browser instance does not expose WebKit-specific features.
|
WebKit browser instance does not expose WebKit-specific features.
|
||||||
|
|
||||||
### class: WebKitBrowserServer
|
|
||||||
|
|
||||||
<!-- GEN:toc -->
|
|
||||||
- [webKitBrowserServer.close()](#webkitbrowserserverclose)
|
|
||||||
- [webKitBrowserServer.connectOptions()](#webkitbrowserserverconnectoptions)
|
|
||||||
- [webKitBrowserServer.process()](#webkitbrowserserverprocess)
|
|
||||||
- [webKitBrowserServer.wsEndpoint()](#webkitbrowserserverwsendpoint)
|
|
||||||
<!-- GEN:stop -->
|
|
||||||
|
|
||||||
#### webKitBrowserServer.close()
|
|
||||||
- returns: <[Promise]>
|
|
||||||
|
|
||||||
Closes the browser gracefully and makes sure the process is terminated.
|
|
||||||
|
|
||||||
#### webKitBrowserServer.connectOptions()
|
|
||||||
- returns: <[Object]>
|
|
||||||
- `slowMo` <[number]>
|
|
||||||
- `transport` <[ConnectionTransport]> **Experimental** A custom transport object which should be used to connect.
|
|
||||||
|
|
||||||
This options object can be passed to [webKitPlaywright.connect(options)](#webkitplaywrightconnectoptions) to establish connection to the browser.
|
|
||||||
|
|
||||||
#### webKitBrowserServer.process()
|
|
||||||
- returns: <?[ChildProcess]> Spawned browser server process.
|
|
||||||
|
|
||||||
#### webKitBrowserServer.wsEndpoint()
|
|
||||||
- returns: <?[string]> Browser websocket url.
|
|
||||||
|
|
||||||
Browser websocket endpoint which can be used as an argument to [webkitPlaywright.connect(options)](#webkitplaywrightconnectoptions).
|
|
||||||
|
|
||||||
### Working with selectors
|
### Working with selectors
|
||||||
|
|
||||||
Selector describes an element in the page. It can be used to obtain `ElementHandle` (see [page.$()](#pageselector) for example) or shortcut element operations to avoid intermediate handle (see [page.click()](#pageclickselector-options) for example).
|
Selector describes an element in the page. It can be used to obtain `ElementHandle` (see [page.$()](#pageselector) for example) or shortcut element operations to avoid intermediate handle (see [page.click()](#pageclickselector-options) for example).
|
||||||
|
|
@ -3768,12 +3707,12 @@ During installation Playwright downloads browser executables, according to revis
|
||||||
[Accessibility]: #class-accessibility "Accessibility"
|
[Accessibility]: #class-accessibility "Accessibility"
|
||||||
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
|
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
|
||||||
[Body]: #class-body "Body"
|
[Body]: #class-body "Body"
|
||||||
|
[BrowserApp]: #class-browserapp "BrowserApp"
|
||||||
[BrowserContext]: #class-browsercontext "BrowserContext"
|
[BrowserContext]: #class-browsercontext "BrowserContext"
|
||||||
[Browser]: #class-browser "Browser"
|
[Browser]: #class-browser "Browser"
|
||||||
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
|
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
|
||||||
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
|
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
|
||||||
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
|
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
|
||||||
[ChromiumBrowserServer]: #class-chromiumbrowserserver "ChromiumBrowserServer"
|
|
||||||
[ChromiumPlaywright]: #class-chromiumplaywright "ChromiumPlaywright"
|
[ChromiumPlaywright]: #class-chromiumplaywright "ChromiumPlaywright"
|
||||||
[ChromiumSession]: #class-chromiumsession "ChromiumSession"
|
[ChromiumSession]: #class-chromiumsession "ChromiumSession"
|
||||||
[ChromiumTarget]: #class-chromiumtarget "ChromiumTarget"
|
[ChromiumTarget]: #class-chromiumtarget "ChromiumTarget"
|
||||||
|
|
@ -3787,7 +3726,6 @@ During installation Playwright downloads browser executables, according to revis
|
||||||
[File]: #class-file "https://developer.mozilla.org/en-US/docs/Web/API/File"
|
[File]: #class-file "https://developer.mozilla.org/en-US/docs/Web/API/File"
|
||||||
[FileChooser]: #class-filechooser "FileChooser"
|
[FileChooser]: #class-filechooser "FileChooser"
|
||||||
[FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser"
|
[FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser"
|
||||||
[FirefoxBrowserServer]: #class-firefoxbrowserserver "FirefoxBrowserServer"
|
|
||||||
[FirefoxPlaywright]: #class-firefoxplaywright "FirefoxPlaywright"
|
[FirefoxPlaywright]: #class-firefoxplaywright "FirefoxPlaywright"
|
||||||
[Frame]: #class-frame "Frame"
|
[Frame]: #class-frame "Frame"
|
||||||
[JSHandle]: #class-jshandle "JSHandle"
|
[JSHandle]: #class-jshandle "JSHandle"
|
||||||
|
|
@ -3809,7 +3747,6 @@ During installation Playwright downloads browser executables, according to revis
|
||||||
[USKeyboardLayout]: ../lib/USKeyboardLayout.js "USKeyboardLayout"
|
[USKeyboardLayout]: ../lib/USKeyboardLayout.js "USKeyboardLayout"
|
||||||
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
|
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
|
||||||
[WebKitBrowser]: #class-webkitbrowser "WebKitBrowser"
|
[WebKitBrowser]: #class-webkitbrowser "WebKitBrowser"
|
||||||
[WebKitBrowserServer]: #class-webkitbrowserserver "WebKitBrowserServer"
|
|
||||||
[WebKitPlaywright]: #class-webkitplaywright "WebKitPlaywright"
|
[WebKitPlaywright]: #class-webkitplaywright "WebKitPlaywright"
|
||||||
[Worker]: #class-worker "Worker"
|
[Worker]: #class-worker "Worker"
|
||||||
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
|
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ export { FFBrowser as FirefoxBrowser } from './firefox/ffBrowser';
|
||||||
export { WKBrowser as WebKitBrowser } from './webkit/wkBrowser';
|
export { WKBrowser as WebKitBrowser } from './webkit/wkBrowser';
|
||||||
|
|
||||||
export { Playwright } from './server/playwright';
|
export { Playwright } from './server/playwright';
|
||||||
export { CRPlaywright as ChromiumPlaywright, CRBrowserServer as ChromiumBrowserServer } from './server/crPlaywright';
|
export { BrowserApp } from './server/browserApp';
|
||||||
export { FFPlaywright as FirefoxPlaywright, FFBrowserServer as FirefoxBrowserServer } from './server/ffPlaywright';
|
export { CRPlaywright as ChromiumPlaywright } from './server/crPlaywright';
|
||||||
export { WKPlaywright as WebKitPlaywright, WKBrowserServer as WebKitBrowserServer } from './server/wkPlaywright';
|
export { FFPlaywright as FirefoxPlaywright } from './server/ffPlaywright';
|
||||||
|
export { WKPlaywright as WebKitPlaywright } from './server/wkPlaywright';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { BrowserContext, BrowserContextOptions } from './browserContext';
|
import { BrowserContext, BrowserContextOptions } from './browserContext';
|
||||||
|
import { ConnectionTransport, SlowMoTransport } from './transport';
|
||||||
import * as platform from './platform';
|
import * as platform from './platform';
|
||||||
|
import { assert } from './helper';
|
||||||
|
|
||||||
export interface Browser extends platform.EventEmitterType {
|
export interface Browser extends platform.EventEmitterType {
|
||||||
newContext(options?: BrowserContextOptions): Promise<BrowserContext>;
|
newContext(options?: BrowserContextOptions): Promise<BrowserContext>;
|
||||||
|
|
@ -26,3 +28,19 @@ export interface Browser extends platform.EventEmitterType {
|
||||||
isConnected(): boolean;
|
isConnected(): boolean;
|
||||||
close(): Promise<void>;
|
close(): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ConnectOptions = {
|
||||||
|
slowMo?: number,
|
||||||
|
browserWSEndpoint?: string;
|
||||||
|
transport?: ConnectionTransport;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function createTransport(options: ConnectOptions): Promise<ConnectionTransport> {
|
||||||
|
assert(Number(!!options.browserWSEndpoint) + Number(!!options.transport) === 1, 'Exactly one of browserWSEndpoint or transport must be passed to connect');
|
||||||
|
let transport: ConnectionTransport | undefined;
|
||||||
|
if (options.transport)
|
||||||
|
transport = options.transport;
|
||||||
|
else if (options.browserWSEndpoint)
|
||||||
|
transport = await platform.createWebSocketTransport(options.browserWSEndpoint);
|
||||||
|
return SlowMoTransport.wrap(transport!, options.slowMo);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,20 +24,12 @@ import { Page, Worker } from '../page';
|
||||||
import { CRTarget } from './crTarget';
|
import { CRTarget } from './crTarget';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { CRPage } from './crPage';
|
import { CRPage } from './crPage';
|
||||||
import { Browser } from '../browser';
|
import { Browser, createTransport, ConnectOptions } from '../browser';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import * as platform from '../platform';
|
import * as platform from '../platform';
|
||||||
import { ConnectionTransport, SlowMoTransport } from '../transport';
|
|
||||||
import { readProtocolStream } from './crProtocolHelper';
|
import { readProtocolStream } from './crProtocolHelper';
|
||||||
|
|
||||||
export type CRConnectOptions = {
|
|
||||||
slowMo?: number,
|
|
||||||
browserWSEndpoint?: string;
|
|
||||||
browserURL?: string;
|
|
||||||
transport?: ConnectionTransport;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class CRBrowser extends platform.EventEmitter implements Browser {
|
export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||||
_connection: CRConnection;
|
_connection: CRConnection;
|
||||||
_client: CRSession;
|
_client: CRSession;
|
||||||
|
|
@ -49,7 +41,7 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||||
private _tracingPath: string | null = '';
|
private _tracingPath: string | null = '';
|
||||||
private _tracingClient: CRSession | undefined;
|
private _tracingClient: CRSession | undefined;
|
||||||
|
|
||||||
static async connect(options: CRConnectOptions): Promise<CRBrowser> {
|
static async connect(options: ConnectOptions): Promise<CRBrowser> {
|
||||||
const transport = await createTransport(options);
|
const transport = await createTransport(options);
|
||||||
const connection = new CRConnection(transport);
|
const connection = new CRConnection(transport);
|
||||||
const { browserContextIds } = await connection.rootSession.send('Target.getBrowserContexts');
|
const { browserContextIds } = await connection.rootSession.send('Target.getBrowserContexts');
|
||||||
|
|
@ -309,24 +301,3 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
||||||
return !this._connection._closed;
|
return !this._connection._closed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTransport(options: CRConnectOptions): Promise<ConnectionTransport> {
|
|
||||||
assert(Number(!!options.browserWSEndpoint) + Number(!!options.browserURL) + Number(!!options.transport) === 1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to connect');
|
|
||||||
let transport: ConnectionTransport | undefined;
|
|
||||||
if (options.transport) {
|
|
||||||
transport = options.transport;
|
|
||||||
} else if (options.browserWSEndpoint) {
|
|
||||||
transport = await platform.createWebSocketTransport(options.browserWSEndpoint);
|
|
||||||
} else if (options.browserURL) {
|
|
||||||
let connectionURL: string;
|
|
||||||
try {
|
|
||||||
const data = await platform.fetchUrl(new URL('/json/version', options.browserURL).href);
|
|
||||||
connectionURL = JSON.parse(data).webSocketDebuggerUrl;
|
|
||||||
} catch (e) {
|
|
||||||
e.message = `Failed to fetch browser webSocket url from ${options.browserURL}: ` + e.message;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
transport = await platform.createWebSocketTransport(connectionURL);
|
|
||||||
}
|
|
||||||
return SlowMoTransport.wrap(transport!, options.slowMo);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -15,25 +15,18 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Browser } from '../browser';
|
import { Browser, createTransport, ConnectOptions } from '../browser';
|
||||||
import { BrowserContext, BrowserContextOptions } from '../browserContext';
|
import { BrowserContext, BrowserContextOptions } from '../browserContext';
|
||||||
import { Events } from '../events';
|
import { Events } from '../events';
|
||||||
import { assert, helper, RegisteredListener } from '../helper';
|
import { assert, helper, RegisteredListener } from '../helper';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { Page } from '../page';
|
import { Page } from '../page';
|
||||||
import { ConnectionTransport, SlowMoTransport } from '../transport';
|
|
||||||
import { ConnectionEvents, FFConnection, FFSessionEvents } from './ffConnection';
|
import { ConnectionEvents, FFConnection, FFSessionEvents } from './ffConnection';
|
||||||
import { FFPage } from './ffPage';
|
import { FFPage } from './ffPage';
|
||||||
import * as platform from '../platform';
|
import * as platform from '../platform';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
|
|
||||||
export type FFConnectOptions = {
|
|
||||||
slowMo?: number,
|
|
||||||
browserWSEndpoint?: string;
|
|
||||||
transport?: ConnectionTransport;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class FFBrowser extends platform.EventEmitter implements Browser {
|
export class FFBrowser extends platform.EventEmitter implements Browser {
|
||||||
_connection: FFConnection;
|
_connection: FFConnection;
|
||||||
_targets: Map<string, Target>;
|
_targets: Map<string, Target>;
|
||||||
|
|
@ -41,7 +34,7 @@ export class FFBrowser extends platform.EventEmitter implements Browser {
|
||||||
private _contexts: Map<string, BrowserContext>;
|
private _contexts: Map<string, BrowserContext>;
|
||||||
private _eventListeners: RegisteredListener[];
|
private _eventListeners: RegisteredListener[];
|
||||||
|
|
||||||
static async connect(options: FFConnectOptions): Promise<FFBrowser> {
|
static async connect(options: ConnectOptions): Promise<FFBrowser> {
|
||||||
const transport = await createTransport(options);
|
const transport = await createTransport(options);
|
||||||
const connection = new FFConnection(transport);
|
const connection = new FFConnection(transport);
|
||||||
const {browserContextIds} = await connection.send('Target.getBrowserContexts');
|
const {browserContextIds} = await connection.send('Target.getBrowserContexts');
|
||||||
|
|
@ -292,13 +285,3 @@ class Target {
|
||||||
return this._browser;
|
return this._browser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTransport(options: FFConnectOptions): Promise<ConnectionTransport> {
|
|
||||||
assert(Number(!!options.browserWSEndpoint) + Number(!!options.transport) === 1, 'Exactly one of browserWSEndpoint or transport must be passed to connect');
|
|
||||||
let transport: ConnectionTransport | undefined;
|
|
||||||
if (options.transport)
|
|
||||||
transport = options.transport;
|
|
||||||
else if (options.browserWSEndpoint)
|
|
||||||
transport = await platform.createWebSocketTransport(options.browserWSEndpoint);
|
|
||||||
return SlowMoTransport.wrap(transport!, options.slowMo);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
46
src/server/browserApp.ts
Normal file
46
src/server/browserApp.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ChildProcess } from 'child_process';
|
||||||
|
import { ConnectOptions } from '../browser';
|
||||||
|
|
||||||
|
export class BrowserApp {
|
||||||
|
private _process: ChildProcess;
|
||||||
|
private _gracefullyClose: () => Promise<void>;
|
||||||
|
private _connectOptions: ConnectOptions;
|
||||||
|
|
||||||
|
constructor(process: ChildProcess, gracefullyClose: () => Promise<void>, connectOptions: ConnectOptions) {
|
||||||
|
this._process = process;
|
||||||
|
this._gracefullyClose = gracefullyClose;
|
||||||
|
this._connectOptions = connectOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(): ChildProcess {
|
||||||
|
return this._process;
|
||||||
|
}
|
||||||
|
|
||||||
|
wsEndpoint(): string | null {
|
||||||
|
return this._connectOptions.browserWSEndpoint || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectOptions(): ConnectOptions {
|
||||||
|
return this._connectOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
async close(): Promise<void> {
|
||||||
|
await this._gracefullyClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,14 +23,15 @@ import { BrowserFetcher, BrowserFetcherOptions } from '../server/browserFetcher'
|
||||||
import { DeviceDescriptors } from '../deviceDescriptors';
|
import { DeviceDescriptors } from '../deviceDescriptors';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { assert } from '../helper';
|
import { assert } from '../helper';
|
||||||
import { CRBrowser, CRConnectOptions, createTransport } from '../chromium/crBrowser';
|
import { CRBrowser } from '../chromium/crBrowser';
|
||||||
import * as platform from '../platform';
|
import * as platform from '../platform';
|
||||||
import { TimeoutError } from '../errors';
|
import { TimeoutError } from '../errors';
|
||||||
import { launchProcess, waitForLine } from '../server/processLauncher';
|
import { launchProcess, waitForLine } from '../server/processLauncher';
|
||||||
import { ChildProcess } from 'child_process';
|
|
||||||
import { CRConnection } from '../chromium/crConnection';
|
import { CRConnection } from '../chromium/crConnection';
|
||||||
import { PipeTransport } from './pipeTransport';
|
import { PipeTransport } from './pipeTransport';
|
||||||
import { Playwright } from './playwright';
|
import { Playwright } from './playwright';
|
||||||
|
import { createTransport, ConnectOptions } from '../browser';
|
||||||
|
import { BrowserApp } from './browserApp';
|
||||||
|
|
||||||
export type SlowMoOptions = {
|
export type SlowMoOptions = {
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
|
|
@ -55,34 +56,6 @@ export type LaunchOptions = ChromiumArgOptions & SlowMoOptions & {
|
||||||
pipe?: boolean,
|
pipe?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class CRBrowserServer {
|
|
||||||
private _process: ChildProcess;
|
|
||||||
private _gracefullyClose: () => Promise<void>;
|
|
||||||
private _connectOptions: CRConnectOptions;
|
|
||||||
|
|
||||||
constructor(process: ChildProcess, gracefullyClose: () => Promise<void>, connectOptions: CRConnectOptions) {
|
|
||||||
this._process = process;
|
|
||||||
this._gracefullyClose = gracefullyClose;
|
|
||||||
this._connectOptions = connectOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
process(): ChildProcess {
|
|
||||||
return this._process;
|
|
||||||
}
|
|
||||||
|
|
||||||
wsEndpoint(): string | null {
|
|
||||||
return this._connectOptions.browserWSEndpoint || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectOptions(): CRConnectOptions {
|
|
||||||
return this._connectOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
async close(): Promise<void> {
|
|
||||||
await this._gracefullyClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CRPlaywright implements Playwright {
|
export class CRPlaywright implements Playwright {
|
||||||
private _projectRoot: string;
|
private _projectRoot: string;
|
||||||
readonly _revision: string;
|
readonly _revision: string;
|
||||||
|
|
@ -93,14 +66,14 @@ export class CRPlaywright implements Playwright {
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(options?: LaunchOptions): Promise<CRBrowser> {
|
async launch(options?: LaunchOptions): Promise<CRBrowser> {
|
||||||
const server = await this.launchServer(options);
|
const app = await this.launchBrowserApp(options);
|
||||||
const browser = await CRBrowser.connect(server.connectOptions());
|
const browser = await CRBrowser.connect(app.connectOptions());
|
||||||
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
||||||
browser.close = () => server.close();
|
browser.close = () => app.close();
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchServer(options: LaunchOptions = {}): Promise<CRBrowserServer> {
|
async launchBrowserApp(options: LaunchOptions = {}): Promise<BrowserApp> {
|
||||||
const {
|
const {
|
||||||
ignoreDefaultArgs = false,
|
ignoreDefaultArgs = false,
|
||||||
args = [],
|
args = [],
|
||||||
|
|
@ -165,7 +138,7 @@ export class CRPlaywright implements Playwright {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let connectOptions: CRConnectOptions | undefined;
|
let connectOptions: ConnectOptions | undefined;
|
||||||
if (!usePipe) {
|
if (!usePipe) {
|
||||||
const timeoutError = new TimeoutError(`Timed out after ${timeout} ms while trying to connect to Chromium! The only Chromium revision guaranteed to work is r${this._revision}`);
|
const timeoutError = new TimeoutError(`Timed out after ${timeout} ms while trying to connect to Chromium! The only Chromium revision guaranteed to work is r${this._revision}`);
|
||||||
const match = await waitForLine(launchedProcess, launchedProcess.stderr, /^DevTools listening on (ws:\/\/.*)$/, timeout, timeoutError);
|
const match = await waitForLine(launchedProcess, launchedProcess.stderr, /^DevTools listening on (ws:\/\/.*)$/, timeout, timeoutError);
|
||||||
|
|
@ -175,10 +148,23 @@ export class CRPlaywright implements Playwright {
|
||||||
const transport = new PipeTransport(launchedProcess.stdio[3] as NodeJS.WritableStream, launchedProcess.stdio[4] as NodeJS.ReadableStream);
|
const transport = new PipeTransport(launchedProcess.stdio[3] as NodeJS.WritableStream, launchedProcess.stdio[4] as NodeJS.ReadableStream);
|
||||||
connectOptions = { slowMo, transport };
|
connectOptions = { slowMo, transport };
|
||||||
}
|
}
|
||||||
return new CRBrowserServer(launchedProcess, gracefullyClose, connectOptions);
|
return new BrowserApp(launchedProcess, gracefullyClose, connectOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect(options: CRConnectOptions): Promise<CRBrowser> {
|
async connect(options: ConnectOptions & { browserURL?: string }): Promise<CRBrowser> {
|
||||||
|
if (options.browserURL) {
|
||||||
|
assert(!options.browserWSEndpoint && !options.transport, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to connect');
|
||||||
|
let connectionURL: string;
|
||||||
|
try {
|
||||||
|
const data = await platform.fetchUrl(new URL('/json/version', options.browserURL).href);
|
||||||
|
connectionURL = JSON.parse(data).webSocketDebuggerUrl;
|
||||||
|
} catch (e) {
|
||||||
|
e.message = `Failed to fetch browser webSocket url from ${options.browserURL}: ` + e.message;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
const transport = await platform.createWebSocketTransport(connectionURL);
|
||||||
|
options = { ...options, transport };
|
||||||
|
}
|
||||||
return CRBrowser.connect(options);
|
return CRBrowser.connect(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FFBrowser, FFConnectOptions, createTransport } from '../firefox/ffBrowser';
|
import { FFBrowser } from '../firefox/ffBrowser';
|
||||||
import { BrowserFetcher, BrowserFetcherOptions } from './browserFetcher';
|
import { BrowserFetcher, BrowserFetcherOptions } from './browserFetcher';
|
||||||
import { DeviceDescriptors } from '../deviceDescriptors';
|
import { DeviceDescriptors } from '../deviceDescriptors';
|
||||||
import { launchProcess, waitForLine } from './processLauncher';
|
import { launchProcess, waitForLine } from './processLauncher';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import * as platform from '../platform';
|
import * as platform from '../platform';
|
||||||
import { FFConnection } from '../firefox/ffConnection';
|
import { FFConnection } from '../firefox/ffConnection';
|
||||||
import { ChildProcess } from 'child_process';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
@ -30,6 +29,8 @@ import * as util from 'util';
|
||||||
import { TimeoutError } from '../errors';
|
import { TimeoutError } from '../errors';
|
||||||
import { assert } from '../helper';
|
import { assert } from '../helper';
|
||||||
import { Playwright } from './playwright';
|
import { Playwright } from './playwright';
|
||||||
|
import { createTransport, ConnectOptions } from '../browser';
|
||||||
|
import { BrowserApp } from './browserApp';
|
||||||
|
|
||||||
export type SlowMoOptions = {
|
export type SlowMoOptions = {
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
|
|
@ -52,34 +53,6 @@ export type LaunchOptions = FirefoxArgOptions & SlowMoOptions & {
|
||||||
env?: {[key: string]: string} | undefined,
|
env?: {[key: string]: string} | undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class FFBrowserServer {
|
|
||||||
private _process: ChildProcess;
|
|
||||||
private _gracefullyClose: () => Promise<void>;
|
|
||||||
private _connectOptions: FFConnectOptions;
|
|
||||||
|
|
||||||
constructor(process: ChildProcess, gracefullyClose: () => Promise<void>, connectOptions: FFConnectOptions) {
|
|
||||||
this._process = process;
|
|
||||||
this._gracefullyClose = gracefullyClose;
|
|
||||||
this._connectOptions = connectOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
process(): ChildProcess {
|
|
||||||
return this._process;
|
|
||||||
}
|
|
||||||
|
|
||||||
wsEndpoint(): string | null {
|
|
||||||
return this._connectOptions.browserWSEndpoint || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectOptions(): FFConnectOptions {
|
|
||||||
return this._connectOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
async close(): Promise<void> {
|
|
||||||
await this._gracefullyClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FFPlaywright implements Playwright {
|
export class FFPlaywright implements Playwright {
|
||||||
private _projectRoot: string;
|
private _projectRoot: string;
|
||||||
readonly _revision: string;
|
readonly _revision: string;
|
||||||
|
|
@ -90,14 +63,14 @@ export class FFPlaywright implements Playwright {
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(options: LaunchOptions): Promise<FFBrowser> {
|
async launch(options: LaunchOptions): Promise<FFBrowser> {
|
||||||
const server = await this.launchServer(options);
|
const app = await this.launchBrowserApp(options);
|
||||||
const browser = await FFBrowser.connect(server.connectOptions());
|
const browser = await FFBrowser.connect(app.connectOptions());
|
||||||
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
||||||
browser.close = () => server.close();
|
browser.close = () => app.close();
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchServer(options: LaunchOptions = {}): Promise<FFBrowserServer> {
|
async launchBrowserApp(options: LaunchOptions = {}): Promise<BrowserApp> {
|
||||||
const {
|
const {
|
||||||
ignoreDefaultArgs = false,
|
ignoreDefaultArgs = false,
|
||||||
args = [],
|
args = [],
|
||||||
|
|
@ -136,7 +109,7 @@ export class FFPlaywright implements Playwright {
|
||||||
firefoxExecutable = executablePath;
|
firefoxExecutable = executablePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
let connectOptions: FFConnectOptions | undefined = undefined;
|
let connectOptions: ConnectOptions | undefined = undefined;
|
||||||
|
|
||||||
const { launchedProcess, gracefullyClose } = await launchProcess({
|
const { launchedProcess, gracefullyClose } = await launchProcess({
|
||||||
executablePath: firefoxExecutable,
|
executablePath: firefoxExecutable,
|
||||||
|
|
@ -168,10 +141,10 @@ export class FFPlaywright implements Playwright {
|
||||||
const match = await waitForLine(launchedProcess, launchedProcess.stdout, /^Juggler listening on (ws:\/\/.*)$/, timeout, timeoutError);
|
const match = await waitForLine(launchedProcess, launchedProcess.stdout, /^Juggler listening on (ws:\/\/.*)$/, timeout, timeoutError);
|
||||||
const url = match[1];
|
const url = match[1];
|
||||||
connectOptions = { browserWSEndpoint: url, slowMo };
|
connectOptions = { browserWSEndpoint: url, slowMo };
|
||||||
return new FFBrowserServer(launchedProcess, gracefullyClose, connectOptions);
|
return new BrowserApp(launchedProcess, gracefullyClose, connectOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect(options: FFConnectOptions): Promise<FFBrowser> {
|
async connect(options: ConnectOptions): Promise<FFBrowser> {
|
||||||
return FFBrowser.connect(options);
|
return FFBrowser.connect(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@ import { DeviceDescriptors } from '../deviceDescriptors';
|
||||||
import { TimeoutError } from '../errors';
|
import { TimeoutError } from '../errors';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { WKBrowser } from '../webkit/wkBrowser';
|
import { WKBrowser } from '../webkit/wkBrowser';
|
||||||
import { WKConnectOptions } from '../webkit/wkBrowser';
|
import { execSync } from 'child_process';
|
||||||
import { execSync, ChildProcess } from 'child_process';
|
|
||||||
import { PipeTransport } from './pipeTransport';
|
import { PipeTransport } from './pipeTransport';
|
||||||
import { launchProcess } from './processLauncher';
|
import { launchProcess } from './processLauncher';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
@ -35,6 +34,8 @@ import { Playwright } from './playwright';
|
||||||
import { ConnectionTransport } from '../transport';
|
import { ConnectionTransport } from '../transport';
|
||||||
import * as ws from 'ws';
|
import * as ws from 'ws';
|
||||||
import * as uuidv4 from 'uuid/v4';
|
import * as uuidv4 from 'uuid/v4';
|
||||||
|
import { ConnectOptions } from '../browser';
|
||||||
|
import { BrowserApp } from './browserApp';
|
||||||
|
|
||||||
export type SlowMoOptions = {
|
export type SlowMoOptions = {
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
|
|
@ -58,34 +59,6 @@ export type LaunchOptions = WebKitArgOptions & SlowMoOptions & {
|
||||||
pipe?: boolean,
|
pipe?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class WKBrowserServer {
|
|
||||||
private _process: ChildProcess;
|
|
||||||
private _gracefullyClose: () => Promise<void>;
|
|
||||||
private _connectOptions: WKConnectOptions;
|
|
||||||
|
|
||||||
constructor(process: ChildProcess, gracefullyClose: () => Promise<void>, connectOptions: WKConnectOptions) {
|
|
||||||
this._process = process;
|
|
||||||
this._gracefullyClose = gracefullyClose;
|
|
||||||
this._connectOptions = connectOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
process(): ChildProcess {
|
|
||||||
return this._process;
|
|
||||||
}
|
|
||||||
|
|
||||||
wsEndpoint(): string | null {
|
|
||||||
return this._connectOptions.browserWSEndpoint || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectOptions(): WKConnectOptions {
|
|
||||||
return this._connectOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
async close(): Promise<void> {
|
|
||||||
await this._gracefullyClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WKPlaywright implements Playwright {
|
export class WKPlaywright implements Playwright {
|
||||||
private _projectRoot: string;
|
private _projectRoot: string;
|
||||||
readonly _revision: string;
|
readonly _revision: string;
|
||||||
|
|
@ -96,14 +69,14 @@ export class WKPlaywright implements Playwright {
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(options?: LaunchOptions): Promise<WKBrowser> {
|
async launch(options?: LaunchOptions): Promise<WKBrowser> {
|
||||||
const server = await this.launchServer(options);
|
const app = await this.launchBrowserApp(options);
|
||||||
const browser = await WKBrowser.connect(server.connectOptions());
|
const browser = await WKBrowser.connect(app.connectOptions());
|
||||||
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
// Hack: for typical launch scenario, ensure that close waits for actual process termination.
|
||||||
browser.close = () => server.close();
|
browser.close = () => app.close();
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchServer(options: LaunchOptions = {}): Promise<WKBrowserServer> {
|
async launchBrowserApp(options: LaunchOptions = {}): Promise<BrowserApp> {
|
||||||
const {
|
const {
|
||||||
ignoreDefaultArgs = false,
|
ignoreDefaultArgs = false,
|
||||||
args = [],
|
args = [],
|
||||||
|
|
@ -166,17 +139,17 @@ export class WKPlaywright implements Playwright {
|
||||||
|
|
||||||
transport = new PipeTransport(launchedProcess.stdio[3] as NodeJS.WritableStream, launchedProcess.stdio[4] as NodeJS.ReadableStream);
|
transport = new PipeTransport(launchedProcess.stdio[3] as NodeJS.WritableStream, launchedProcess.stdio[4] as NodeJS.ReadableStream);
|
||||||
|
|
||||||
let connectOptions: WKConnectOptions;
|
let connectOptions: ConnectOptions;
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
const browserWSEndpoint = wrapTransportWithWebSocket(transport);
|
const browserWSEndpoint = wrapTransportWithWebSocket(transport);
|
||||||
connectOptions = { browserWSEndpoint, slowMo };
|
connectOptions = { browserWSEndpoint, slowMo };
|
||||||
} else {
|
} else {
|
||||||
connectOptions = { transport, slowMo };
|
connectOptions = { transport, slowMo };
|
||||||
}
|
}
|
||||||
return new WKBrowserServer(launchedProcess, gracefullyClose, connectOptions);
|
return new BrowserApp(launchedProcess, gracefullyClose, connectOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect(options: WKConnectOptions): Promise<WKBrowser> {
|
async connect(options: ConnectOptions): Promise<WKBrowser> {
|
||||||
return WKBrowser.connect(options);
|
return WKBrowser.connect(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Browser } from '../browser';
|
import { Browser, createTransport, ConnectOptions } from '../browser';
|
||||||
import { BrowserContext, BrowserContextOptions } from '../browserContext';
|
import { BrowserContext, BrowserContextOptions } from '../browserContext';
|
||||||
import { assert, helper, RegisteredListener } from '../helper';
|
import { assert, helper, RegisteredListener } from '../helper';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import { Page } from '../page';
|
import { Page } from '../page';
|
||||||
import { ConnectionTransport, SlowMoTransport } from '../transport';
|
import { ConnectionTransport } from '../transport';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { Events } from '../events';
|
import { Events } from '../events';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
|
|
@ -28,12 +28,6 @@ import { WKConnection, WKSession, kPageProxyMessageReceived, PageProxyMessageRec
|
||||||
import { WKPageProxy } from './wkPageProxy';
|
import { WKPageProxy } from './wkPageProxy';
|
||||||
import * as platform from '../platform';
|
import * as platform from '../platform';
|
||||||
|
|
||||||
export type WKConnectOptions = {
|
|
||||||
slowMo?: number,
|
|
||||||
browserWSEndpoint?: string,
|
|
||||||
transport?: ConnectionTransport,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class WKBrowser extends platform.EventEmitter implements Browser {
|
export class WKBrowser extends platform.EventEmitter implements Browser {
|
||||||
private readonly _connection: WKConnection;
|
private readonly _connection: WKConnection;
|
||||||
private readonly _browserSession: WKSession;
|
private readonly _browserSession: WKSession;
|
||||||
|
|
@ -45,7 +39,7 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
|
||||||
private _firstPageProxyCallback?: () => void;
|
private _firstPageProxyCallback?: () => void;
|
||||||
private readonly _firstPageProxyPromise: Promise<void>;
|
private readonly _firstPageProxyPromise: Promise<void>;
|
||||||
|
|
||||||
static async connect(options: WKConnectOptions): Promise<WKBrowser> {
|
static async connect(options: ConnectOptions): Promise<WKBrowser> {
|
||||||
const transport = await createTransport(options);
|
const transport = await createTransport(options);
|
||||||
const browser = new WKBrowser(transport);
|
const browser = new WKBrowser(transport);
|
||||||
// TODO: figure out the timeout.
|
// TODO: figure out the timeout.
|
||||||
|
|
@ -228,13 +222,3 @@ export class WKBrowser extends platform.EventEmitter implements Browser {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTransport(options: WKConnectOptions): Promise<ConnectionTransport> {
|
|
||||||
assert(Number(!!options.browserWSEndpoint) + Number(!!options.transport) === 1, 'Exactly one of browserWSEndpoint or transport must be passed to connect');
|
|
||||||
let transport: ConnectionTransport | undefined;
|
|
||||||
if (options.transport)
|
|
||||||
transport = options.transport;
|
|
||||||
else if (options.browserWSEndpoint)
|
|
||||||
transport = await platform.createWebSocketTransport(options.browserWSEndpoint);
|
|
||||||
return SlowMoTransport.wrap(transport!, options.slowMo);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import { Protocol } from './protocol';
|
||||||
|
|
||||||
const debugProtocol = platform.debug('pw:protocol');
|
const debugProtocol = platform.debug('pw:protocol');
|
||||||
|
|
||||||
// WKBrowserServer uses this special id to issue Browser.close command which we
|
// WKPlaywright uses this special id to issue Browser.close command which we
|
||||||
// should ignore.
|
// should ignore.
|
||||||
export const kBrowserCloseMessageId = -9999;
|
export const kBrowserCloseMessageId = -9999;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF
|
||||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||||
|
|
||||||
describe('Browser.process', function() {
|
describe('Browser.process', function() {
|
||||||
it('should return child_process instance', async function({browserServer}) {
|
it('should return child_process instance', async function({browserApp}) {
|
||||||
const process = await browserServer.process();
|
const process = await browserApp.process();
|
||||||
expect(process.pid).toBeGreaterThan(0);
|
expect(process.pid).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROMI
|
||||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||||
|
|
||||||
describe('Chromium', function() {
|
describe('Chromium', function() {
|
||||||
it('should work across sessions', async function({browserServer, server, browser, newContext}) {
|
it('should work across sessions', async function({browserApp, server, browser, newContext}) {
|
||||||
expect(browser.browserContexts().length).toBe(2);
|
expect(browser.browserContexts().length).toBe(2);
|
||||||
await newContext();
|
await newContext();
|
||||||
expect(browser.browserContexts().length).toBe(3);
|
expect(browser.browserContexts().length).toBe(3);
|
||||||
const remoteBrowser = await playwright.connect({
|
const remoteBrowser = await playwright.connect({
|
||||||
browserWSEndpoint: browserServer.wsEndpoint()
|
browserWSEndpoint: browserApp.wsEndpoint()
|
||||||
});
|
});
|
||||||
const contexts = remoteBrowser.browserContexts();
|
const contexts = remoteBrowser.browserContexts();
|
||||||
expect(contexts.length).toBe(3);
|
expect(contexts.length).toBe(3);
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
|
|
||||||
describe('Playwright.connect', function() {
|
describe('Playwright.connect', function() {
|
||||||
it('should be able to connect multiple times to the same browser', async({server}) => {
|
it('should be able to connect multiple times to the same browser', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const local = await playwright.connect(browserServer.connectOptions());
|
const local = await playwright.connect(browserApp.connectOptions());
|
||||||
const remote = await playwright.connect({
|
const remote = await playwright.connect({
|
||||||
...defaultBrowserOptions,
|
...defaultBrowserOptions,
|
||||||
browserWSEndpoint: browserServer.wsEndpoint()
|
browserWSEndpoint: browserApp.wsEndpoint()
|
||||||
});
|
});
|
||||||
const page = await remote.defaultContext().newPage();
|
const page = await remote.defaultContext().newPage();
|
||||||
expect(await page.evaluate(() => 7 * 8)).toBe(56);
|
expect(await page.evaluate(() => 7 * 8)).toBe(56);
|
||||||
|
|
@ -36,14 +36,14 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
|
|
||||||
const secondPage = await local.defaultContext().newPage();
|
const secondPage = await local.defaultContext().newPage();
|
||||||
expect(await secondPage.evaluate(() => 7 * 6)).toBe(42, 'original browser should still work');
|
expect(await secondPage.evaluate(() => 7 * 6)).toBe(42, 'original browser should still work');
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should be able to close remote browser', async({server}) => {
|
it('should be able to close remote browser', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const local = await playwright.connect(browserServer.connectOptions());
|
const local = await playwright.connect(browserApp.connectOptions());
|
||||||
const remote = await playwright.connect({
|
const remote = await playwright.connect({
|
||||||
...defaultBrowserOptions,
|
...defaultBrowserOptions,
|
||||||
browserWSEndpoint: browserServer.wsEndpoint()
|
browserWSEndpoint: browserApp.wsEndpoint()
|
||||||
});
|
});
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
utils.waitEvent(local, 'disconnected'),
|
utils.waitEvent(local, 'disconnected'),
|
||||||
|
|
@ -52,9 +52,9 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
});
|
});
|
||||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4197#issuecomment-481793410
|
// @see https://github.com/GoogleChrome/puppeteer/issues/4197#issuecomment-481793410
|
||||||
it('should be able to connect to the same page simultaneously', async({server}) => {
|
it('should be able to connect to the same page simultaneously', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const local = await playwright.connect(browserServer.connectOptions());
|
const local = await playwright.connect(browserApp.connectOptions());
|
||||||
const remote = await playwright.connect({ ...defaultBrowserOptions, browserWSEndpoint: browserServer.wsEndpoint() });
|
const remote = await playwright.connect({ ...defaultBrowserOptions, browserWSEndpoint: browserApp.wsEndpoint() });
|
||||||
const [page1, page2] = await Promise.all([
|
const [page1, page2] = await Promise.all([
|
||||||
new Promise(x => local.once('targetcreated', target => x(target.page()))),
|
new Promise(x => local.once('targetcreated', target => x(target.page()))),
|
||||||
remote.defaultContext().newPage(),
|
remote.defaultContext().newPage(),
|
||||||
|
|
|
||||||
|
|
@ -51,16 +51,16 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
originalBrowser.close();
|
originalBrowser.close();
|
||||||
});
|
});
|
||||||
it('should throw when using both browserWSEndpoint and browserURL', async({server}) => {
|
it('should throw when using both browserWSEndpoint and browserURL', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(Object.assign({}, defaultBrowserOptions, {
|
const browserApp = await playwright.launchBrowserApp(Object.assign({}, defaultBrowserOptions, {
|
||||||
args: ['--remote-debugging-port=21222']
|
args: ['--remote-debugging-port=21222']
|
||||||
}));
|
}));
|
||||||
const browserURL = 'http://127.0.0.1:21222';
|
const browserURL = 'http://127.0.0.1:21222';
|
||||||
|
|
||||||
let error = null;
|
let error = null;
|
||||||
await playwright.connect({browserURL, browserWSEndpoint: browserServer.wsEndpoint()}).catch(e => error = e);
|
await playwright.connect({browserURL, browserWSEndpoint: browserApp.wsEndpoint()}).catch(e => error = e);
|
||||||
expect(error.message).toContain('Exactly one of browserWSEndpoint, browserURL or transport');
|
expect(error.message).toContain('Exactly one of browserWSEndpoint, browserURL or transport');
|
||||||
|
|
||||||
browserServer.close();
|
browserApp.close();
|
||||||
});
|
});
|
||||||
it('should throw when trying to connect to non-existing browser', async({server}) => {
|
it('should throw when trying to connect to non-existing browser', async({server}) => {
|
||||||
const originalBrowser = await playwright.launch(Object.assign({}, defaultBrowserOptions, {
|
const originalBrowser = await playwright.launch(Object.assign({}, defaultBrowserOptions, {
|
||||||
|
|
@ -78,33 +78,33 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
describe('Playwright.launch |pipe| option', function() {
|
describe('Playwright.launch |pipe| option', function() {
|
||||||
it('should support the pipe option', async() => {
|
it('should support the pipe option', async() => {
|
||||||
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
expect((await browser.defaultContext().pages()).length).toBe(1);
|
expect((await browser.defaultContext().pages()).length).toBe(1);
|
||||||
expect(browserServer.wsEndpoint()).toBe(null);
|
expect(browserApp.wsEndpoint()).toBe(null);
|
||||||
const page = await browser.defaultContext().newPage();
|
const page = await browser.defaultContext().newPage();
|
||||||
expect(await page.evaluate('11 * 11')).toBe(121);
|
expect(await page.evaluate('11 * 11')).toBe(121);
|
||||||
await page.close();
|
await page.close();
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should support the pipe argument', async() => {
|
it('should support the pipe argument', async() => {
|
||||||
const options = Object.assign({}, defaultBrowserOptions);
|
const options = Object.assign({}, defaultBrowserOptions);
|
||||||
options.args = ['--remote-debugging-pipe'].concat(options.args || []);
|
options.args = ['--remote-debugging-pipe'].concat(options.args || []);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
expect(browserServer.wsEndpoint()).toBe(null);
|
expect(browserApp.wsEndpoint()).toBe(null);
|
||||||
const page = await browser.defaultContext().newPage();
|
const page = await browser.defaultContext().newPage();
|
||||||
expect(await page.evaluate('11 * 11')).toBe(121);
|
expect(await page.evaluate('11 * 11')).toBe(121);
|
||||||
await page.close();
|
await page.close();
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should fire "disconnected" when closing with pipe', async() => {
|
it('should fire "disconnected" when closing with pipe', async() => {
|
||||||
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
const disconnectedEventPromise = new Promise(resolve => browser.once('disconnected', resolve));
|
const disconnectedEventPromise = new Promise(resolve => browser.once('disconnected', resolve));
|
||||||
// Emulate user exiting browser.
|
// Emulate user exiting browser.
|
||||||
browserServer.process().kill();
|
browserApp.process().kill();
|
||||||
await disconnectedEventPromise;
|
await disconnectedEventPromise;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -127,9 +127,9 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
|
|
||||||
describe('Browser.Events.disconnected', function() {
|
describe('Browser.Events.disconnected', function() {
|
||||||
it('should be emitted when: browser gets closed, disconnected or underlying websocket gets closed', async() => {
|
it('should be emitted when: browser gets closed, disconnected or underlying websocket gets closed', async() => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const originalBrowser = await playwright.connect(browserServer.connectOptions());
|
const originalBrowser = await playwright.connect(browserApp.connectOptions());
|
||||||
const browserWSEndpoint = browserServer.wsEndpoint();
|
const browserWSEndpoint = browserApp.wsEndpoint();
|
||||||
const remoteBrowser1 = await playwright.connect({browserWSEndpoint});
|
const remoteBrowser1 = await playwright.connect({browserWSEndpoint});
|
||||||
const remoteBrowser2 = await playwright.connect({browserWSEndpoint});
|
const remoteBrowser2 = await playwright.connect({browserWSEndpoint});
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
waitEvent(remoteBrowser1, 'disconnected'),
|
waitEvent(remoteBrowser1, 'disconnected'),
|
||||||
waitEvent(originalBrowser, 'disconnected'),
|
waitEvent(originalBrowser, 'disconnected'),
|
||||||
browserServer.close(),
|
browserApp.close(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(disconnectedOriginal).toBe(1);
|
expect(disconnectedOriginal).toBe(1);
|
||||||
|
|
|
||||||
|
|
@ -65,15 +65,15 @@ module.exports.describe = function ({ testRunner, expect, defaultBrowserOptions,
|
||||||
it('should filter out ignored default arguments', async() => {
|
it('should filter out ignored default arguments', async() => {
|
||||||
// Make sure we launch with `--enable-automation` by default.
|
// Make sure we launch with `--enable-automation` by default.
|
||||||
const defaultArgs = playwright.defaultArgs(defaultBrowserOptions);
|
const defaultArgs = playwright.defaultArgs(defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(Object.assign({}, defaultBrowserOptions, {
|
const browserApp = await playwright.launchBrowserApp(Object.assign({}, defaultBrowserOptions, {
|
||||||
// Ignore first and third default argument.
|
// Ignore first and third default argument.
|
||||||
ignoreDefaultArgs: [ defaultArgs[0], defaultArgs[2] ],
|
ignoreDefaultArgs: [ defaultArgs[0], defaultArgs[2] ],
|
||||||
}));
|
}));
|
||||||
const spawnargs = browserServer.process().spawnargs;
|
const spawnargs = browserApp.process().spawnargs;
|
||||||
expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1);
|
expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1);
|
||||||
expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1);
|
expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1);
|
||||||
expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1);
|
expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1);
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
4
test/fixtures/closeme.js
vendored
4
test/fixtures/closeme.js
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
(async() => {
|
(async() => {
|
||||||
const [, , playwrightRoot, product, options] = process.argv;
|
const [, , playwrightRoot, product, options] = process.argv;
|
||||||
const browserServer = await require(playwrightRoot)[product.toLowerCase()].launchServer(JSON.parse(options));
|
const browserApp = await require(playwrightRoot)[product.toLowerCase()].launchBrowserApp(JSON.parse(options));
|
||||||
console.log(browserServer.wsEndpoint());
|
console.log(browserApp.wsEndpoint());
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
2
test/fixtures/dumpio.js
vendored
2
test/fixtures/dumpio.js
vendored
|
|
@ -17,7 +17,7 @@
|
||||||
if (product.toLowerCase() === 'firefox')
|
if (product.toLowerCase() === 'firefox')
|
||||||
options.args.push('-juggler', '-profile');
|
options.args.push('-juggler', '-profile');
|
||||||
try {
|
try {
|
||||||
await require(playwrightRoot)[product.toLowerCase()].launchServer(options);
|
await require(playwrightRoot)[product.toLowerCase()].launchBrowserApp(options);
|
||||||
console.error('Browser launch unexpectedly succeeded.');
|
console.error('Browser launch unexpectedly succeeded.');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,20 +90,20 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
|
|
||||||
describe('Browser.isConnected', () => {
|
describe('Browser.isConnected', () => {
|
||||||
it('should set the browser connected state', async () => {
|
it('should set the browser connected state', async () => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const browserWSEndpoint = browserServer.wsEndpoint();
|
const browserWSEndpoint = browserApp.wsEndpoint();
|
||||||
const remote = await playwright.connect({browserWSEndpoint});
|
const remote = await playwright.connect({browserWSEndpoint});
|
||||||
expect(remote.isConnected()).toBe(true);
|
expect(remote.isConnected()).toBe(true);
|
||||||
await remote.disconnect();
|
await remote.disconnect();
|
||||||
expect(remote.isConnected()).toBe(false);
|
expect(remote.isConnected()).toBe(false);
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should throw when used after isConnected returns false', async({server}) => {
|
it('should throw when used after isConnected returns false', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserServer.wsEndpoint()});
|
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserApp.wsEndpoint()});
|
||||||
const page = await remote.defaultContext().newPage();
|
const page = await remote.defaultContext().newPage();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
browserServer.close(),
|
browserApp.close(),
|
||||||
new Promise(f => remote.once('disconnected', f)),
|
new Promise(f => remote.once('disconnected', f)),
|
||||||
]);
|
]);
|
||||||
expect(remote.isConnected()).toBe(false);
|
expect(remote.isConnected()).toBe(false);
|
||||||
|
|
@ -115,47 +115,47 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
describe('Browser.disconnect', function() {
|
describe('Browser.disconnect', function() {
|
||||||
it('should reject navigation when browser closes', async({server}) => {
|
it('should reject navigation when browser closes', async({server}) => {
|
||||||
server.setRoute('/one-style.css', () => {});
|
server.setRoute('/one-style.css', () => {});
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserServer.wsEndpoint()});
|
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserApp.wsEndpoint()});
|
||||||
const page = await remote.defaultContext().newPage();
|
const page = await remote.defaultContext().newPage();
|
||||||
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', {timeout: 60000}).catch(e => e);
|
const navigationPromise = page.goto(server.PREFIX + '/one-style.html', {timeout: 60000}).catch(e => e);
|
||||||
await server.waitForRequest('/one-style.css');
|
await server.waitForRequest('/one-style.css');
|
||||||
await remote.disconnect();
|
await remote.disconnect();
|
||||||
const error = await navigationPromise;
|
const error = await navigationPromise;
|
||||||
expect(error.message).toBe('Navigation failed because browser has disconnected!');
|
expect(error.message).toBe('Navigation failed because browser has disconnected!');
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should reject waitForSelector when browser closes', async({server}) => {
|
it('should reject waitForSelector when browser closes', async({server}) => {
|
||||||
server.setRoute('/empty.html', () => {});
|
server.setRoute('/empty.html', () => {});
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserServer.wsEndpoint()});
|
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserApp.wsEndpoint()});
|
||||||
const page = await remote.defaultContext().newPage();
|
const page = await remote.defaultContext().newPage();
|
||||||
const watchdog = page.waitForSelector('div', { timeout: 60000 }).catch(e => e);
|
const watchdog = page.waitForSelector('div', { timeout: 60000 }).catch(e => e);
|
||||||
await remote.disconnect();
|
await remote.disconnect();
|
||||||
const error = await watchdog;
|
const error = await watchdog;
|
||||||
expect(error.message).toContain('Protocol error');
|
expect(error.message).toContain('Protocol error');
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should throw if used after disconnect', async({server}) => {
|
it('should throw if used after disconnect', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserServer.wsEndpoint()});
|
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserApp.wsEndpoint()});
|
||||||
const page = await remote.defaultContext().newPage();
|
const page = await remote.defaultContext().newPage();
|
||||||
await remote.disconnect();
|
await remote.disconnect();
|
||||||
const error = await page.evaluate('1 + 1').catch(e => e);
|
const error = await page.evaluate('1 + 1').catch(e => e);
|
||||||
expect(error.message).toContain('has been closed');
|
expect(error.message).toContain('has been closed');
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Browser.close', function() {
|
describe('Browser.close', function() {
|
||||||
it('should terminate network waiters', async({context, server}) => {
|
it('should terminate network waiters', async({context, server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserServer.wsEndpoint()});
|
const remote = await playwright.connect({...defaultBrowserOptions, browserWSEndpoint: browserApp.wsEndpoint()});
|
||||||
const newPage = await remote.defaultContext().newPage();
|
const newPage = await remote.defaultContext().newPage();
|
||||||
const results = await Promise.all([
|
const results = await Promise.all([
|
||||||
newPage.waitForRequest(server.EMPTY_PAGE).catch(e => e),
|
newPage.waitForRequest(server.EMPTY_PAGE).catch(e => e),
|
||||||
newPage.waitForResponse(server.EMPTY_PAGE).catch(e => e),
|
newPage.waitForResponse(server.EMPTY_PAGE).catch(e => e),
|
||||||
browserServer.close()
|
browserApp.close()
|
||||||
]);
|
]);
|
||||||
for (let i = 0; i < 2; i++) {
|
for (let i = 0; i < 2; i++) {
|
||||||
const message = results[i].message;
|
const message = results[i].message;
|
||||||
|
|
@ -167,9 +167,9 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
|
|
||||||
describe('Playwright.connect', function() {
|
describe('Playwright.connect', function() {
|
||||||
it.skip(WEBKIT)('should be able to reconnect to a browser', async({server}) => {
|
it.skip(WEBKIT)('should be able to reconnect to a browser', async({server}) => {
|
||||||
const browserServer = await playwright.launchServer(defaultBrowserOptions);
|
const browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
const browserWSEndpoint = browserServer.wsEndpoint();
|
const browserWSEndpoint = browserApp.wsEndpoint();
|
||||||
const page = await browser.defaultContext().newPage();
|
const page = await browser.defaultContext().newPage();
|
||||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||||
await browser.disconnect();
|
await browser.disconnect();
|
||||||
|
|
@ -185,7 +185,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
' http://localhost:<PORT>/frames/frame.html (uno)',
|
' http://localhost:<PORT>/frames/frame.html (uno)',
|
||||||
]);
|
]);
|
||||||
expect(await restoredPage.evaluate(() => 7 * 8)).toBe(56);
|
expect(await restoredPage.evaluate(() => 7 * 8)).toBe(56);
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -228,15 +228,15 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
it('should filter out ignored default arguments', async() => {
|
it('should filter out ignored default arguments', async() => {
|
||||||
// Make sure we launch with `--enable-automation` by default.
|
// Make sure we launch with `--enable-automation` by default.
|
||||||
const defaultArgs = playwright.defaultArgs(defaultBrowserOptions);
|
const defaultArgs = playwright.defaultArgs(defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(Object.assign({}, defaultBrowserOptions, {
|
const browserApp = await playwright.launchBrowserApp(Object.assign({}, defaultBrowserOptions, {
|
||||||
// Ignore first and third default argument.
|
// Ignore first and third default argument.
|
||||||
ignoreDefaultArgs: [ defaultArgs[0], defaultArgs[2] ],
|
ignoreDefaultArgs: [ defaultArgs[0], defaultArgs[2] ],
|
||||||
}));
|
}));
|
||||||
const spawnargs = browserServer.process().spawnargs;
|
const spawnargs = browserApp.process().spawnargs;
|
||||||
expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1);
|
expect(spawnargs.indexOf(defaultArgs[0])).toBe(-1);
|
||||||
expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1);
|
expect(spawnargs.indexOf(defaultArgs[1])).not.toBe(-1);
|
||||||
expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1);
|
expect(spawnargs.indexOf(defaultArgs[2])).toBe(-1);
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('userDataDir option should restore state', async({server}) => {
|
it('userDataDir option should restore state', async({server}) => {
|
||||||
const userDataDir = await mkdtempAsync(TMP_FOLDER);
|
const userDataDir = await mkdtempAsync(TMP_FOLDER);
|
||||||
|
|
|
||||||
|
|
@ -90,14 +90,14 @@ module.exports.describe = ({testRunner, product, playwrightPath}) => {
|
||||||
|
|
||||||
describe('Browser', function() {
|
describe('Browser', function() {
|
||||||
beforeAll(async state => {
|
beforeAll(async state => {
|
||||||
state.browserServer = await playwright.launchServer(defaultBrowserOptions);
|
state.browserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
state.browser = await playwright.connect(state.browserServer.connectOptions());
|
state.browser = await playwright.connect(state.browserApp.connectOptions());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async state => {
|
afterAll(async state => {
|
||||||
await state.browserServer.close();
|
await state.browserApp.close();
|
||||||
state.browser = null;
|
state.browser = null;
|
||||||
state.browserServer = null;
|
state.browserApp = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async(state, test) => {
|
beforeEach(async(state, test) => {
|
||||||
|
|
@ -106,7 +106,7 @@ module.exports.describe = ({testRunner, product, playwrightPath}) => {
|
||||||
|
|
||||||
let rl;
|
let rl;
|
||||||
if (!WEBKIT) {
|
if (!WEBKIT) {
|
||||||
rl = require('readline').createInterface({ input: state.browserServer.process().stderr });
|
rl = require('readline').createInterface({ input: state.browserApp.process().stderr });
|
||||||
test.output = '';
|
test.output = '';
|
||||||
rl.on('line', onLine);
|
rl.on('line', onLine);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,18 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
|
|
||||||
(CHROMIUM || FFOX) && describe('Web SDK', function() {
|
(CHROMIUM || FFOX) && describe('Web SDK', function() {
|
||||||
beforeAll(async state => {
|
beforeAll(async state => {
|
||||||
state.controlledBrowserServer = await playwright.launchServer({ ...defaultBrowserOptions, pipe: false });
|
state.controlledBrowserApp = await playwright.launchBrowserApp({ ...defaultBrowserOptions, pipe: false });
|
||||||
state.hostBrowserServer = await playwright.launchServer(defaultBrowserOptions);
|
state.hostBrowserApp = await playwright.launchBrowserApp(defaultBrowserOptions);
|
||||||
state.hostBrowser = await playwright.connect(state.hostBrowserServer.connectOptions());
|
state.hostBrowser = await playwright.connect(state.hostBrowserApp.connectOptions());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async state => {
|
afterAll(async state => {
|
||||||
await state.hostBrowserServer.close();
|
await state.hostBrowserApp.close();
|
||||||
state.hostBrowser = null;
|
state.hostBrowser = null;
|
||||||
state.hostBrowserServer = null;
|
state.hostBrowserApp = null;
|
||||||
|
|
||||||
await state.controlledBrowserServer.close();
|
await state.controlledBrowserApp.close();
|
||||||
state.controlledBrowserServer = null;
|
state.controlledBrowserApp = null;
|
||||||
state.webUrl = null;
|
state.webUrl = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ module.exports.describe = function({testRunner, expect, defaultBrowserOptions, p
|
||||||
state.page = await state.hostBrowser.defaultContext().newPage();
|
state.page = await state.hostBrowser.defaultContext().newPage();
|
||||||
state.page.on('console', message => console.log('TEST: ' + message.text()));
|
state.page.on('console', message => console.log('TEST: ' + message.text()));
|
||||||
await state.page.goto(state.sourceServer.PREFIX + '/test/assets/playwrightweb.html');
|
await state.page.goto(state.sourceServer.PREFIX + '/test/assets/playwrightweb.html');
|
||||||
await state.page.evaluate((product, connectOptions) => setup(product, connectOptions), product.toLowerCase(), state.controlledBrowserServer.connectOptions());
|
await state.page.evaluate((product, connectOptions) => setup(product, connectOptions), product.toLowerCase(), state.controlledBrowserApp.connectOptions());
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async state => {
|
afterEach(async state => {
|
||||||
|
|
|
||||||
|
|
@ -24,42 +24,42 @@ module.exports.describe = function ({ testRunner, expect, playwright, defaultBro
|
||||||
describe('Playwright.launch |pipe| option', function() {
|
describe('Playwright.launch |pipe| option', function() {
|
||||||
it('should have websocket by default', async() => {
|
it('should have websocket by default', async() => {
|
||||||
const options = Object.assign({pipe: false}, defaultBrowserOptions);
|
const options = Object.assign({pipe: false}, defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
expect((await browser.defaultContext().pages()).length).toBe(1);
|
expect((await browser.defaultContext().pages()).length).toBe(1);
|
||||||
expect(browserServer.wsEndpoint()).not.toBe(null);
|
expect(browserApp.wsEndpoint()).not.toBe(null);
|
||||||
const page = await browser.defaultContext().newPage();
|
const page = await browser.defaultContext().newPage();
|
||||||
expect(await page.evaluate('11 * 11')).toBe(121);
|
expect(await page.evaluate('11 * 11')).toBe(121);
|
||||||
await page.close();
|
await page.close();
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should support the pipe option', async() => {
|
it('should support the pipe option', async() => {
|
||||||
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
expect((await browser.defaultContext().pages()).length).toBe(1);
|
expect((await browser.defaultContext().pages()).length).toBe(1);
|
||||||
expect(browserServer.wsEndpoint()).toBe(null);
|
expect(browserApp.wsEndpoint()).toBe(null);
|
||||||
const page = await browser.defaultContext().newPage();
|
const page = await browser.defaultContext().newPage();
|
||||||
expect(await page.evaluate('11 * 11')).toBe(121);
|
expect(await page.evaluate('11 * 11')).toBe(121);
|
||||||
await page.close();
|
await page.close();
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
});
|
});
|
||||||
it('should fire "disconnected" when closing with pipe', async() => {
|
it('should fire "disconnected" when closing with pipe', async() => {
|
||||||
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
const options = Object.assign({pipe: true}, defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
const disconnectedEventPromise = new Promise(resolve => browser.once('disconnected', resolve));
|
const disconnectedEventPromise = new Promise(resolve => browser.once('disconnected', resolve));
|
||||||
// Emulate user exiting browser.
|
// Emulate user exiting browser.
|
||||||
process.kill(-browserServer.process().pid, 'SIGKILL');
|
process.kill(-browserApp.process().pid, 'SIGKILL');
|
||||||
await disconnectedEventPromise;
|
await disconnectedEventPromise;
|
||||||
});
|
});
|
||||||
it('should fire "disconnected" when closing with websocket', async() => {
|
it('should fire "disconnected" when closing with websocket', async() => {
|
||||||
const options = Object.assign({pipe: false}, defaultBrowserOptions);
|
const options = Object.assign({pipe: false}, defaultBrowserOptions);
|
||||||
const browserServer = await playwright.launchServer(options);
|
const browserApp = await playwright.launchBrowserApp(options);
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
const disconnectedEventPromise = new Promise(resolve => browser.once('disconnected', resolve));
|
const disconnectedEventPromise = new Promise(resolve => browser.once('disconnected', resolve));
|
||||||
// Emulate user exiting browser.
|
// Emulate user exiting browser.
|
||||||
process.kill(-browserServer.process().pid, 'SIGKILL');
|
process.kill(-browserApp.process().pid, 'SIGKILL');
|
||||||
await disconnectedEventPromise;
|
await disconnectedEventPromise;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ async function generateChromiunProtocol(revision) {
|
||||||
if (revision.local && fs.existsSync(outputPath))
|
if (revision.local && fs.existsSync(outputPath))
|
||||||
return;
|
return;
|
||||||
const playwright = await require('../../index').chromium;
|
const playwright = await require('../../index').chromium;
|
||||||
const browserServer = await playwright.launchServer({executablePath: revision.executablePath});
|
const browserApp = await playwright.launchBrowserApp({executablePath: revision.executablePath});
|
||||||
const origin = browserServer.wsEndpoint().match(/ws:\/\/([0-9A-Za-z:\.]*)\//)[1];
|
const origin = browserApp.wsEndpoint().match(/ws:\/\/([0-9A-Za-z:\.]*)\//)[1];
|
||||||
const browser = await playwright.connect(browserServer.connectOptions());
|
const browser = await playwright.connect(browserApp.connectOptions());
|
||||||
const page = await browser.defaultContext().newPage();
|
const page = await browser.defaultContext().newPage();
|
||||||
await page.goto(`http://${origin}/json/protocol`);
|
await page.goto(`http://${origin}/json/protocol`);
|
||||||
const json = JSON.parse(await page.evaluate(() => document.documentElement.innerText));
|
const json = JSON.parse(await page.evaluate(() => document.documentElement.innerText));
|
||||||
await browserServer.close();
|
await browserApp.close();
|
||||||
fs.writeFileSync(outputPath, jsonToTS(json));
|
fs.writeFileSync(outputPath, jsonToTS(json));
|
||||||
console.log(`Wrote protocol.ts to ${path.relative(process.cwd(), outputPath)}`);
|
console.log(`Wrote protocol.ts to ${path.relative(process.cwd(), outputPath)}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue