diff --git a/README.md b/README.md index 452575af68ec7..f759cbd13947e 100644 --- a/README.md +++ b/README.md @@ -39,15 +39,15 @@ Playwright can be used to create a browser instance, open pages, and then manipu This code snippet navigates to whatsmyuseragent.org in Chromium, Firefox and WebKit, and saves 3 screenshots. ```js -const pw = require('playwright'); +const playwright = require('playwright'); (async () => { - for (const name of ['chromium', 'firefox', 'webkit']) { - const browser = await pw[name].launch(); + for (const browserType of ['chromium', 'firefox', 'webkit']) { + const browser = await playwright[browserType].launch(); const context = await browser.newContext(); const page = await context.newPage('http://whatsmyuseragent.org/'); - - await page.screenshot({ path: `example-${name}.png` }); + + await page.screenshot({ path: `example-${browserType}.png` }); await browser.close(); } })(); @@ -58,11 +58,11 @@ const pw = require('playwright'); This snippet emulates Mobile Safari on a device at a given geolocation, navigates to maps.google.com, performs action and takes a screenshot. ```js -const pw = require('playwright'); -const iPhone11 = pw.devices['iPhone 11 Pro']; +const { webkit, devices } = require('playwright'); +const iPhone11 = devices['iPhone 11 Pro']; (async () => { - const browser = await pw.webkit.launch(); + const browser = await webkit.launch(); const context = await browser.newContext({ viewport: iPhone11.viewport, userAgent: iPhone11.userAgent, @@ -73,7 +73,7 @@ const iPhone11 = pw.devices['iPhone 11 Pro']; const page = await context.newPage('https://maps.google.com'); await page.click('text="Your location"'); await page.waitForRequest(/.*preview\/pwa/); - await page.screenshot({ path: 'colosseum-iphone.png' }); + await page.screenshot({ path: 'colosseum-iphone.png' }); await browser.close(); })(); ``` @@ -81,11 +81,11 @@ const iPhone11 = pw.devices['iPhone 11 Pro']; And here is the same script for Chrome on Android. ```js -const pw = require('playwright'); -const pixel2 = pw.devices['Pixel 2']; +const { chromium, devices } = require('playwright'); +const pixel2 = devices['Pixel 2']; (async () => { - const browser = await pw.chromium.launch(); + const browser = await chromium.launch(); const context = await browser.newContext({ viewport: pixel2.viewport, userAgent: pixel2.userAgent, @@ -106,10 +106,10 @@ const pixel2 = pw.devices['Pixel 2']; This code snippet navigates to example.com in Firefox, and executes a script in the page context. ```js -const pw = require('playwright'); +const { firefox } = require('playwright'); (async () => { - const browser = await pw.firefox.launch(); // or 'chromium', 'webkit' + const browser = await firefox.launch(); const context = await browser.newContext(); const page = await context.newPage(); diff --git a/docs/api.md b/docs/api.md index c51867ef0d812..0cabbc8c2e3b6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -5,7 +5,8 @@ ##### Table of Contents -- [class: Playwright](#class-playwright) +- [Playwright module](#playwright-module) +- [class: BrowserType](#class-browsertype) - [class: Browser](#class-browser) - [class: BrowserApp](#class-browserapp) - [class: BrowserContext](#class-browsercontext) @@ -24,28 +25,25 @@ - [class: Accessibility](#class-accessibility) - [class: Coverage](#class-coverage) - [class: Worker](#class-worker) -- [class: ChromiumPlaywright](#class-chromiumplaywright) - [class: ChromiumBrowser](#class-chromiumbrowser) - [class: ChromiumSession](#class-chromiumsession) - [class: ChromiumTarget](#class-chromiumtarget) -- [class: FirefoxPlaywright](#class-firefoxplaywright) - [class: FirefoxBrowser](#class-firefoxbrowser) -- [class: WebKitPlaywright](#class-webkitplaywright) - [class: WebKitBrowser](#class-webkitbrowser) - [Working with selectors](#working-with-selectors) - [Working with Chrome Extensions](#working-with-chrome-extensions) - [Downloaded browsers](#downloaded-browsers) -### class: Playwright +### Playwright module Playwright module provides a method to launch a browser instance. The following is a typical example of using Playwright to drive automation: ```js -const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. +const { chromium, firefox, webkit } = require('playwright'); (async () => { - const browser = await playwright.launch(); + const browser = await chromium.launch(); // Or 'firefox' or 'webkit'. const context = await browser.newContext(); const page = await context.newPage('http://example.com'); // other actions... @@ -53,28 +51,33 @@ const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. })(); ``` -See [chromiumPlaywright.launch([options])](#chromiumplaywrightlaunchoptions), [firefoxPlaywright.launch([options])](#firefoxplaywrightlaunchoptions) or [webkitPlaywright.launch([options])](#webkitplaywrightlaunchoptions) for browser-specific launch methods. - Playwright automatically downloads browser executables during installation, see [Downloaded browsers](#downloaded-browsers) for more information. +- [playwright.chromium](#playwrightchromium) - [playwright.devices](#playwrightdevices) - [playwright.errors](#playwrighterrors) -- [playwright.executablePath()](#playwrightexecutablepath) +- [playwright.firefox](#playwrightfirefox) +- [playwright.webkit](#playwrightwebkit) +#### playwright.chromium +- returns: <[BrowserType]> + +This object can be used to launch or connect to Chromium, returning instances of [ChromiumBrowser]. + #### playwright.devices - returns: <[Object]> Returns a list of devices to be used with [`page.emulate(options)`](#pageemulateoptions). Actual list of -devices can be found in [lib/deviceDescriptors.js](https://github.com/Microsoft/playwright/blob/master/src/deviceDescriptors.ts). +devices can be found in [src/deviceDescriptors.ts](https://github.com/Microsoft/playwright/blob/master/src/deviceDescriptors.ts). ```js -const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'. -const iPhone = playwright.devices['iPhone 6']; +const { webkit, devices } = require('playwright'); +const iPhone = devices['iPhone 6']; (async () => { - const browser = await playwright.launch(); + const browser = await webkit.launch(); const context = await browser.newContext({ viewport: iPhone.viewport, userAgent: iPhone.userAgent @@ -93,7 +96,7 @@ Playwright methods might throw errors if they are unable to fulfill a request. F might fail if the selector doesn't match any nodes during the given timeframe. For certain types of errors Playwright uses specific error classes. -These classes are available via [`playwright.errors`](#playwrighterrors) +These classes are available via [`browserType.errors`](#browsertypeerrors) or [`playwright.errors`](#playwrighterrors). An example of handling a timeout error: ```js @@ -106,21 +109,173 @@ try { } ``` -#### playwright.executablePath() -- returns: <[string]> A path where Playwright expects to find bundled browser. +#### playwright.firefox +- returns: <[BrowserType]> + +This object can be used to launch or connect to Firefox, returning instances of [FirefoxBrowser]. + +#### playwright.webkit +- returns: <[BrowserType]> + +This object can be used to launch or connect to WebKit, returning instances of [WebKitBrowser]. + +### class: BrowserType + +BrowserType provides methods to launch a specific browser instance or connect to an existing one. +The following is a typical example of using Playwright to drive automation: +```js +const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'. + +(async () => { + const browser = await chromium.launch(); + const context = await browser.newContext(); + const page = await context.newPage('http://example.com'); + // other actions... + await browser.close(); +})(); +``` + + +- [browserType.connect(options)](#browsertypeconnectoptions) +- [browserType.defaultArgs([options])](#browsertypedefaultargsoptions) +- [browserType.devices](#browsertypedevices) +- [browserType.errors](#browsertypeerrors) +- [browserType.executablePath()](#browsertypeexecutablepath) +- [browserType.launch([options])](#browsertypelaunchoptions) +- [browserType.launchBrowserApp([options])](#browsertypelaunchbrowserappoptions) + + +#### browserType.connect(options) +- `options` <[Object]> + - `browserWSEndpoint` A browser websocket endpoint to connect to. + - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. + - `browserURL` **Chromium-only** 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). + - `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Playwright to use. +- returns: <[Promise]<[Browser]>> + +This methods attaches Playwright to an existing browser instance. + +#### browserType.defaultArgs([options]) +- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields: + - `headless` <[boolean]> Whether to run browser in headless mode. More details for [Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome) and [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true` unless the `devtools` option is `true`. + - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). + - `userDataDir` <[string]> Path to a [User Data Directory](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md). + - `devtools` <[boolean]> **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be set `false`. +- returns: <[Array]<[string]>> + +The default flags that browser will be launched with. + +#### browserType.devices +- returns: <[Object]> + +Returns a list of devices to be used with [`page.emulate(options)`](#pageemulateoptions). Actual list of +devices can be found in [src/deviceDescriptors.ts](https://github.com/Microsoft/playwright/blob/master/src/deviceDescriptors.ts). + +```js +const { webkit } = require('playwright'); +const iPhone = webkit.devices['iPhone 6']; + +(async () => { + const browser = await webkit.launch(); + const context = await browser.newContext({ + viewport: iPhone.viewport, + userAgent: iPhone.userAgent + }); + const page = await context.newPage('http://example.com'); + // other actions... + await browser.close(); +})(); +``` + +#### browserType.errors +- returns: <[Object]> + - `TimeoutError` <[function]> A class of [TimeoutError]. + +Playwright methods might throw errors if they are unable to fulfill a request. For example, [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) +might fail if the selector doesn't match any nodes during the given timeframe. + +For certain types of errors Playwright uses specific error classes. +These classes are available via [`browserType.errors`](#browsertypeerrors) or [`playwright.errors`](#playwrighterrors). + +An example of handling a timeout error: +```js +const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'. +try { + await page.waitForSelector('.foo'); +} catch (e) { + if (e instanceof webkit.errors.TimeoutError) { + // Do something if this is a timeout. + } +} +``` + +#### browserType.executablePath() +- returns: <[string]> A path where Playwright expects to find a bundled browser. + +#### browserType.launch([options]) +- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields: + - `headless` <[boolean]> Whether to run browser in headless mode. More details for [Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome) and [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true` unless the `devtools` option is `true`. + - `executablePath` <[string]> Path to a browser executable to run instead of the bundled one. 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, Firefox or WebKit, use at your own risk. + - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. + - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). + - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`browserType.defaultArgs()`](#browsertypedefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. + - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. + - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. + - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. + - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. + - `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, which stores browser session data like cookies and local storage. More details for [Chromium](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md) and [Firefox](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`. + - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. + - `devtools` <[boolean]> **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be set `false`. +- returns: <[Promise]<[Browser]>> Promise which resolves to browser instance. + + +You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments: +```js +const browser = await chromium.launch({ // Or 'firefox' or 'webkit'. + ignoreDefaultArgs: ['--mute-audio'] +}); +``` + +> **Chromium-only** Playwright can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. +> +> If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested. +> +> In [browserType.launch([options])](#browsertypelaunchoptions) above, any mention of Chromium also applies to Chrome. +> +> 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. + +#### browserType.launchBrowserApp([options]) +- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields: + - `headless` <[boolean]> Whether to run browser in headless mode. More details for [Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome) and [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode). Defaults to `true` unless the `devtools` option is `true`. + - `executablePath` <[string]> Path to a browser executable to run instead of the bundled one. 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, Firefox or WebKit, use at your own risk. + - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. + - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). + - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`browserType.defaultArgs()`](#browsertypedefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. + - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. + - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. + - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. + - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. + - `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, which stores browser session data like cookies and local storage. More details for [Chromium](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md) and [Firefox](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`. + - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. + - `devtools` <[boolean]> **Chromium-only** Whether to auto-open a Developer Tools panel for each tab. If this option is `true`, the `headless` option will be set `false`. +- returns: <[Promise]<[BrowserApp]>> Promise which resolves to the browser app instance. ### class: Browser * extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) -A Browser is created when Playwright connects to a browser instance, either through [`playwright.launch`](#playwrightlaunchoptions) or [`playwright.connect`](#playwrightconnectoptions). +A Browser is created when Playwright connects to a browser instance, either through [`browserType.launch`](#browsertypelaunchoptions) or [`browserType.connect`](#browsertypeconnectoptions). An example of using a [Browser] to create a [Page]: ```js -const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'. +const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'. (async () => { - const browser = await playwright.launch(); + const browser = await firefox.launch(); const context = await browser.newContext(); const page = await context.newPage('https://example.com'); await browser.close(); @@ -129,17 +284,20 @@ const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'. An example of launching a browser executable and connecting to a [Browser] later: ```js -const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'. +const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'. (async () => { - const browserApp = await playwright.launchBrowserApp({ webSocket: true }); + const browserApp = await webkit.launchBrowserApp({ webSocket: true }); const connectOptions = browserApp.connectOptions(); // Use connect options later to establish a connection. - const browser = await playwright.connect(connectOptions); + const browser = await webkit.connect(connectOptions); // Close browser instance. await browserApp.close(); })(); ``` + +See [ChromiumBrowser], [FirefoxBrowser] and [WebKitBrowser] for browser-specific features. Note that [browserType.connect(options)](#browsertypeconnectoptions) and [browserType.launch(options)](#browsertypelaunchoptions) always return a specific browser instance, based on the browser being connected to or launched. + - [event: 'disconnected'](#event-disconnected) - [browser.browserContexts()](#browserbrowsercontexts) @@ -151,9 +309,9 @@ const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'. #### event: 'disconnected' -Emitted when Playwright gets disconnected from the browser instance. This might happen because of one of the following: -- Browser is closed or crashed -- The [`browser.disconnect`](#browserdisconnect) method was called +Emitted when Browser gets disconnected from the browser application. This might happen because of one of the following: +- Browser application is closed or crashed. +- The [`browser.disconnect`](#browserdisconnect) method was called. #### browser.browserContexts() - returns: <[Array]<[BrowserContext]>> @@ -174,7 +332,7 @@ Returns the default browser context. The default browser context can not be clos #### browser.disconnect() - returns: <[Promise]> -Disconnects Playwright from the browser, but leaves the browser process running. After calling `disconnect`, the [Browser] object is considered disposed and cannot be used anymore. +Disconnects Browser from the browser application, but leaves the application process running. After calling `disconnect`, the [Browser] object is considered disposed and cannot be used anymore. #### browser.isConnected() @@ -205,7 +363,7 @@ Creates a new browser context. It won't share cookies/cache with other browser c ```js (async () => { - const browser = await playwright.launch(); + const browser = await playwright.firefox.launch(); // Or 'chromium' or 'webkit'. // Create a new incognito browser context. const context = await browser.newContext(); // Create a new page in a pristine context. @@ -233,15 +391,15 @@ Closes the browser gracefully and makes sure the process is terminated. - `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. +This options object can be passed to [browserType.connect(options)](#browsertypeconnectoptions) to establish connection to the browser. #### browserApp.process() -- returns: Spawned browser server process. +- returns: Spawned browser application process. #### browserApp.wsEndpoint() - returns: 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. +Browser websocket endpoint which can be used as an argument to [browserType.connect(options)] to establish connection to the browser. ### class: BrowserContext @@ -424,10 +582,10 @@ One of the following values: `'log'`, `'debug'`, `'info'`, `'error'`, `'warning' An example of using `Dialog` class: ```js -const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. +const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'. (async () => { - const browser = await playwright.launch(); + const browser = await chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); page.on('dialog', async dialog => { @@ -469,10 +627,10 @@ const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. ElementHandle represents an in-page DOM element. ElementHandles can be created with the [page.$](#pageselector) method. ```js -const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. +const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'. (async () => { - const browser = await playwright.launch(); + const browser = await chromium.launch(); const context = await browser.newContext(); const page = await context.newPage('https://example.com'); const hrefElement = await page.$('a'); @@ -754,10 +912,10 @@ At every point of time, page exposes its current frame tree via the [page.mainFr An example of dumping frame tree: ```js -const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'. +const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'. (async () => { - const browser = await playwright.launch(); + const browser = await firefox.launch(); const context = await browser.newContext(); const page = await context.newPage('https://www.google.com/chrome/browser/canary.html'); dumpFrameTree(page.mainFrame(), ''); @@ -1213,10 +1371,10 @@ await page.waitFor(selector => !!document.querySelector(selector), {}, selector) The `waitForFunction` can be used to observe viewport size change: ```js -const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'. +const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'. (async () => { - const browser = await playwright.launch(); + const browser = await firefox.launch(); const context = await browser.newContext(); const page = await context.newPage(); const watchDog = page.mainFrame().waitForFunction('window.innerWidth < 100'); @@ -1288,10 +1446,10 @@ immediately. If the selector doesn't appear after the `timeout` milliseconds of This method works across navigations: ```js -const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'. +const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'. (async () => { - const browser = await playwright.launch(); + const browser = await webkit.launch(); const context = await browser.newContext(); const page = await context.newPage(); let currentURL; @@ -1597,10 +1755,10 @@ Page provides methods to interact with a single tab or [extension background pag This example creates a page, navigates it to a URL, and then saves a screenshot: ```js -const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'. +const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'. (async () => { - const browser = await playwright.launch(); + const browser = await webkit.launch(); const context = await browser.newContext(); const page = await context.newPage('https://example.com'); await page.screenshot({path: 'screenshot.png'}); @@ -2140,11 +2298,11 @@ If the `playwrightFunction` returns a [Promise], it will be awaited. An example of adding an `md5` function into the page: ```js -const playwright = require('playwright').firefox; // Or 'chromium' or 'webkit'. +const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'. const crypto = require('crypto'); (async () => { - const browser = await playwright.launch(); + const browser = await firefox.launch(); const context = await browser.newContext(); const page = await context.newPage(); page.on('console', msg => console.log(msg.text())); @@ -2164,11 +2322,11 @@ const crypto = require('crypto'); An example of adding a `window.readfile` function into the page: ```js -const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. +const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'. const fs = require('fs'); (async () => { - const browser = await playwright.launch(); + const browser = await chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); page.on('console', msg => console.log(msg.text())); @@ -2660,10 +2818,10 @@ Waits for event to fire and passes its value into the predicate function. Resolv The `waitForFunction` can be used to observe viewport size change: ```js -const playwright = require('playwright').webkit; // Or 'chromium' or 'firefox'. +const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'. (async () => { - const browser = await playwright.launch(); + const browser = await webkit.launch(); const context = await browser.newContext(); const page = await context.newPage(); const watchDog = page.waitForFunction('window.innerWidth < 100'); @@ -2768,10 +2926,10 @@ immediately. If the selector doesn't appear after the `timeout` milliseconds of This method works across navigations: ```js -const playwright = require('playwright').chromium; // Or 'firefox' or 'webkit'. +const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'. (async () => { - const browser = await playwright.launch(); + const browser = await chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); let currentURL; @@ -3085,7 +3243,7 @@ Contains the URL of the WebSocket. * extends: [Error] -TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) or [playwright.launch([options])](#playwrightlaunchoptions). +TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) or [browserType.launch([options])](#browsertypelaunchoptions). ### class: Accessibility @@ -3194,9 +3352,6 @@ for (const entry of coverage) { console.log(`Bytes used: ${usedBytes / totalBytes * 100}%`); ``` -_To output coverage in a form consumable by [Istanbul](https://github.com/istanbuljs), - see [playwright-to-istanbul](https://github.com/istanbuljs/playwright-to-istanbul)._ - - [coverage.startCSSCoverage([options])](#coveragestartcsscoverageoptions) - [coverage.startJSCoverage([options])](#coveragestartjscoverageoptions) @@ -3279,89 +3434,6 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then #### worker.url() - returns: <[string]> -### class: ChromiumPlaywright - -* extends: [Playwright] - - -- [chromiumPlaywright.connect(options)](#chromiumplaywrightconnectoptions) -- [chromiumPlaywright.defaultArgs([options])](#chromiumplaywrightdefaultargsoptions) -- [chromiumPlaywright.launch([options])](#chromiumplaywrightlaunchoptions) -- [chromiumPlaywright.launchBrowserApp([options])](#chromiumplaywrightlaunchbrowserappoptions) - - -#### chromiumPlaywright.connect(options) -- `options` <[Object]> - - `browserWSEndpoint` a browser websocket endpoint to connect to. - - `browserURL` 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]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Playwright to use. -- returns: <[Promise]<[ChromiumBrowser]>> - -This methods attaches Playwright to an existing Chromium instance. - -#### chromiumPlaywright.defaultArgs([options]) -- `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`. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). - - `userDataDir` <[string]> Path to a [User Data Directory](https://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md). - - `devtools` <[boolean]> Whether to auto-open a DevTools panel for each tab. If this option is `true`, the `headless` option will be set `false`. -- returns: <[Array]<[string]>> - -The default flags that Chromium will be launched with. - -#### chromiumPlaywright.launch([options]) -- `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`. - - `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. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). - - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`chromiumPlaywright.defaultArgs()`](#chromiumplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. - - `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://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md). - - `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`. - - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. -- returns: <[Promise]<[ChromiumBrowser]>> Promise which resolves to browser instance. - - -You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments: -```js -const browser = await playwright.launch({ - ignoreDefaultArgs: ['--mute-audio'] -}); -``` - -> **NOTE** Playwright can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. -> -> If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested. -> -> In [chromiumPlaywright.launch([options])](#chromiumplaywrightlaunchoptions) above, any mention of Chromium also applies to Chrome. -> -> 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.launchBrowserApp([options]) -- `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`. - - `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. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). - - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`chromiumPlaywright.defaultArgs()`](#chromiumplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. - - `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://chromium.googlesource.com/chromium/src/+/master/docs/user_data_dir.md). - - `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`. - - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. -- returns: <[Promise]<[BrowserApp]>> Promise which resolves to browser server instance. - ### class: ChromiumBrowser * extends: [Browser] @@ -3539,155 +3611,12 @@ Identifies what kind of target this is. Can be `"page"`, [`"background_page"`](h #### chromiumTarget.url() - returns: <[string]> -### class: FirefoxPlaywright - -* extends: [Playwright] - - -- [firefoxPlaywright.connect(options)](#firefoxplaywrightconnectoptions) -- [firefoxPlaywright.defaultArgs([options])](#firefoxplaywrightdefaultargsoptions) -- [firefoxPlaywright.launch([options])](#firefoxplaywrightlaunchoptions) -- [firefoxPlaywright.launchBrowserApp([options])](#firefoxplaywrightlaunchbrowserappoptions) - - -#### firefoxPlaywright.connect(options) -- `options` <[Object]> - - `browserWSEndpoint` a browser websocket endpoint to connect to. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Playwright to use. -- returns: <[Promise]<[FirefoxBrowser]>> - -This methods attaches Playwright to an existing Firefox instance. - -#### firefoxPlaywright.defaultArgs([options]) -- `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`. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Firefox flags can be found [here](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options). - - `userDataDir` <[string]> Path to a [User Data Directory](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#User_Profile). -- returns: <[Array]<[string]>> - -The default flags that Firefox will be launched with. - -#### firefoxPlaywright.launch([options]) -- `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`. - - `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. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Firefox flags can be found [here](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options). - - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`firefoxPlaywright.defaultArgs()`](#firefoxplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. - - `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). - - `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`. - - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. -- returns: <[Promise]<[FirefoxBrowser]>> Promise which resolves to browser instance. - - -You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments: -```js -const browser = await playwright.launch({ - ignoreDefaultArgs: ['--mute-audio'] -}); -``` - -#### firefoxPlaywright.launchBrowserApp([options]) -- `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`. - - `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. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Firefox flags can be found [here](https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options). - - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`firefoxPlaywright.defaultArgs()`](#firefoxplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. - - `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). - - `env` <[Object]> Specify environment variables that will be visible to the browser. Defaults to `process.env`. - - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. -- returns: <[Promise]<[BrowserApp]>> Promise which resolves to browser server instance. - ### class: FirefoxBrowser * extends: [Browser] Firefox browser instance does not expose Firefox-specific features. - -### class: WebKitPlaywright - -* extends: [Playwright] - - -- [webkitPlaywright.connect(options)](#webkitplaywrightconnectoptions) -- [webkitPlaywright.defaultArgs([options])](#webkitplaywrightdefaultargsoptions) -- [webkitPlaywright.launch([options])](#webkitplaywrightlaunchoptions) -- [webkitPlaywright.launchBrowserApp([options])](#webkitplaywrightlaunchbrowserappoptions) - - -#### webkitPlaywright.connect(options) -- `options` <[Object]> - - `browserWSEndpoint` a browser websocket endpoint to connect to. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Playwright to use. -- returns: <[Promise]<[WebKitBrowser]>> - -This methods attaches Playwright to an existing WebKit instance. - -#### webkitPlaywright.defaultArgs([options]) -- `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`. - - `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. -- returns: <[Array]<[string]>> - -The default flags that WebKit will be launched with. - -#### webkitPlaywright.launch([options]) -- `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`. - - `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. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. - - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. - - `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`. - - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. -- returns: <[Promise]<[WebKitBrowser]>> Promise which resolves to browser instance. - - -You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments: -```js -const browser = await playwright.launch({ - ignoreDefaultArgs: ['--mute-audio'] -}); -``` - -#### webkitPlaywright.launchBrowserApp([options]) -- `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`. - - `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. - - `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. - - `userDataDir` <[string]> Path to a User Data Directory, which stores browser session data like cookies and local storage. - - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. - - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`webKitPlaywright.defaultArgs()`](#webkitplaywrightdefaultargsoptions). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - - `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. - - `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`. - - `webSocket` <[boolean]> Connects to the browser over a WebSocket instead of a pipe. Defaults to `false`. -- returns: <[Promise]<[BrowserApp]>> Promise which resolves to browser server instance. - ### class: WebKitBrowser * extends: [Browser] @@ -3739,18 +3668,18 @@ Playwright can be used for testing Chrome Extensions. The following is code for getting a handle to the [background page](https://developer.chrome.com/extensions/background_pages) of an extension whose source is located in `./my-extension`: ```js -const playwright = require('playwright').chromium; +const { chromium } = require('playwright'); (async () => { const pathToExtension = require('path').join(__dirname, 'my-extension'); - const browser = await playwright.launch({ + const browser = await chromium.launch({ headless: false, args: [ `--disable-extensions-except=${pathToExtension}`, `--load-extension=${pathToExtension}` ] }); - const targets = await browser.chromium.targets(); + const targets = await browser.targets(); const backgroundPageTarget = targets.find(target => target.type() === 'background_page'); const backgroundPage = await backgroundPageTarget.page(); // Test the background page as you would any other page. @@ -3777,11 +3706,11 @@ During installation Playwright downloads browser executables, according to revis [Body]: #class-body "Body" [BrowserApp]: #class-browserapp "BrowserApp" [BrowserContext]: #class-browsercontext "BrowserContext" +[BrowserType]: #class-browsertype "BrowserType" [Browser]: #class-browser "Browser" [Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer" [ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess" [ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser" -[ChromiumPlaywright]: #class-chromiumplaywright "ChromiumPlaywright" [ChromiumSession]: #class-chromiumsession "ChromiumSession" [ChromiumTarget]: #class-chromiumtarget "ChromiumTarget" [ConnectionTransport]: ../lib/WebSocketTransport.js "ConnectionTransport" @@ -3794,7 +3723,6 @@ During installation Playwright downloads browser executables, according to revis [File]: #class-file "https://developer.mozilla.org/en-US/docs/Web/API/File" [FileChooser]: #class-filechooser "FileChooser" [FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser" -[FirefoxPlaywright]: #class-firefoxplaywright "FirefoxPlaywright" [Frame]: #class-frame "Frame" [JSHandle]: #class-jshandle "JSHandle" [Keyboard]: #class-keyboard "Keyboard" @@ -3815,7 +3743,6 @@ During installation Playwright downloads browser executables, according to revis [USKeyboardLayout]: ../lib/USKeyboardLayout.js "USKeyboardLayout" [UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time" [WebKitBrowser]: #class-webkitbrowser "WebKitBrowser" -[WebKitPlaywright]: #class-webkitplaywright "WebKitPlaywright" [WebSocket]: #class-websocket "WebSocket" [Worker]: #class-worker "Worker" [boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean" diff --git a/docs/web.md b/docs/web.md index 42ddb5298947a..50d2c65b65781 100644 --- a/docs/web.md +++ b/docs/web.md @@ -4,10 +4,7 @@ Playwright contains a version bundled for web browsers under `playwright/web.js` installs playwright under `window.playwrightweb`. You can use it in the web page to drive another browser instance. -API consists of a single `connect` function, similar to -[chromiumPlaywright.connect(options)](api.md#chromiumplaywrightconnectoptions), -[firefoxPlaywright.connect(options)](api.md#firefoxplaywrightconnectoptions) and -[webkitPlaywright.connect(options)](api.md#webkitplaywrightconnectoptions). +API consists of a single `connect` function, similar to [browserType.connect(options)](api.md#browsertypeconnectoptions). ```html diff --git a/download-browser.js b/download-browser.js index 5c7d7502fce9b..5cbb6ba5cac27 100644 --- a/download-browser.js +++ b/download-browser.js @@ -15,13 +15,13 @@ */ async function downloadBrowser(browser) { - const playwright = require('.')[browser]; + const browserType = require('.')[browser]; let progressBar = null; let lastDownloadedBytes = 0; function onProgress(downloadedBytes, totalBytes) { if (!progressBar) { const ProgressBar = require('progress'); - progressBar = new ProgressBar(`Downloading ${browser} ${playwright._revision} - ${toMegabytes(totalBytes)} [:bar] :percent :etas `, { + progressBar = new ProgressBar(`Downloading ${browser} ${browserType._revision} - ${toMegabytes(totalBytes)} [:bar] :percent :etas `, { complete: '=', incomplete: ' ', width: 20, @@ -33,7 +33,7 @@ async function downloadBrowser(browser) { progressBar.tick(delta); } - const fetcher = playwright._createBrowserFetcher(); + const fetcher = browserType._createBrowserFetcher(); const revisionInfo = fetcher.revisionInfo(); // Do nothing if the revision is already downloaded. if (revisionInfo.local) diff --git a/index.d.ts b/index.d.ts index 98e5823929c04..3142b386cd289 100644 --- a/index.d.ts +++ b/index.d.ts @@ -15,7 +15,9 @@ */ export * from './lib/api'; -export const chromium: import('./lib/api').ChromiumPlaywright; -export const firefox: import('./lib/api').FirefoxPlaywright; -export const webkit: import('./lib/api').WebKitPlaywright; +export const devices: typeof import('./lib/deviceDescriptors').DeviceDescriptors; +export const errors: { TimeoutError: typeof import('./lib/errors').TimeoutError }; +export const chromium: import('./lib/api').Chromium; +export const firefox: import('./lib/api').Firefox; +export const webkit: import('./lib/api').WebKit; export type PlaywrightWeb = typeof import('./lib/web'); diff --git a/index.js b/index.js index 569b1281a2c8f..4d745cee491bd 100644 --- a/index.js +++ b/index.js @@ -17,7 +17,11 @@ const { helper } = require('./lib/helper'); const api = require('./lib/api'); const packageJson = require('./package.json'); -const { DeviceDescriptors } = require('./lib/deviceDescriptors'); +const DeviceDescriptors = require('./lib/deviceDescriptors'); +const { TimeoutError } = require('./lib/errors'); +const { Chromium } = require('./lib/server/chromium'); +const { Firefox } = require('./lib/server/firefox'); +const { WebKit } = require('./lib/server/webkit'); for (const className in api) { if (typeof api[className] === 'function') @@ -25,8 +29,9 @@ for (const className in api) { } module.exports = { - chromium: new api.ChromiumPlaywright(__dirname, packageJson.playwright.chromium_revision), - firefox: new api.FirefoxPlaywright(__dirname, packageJson.playwright.firefox_revision), - webkit: new api.WebKitPlaywright(__dirname, packageJson.playwright.webkit_revision), - devices: DeviceDescriptors -}; + devices: DeviceDescriptors, + errors: { TimeoutError }, + chromium: new Chromium(__dirname, packageJson.playwright.chromium_revision), + firefox: new Firefox(__dirname, packageJson.playwright.firefox_revision), + webkit: new WebKit(__dirname, packageJson.playwright.webkit_revision), +} diff --git a/prepare.js b/prepare.js index 2ada94891ec24..d9aab333ffe4b 100644 --- a/prepare.js +++ b/prepare.js @@ -54,8 +54,7 @@ async function downloadAndCleanup(browser) { const revisionInfo = await downloadBrowser(browser); // Remove previous revisions. - const playwright = require('.')[browser]; - const fetcher = playwright._createBrowserFetcher(); + const fetcher = require('.')[browser]._createBrowserFetcher(); const localRevisions = await fetcher.localRevisions(); const cleanupOldVersions = localRevisions.filter(revision => revision !== revisionInfo.revision).map(revision => fetcher.remove(revision)); await Promise.all([...cleanupOldVersions]); diff --git a/src/api.ts b/src/api.ts index 134a1f3c82448..ea74b6c6470a0 100644 --- a/src/api.ts +++ b/src/api.ts @@ -35,8 +35,5 @@ export { FFBrowser as FirefoxBrowser } from './firefox/ffBrowser'; export { WKBrowser as WebKitBrowser } from './webkit/wkBrowser'; -export { Playwright } from './server/playwright'; +export { BrowserType } from './server/browserType'; export { BrowserApp } from './server/browserApp'; -export { CRPlaywright as ChromiumPlaywright } from './server/crPlaywright'; -export { FFPlaywright as FirefoxPlaywright } from './server/ffPlaywright'; -export { WKPlaywright as WebKitPlaywright } from './server/wkPlaywright'; diff --git a/src/server/browserType.ts b/src/server/browserType.ts new file mode 100644 index 0000000000000..a12921db095b5 --- /dev/null +++ b/src/server/browserType.ts @@ -0,0 +1,50 @@ +/** + * 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 * as types from '../types'; +import { TimeoutError } from '../errors'; +import { Browser, ConnectOptions } from '../browser'; +import { BrowserApp } from './browserApp'; + +export type BrowserArgOptions = { + headless?: boolean, + args?: string[], + userDataDir?: string, + devtools?: boolean, +}; + +export type LaunchOptions = BrowserArgOptions & { + executablePath?: string, + ignoreDefaultArgs?: boolean | string[], + handleSIGINT?: boolean, + handleSIGTERM?: boolean, + handleSIGHUP?: boolean, + timeout?: number, + dumpio?: boolean, + env?: {[key: string]: string} | undefined, + webSocket?: boolean, + slowMo?: number, // TODO: we probably don't want this in launchBrowserApp. +}; + +export interface BrowserType { + executablePath(): string; + launchBrowserApp(options?: LaunchOptions): Promise; + launch(options?: LaunchOptions): Promise; + defaultArgs(options?: BrowserArgOptions): string[]; + connect(options: ConnectOptions & { browserURL?: string }): Promise; + devices: types.Devices; + errors: { TimeoutError: typeof TimeoutError }; +} diff --git a/src/server/crPlaywright.ts b/src/server/chromium.ts similarity index 94% rename from src/server/crPlaywright.ts rename to src/server/chromium.ts index 4c10b511aae45..cd794798beeb1 100644 --- a/src/server/crPlaywright.ts +++ b/src/server/chromium.ts @@ -29,34 +29,11 @@ import { TimeoutError } from '../errors'; import { launchProcess, waitForLine } from '../server/processLauncher'; import { kBrowserCloseMessageId } from '../chromium/crConnection'; import { PipeTransport } from './pipeTransport'; -import { Playwright } from './playwright'; +import { LaunchOptions, BrowserArgOptions, BrowserType } from './browserType'; import { createTransport, ConnectOptions } from '../browser'; import { BrowserApp } from './browserApp'; -export type SlowMoOptions = { - slowMo?: number, -}; - -export type ChromiumArgOptions = { - headless?: boolean, - args?: string[], - userDataDir?: string, - devtools?: boolean, -}; - -export type LaunchOptions = ChromiumArgOptions & SlowMoOptions & { - executablePath?: string, - ignoreDefaultArgs?: boolean | string[], - handleSIGINT?: boolean, - handleSIGTERM?: boolean, - handleSIGHUP?: boolean, - timeout?: number, - dumpio?: boolean, - env?: {[key: string]: string} | undefined, - webSocket?: boolean, -}; - -export class CRPlaywright implements Playwright { +export class Chromium implements BrowserType { private _projectRoot: string; readonly _revision: string; @@ -184,7 +161,7 @@ export class CRPlaywright implements Playwright { return { TimeoutError }; } - defaultArgs(options: ChromiumArgOptions = {}): string[] { + defaultArgs(options: BrowserArgOptions = {}): string[] { const { devtools = false, headless = !devtools, diff --git a/src/server/ffPlaywright.ts b/src/server/firefox.ts similarity index 95% rename from src/server/ffPlaywright.ts rename to src/server/firefox.ts index d08626a9fabc8..80db28f035e4c 100644 --- a/src/server/ffPlaywright.ts +++ b/src/server/firefox.ts @@ -28,33 +28,11 @@ import * as path from 'path'; import * as util from 'util'; import { TimeoutError } from '../errors'; import { assert } from '../helper'; -import { Playwright } from './playwright'; +import { LaunchOptions, BrowserArgOptions, BrowserType } from './browserType'; import { createTransport, ConnectOptions } from '../browser'; import { BrowserApp } from './browserApp'; -export type SlowMoOptions = { - slowMo?: number, -}; - -export type FirefoxArgOptions = { - headless?: boolean, - args?: string[], - userDataDir?: string, -}; - -export type LaunchOptions = FirefoxArgOptions & SlowMoOptions & { - executablePath?: string, - ignoreDefaultArgs?: boolean | string[], - handleSIGINT?: boolean, - handleSIGTERM?: boolean, - handleSIGHUP?: boolean, - timeout?: number, - dumpio?: boolean, - env?: {[key: string]: string} | undefined, - webSocket?: boolean, -}; - -export class FFPlaywright implements Playwright { +export class Firefox implements BrowserType { private _projectRoot: string; readonly _revision: string; @@ -151,7 +129,9 @@ export class FFPlaywright implements Playwright { return new BrowserApp(launchedProcess, gracefullyClose, connectOptions); } - async connect(options: ConnectOptions): Promise { + async connect(options: ConnectOptions & { browserURL?: string }): Promise { + if (options.browserURL) + throw new Error('Option "browserURL" is not supported by Firefox'); if (options.transport && options.transport.onmessage) throw new Error('Transport is already in use'); return FFBrowser.connect(options); @@ -169,13 +149,15 @@ export class FFPlaywright implements Playwright { return { TimeoutError }; } - // TODO: rename userDataDir to profile? - defaultArgs(options: FirefoxArgOptions = {}): string[] { + defaultArgs(options: BrowserArgOptions = {}): string[] { const { - headless = true, + devtools = false, + headless = !devtools, args = [], userDataDir = null, } = options; + if (devtools) + throw new Error('Option "devtools" is not supported by Firefox'); const firefoxArguments = [...DEFAULT_ARGS]; if (userDataDir) firefoxArguments.push('-profile', userDataDir); diff --git a/src/server/playwright.ts b/src/server/playwright.ts index eb02005efcb65..6547196c62f48 100644 --- a/src/server/playwright.ts +++ b/src/server/playwright.ts @@ -16,9 +16,23 @@ import * as types from '../types'; import { TimeoutError } from '../errors'; +import { DeviceDescriptors } from '../deviceDescriptors'; +import { Chromium } from './chromium'; +import { WebKit } from './webkit'; +import { Firefox } from './firefox'; -export interface Playwright { - executablePath(): string; - devices: types.Devices; - errors: { TimeoutError: typeof TimeoutError }; +export class Playwright { + readonly devices: types.Devices; + readonly errors: { TimeoutError: typeof TimeoutError }; + readonly chromium: Chromium; + readonly firefox: Firefox; + readonly webkit: WebKit; + + constructor(projectRoot: string, revisions: { chromium_revision: string, firefox_revision: string, webkit_revision: string }) { + this.devices = DeviceDescriptors; + this.errors = { TimeoutError }; + this.chromium = new Chromium(projectRoot, revisions.chromium_revision); + this.firefox = new Firefox(projectRoot, revisions.firefox_revision); + this.webkit = new WebKit(projectRoot, revisions.webkit_revision); + } } diff --git a/src/server/wkPlaywright.ts b/src/server/webkit.ts similarity index 92% rename from src/server/wkPlaywright.ts rename to src/server/webkit.ts index 7abc5f03ada08..318b56f08bc2b 100644 --- a/src/server/wkPlaywright.ts +++ b/src/server/webkit.ts @@ -30,36 +30,14 @@ import * as util from 'util'; import * as os from 'os'; import { assert } from '../helper'; import { kBrowserCloseMessageId } from '../webkit/wkConnection'; -import { Playwright } from './playwright'; +import { LaunchOptions, BrowserArgOptions, BrowserType } from './browserType'; import { ConnectionTransport } from '../transport'; import * as ws from 'ws'; import * as uuidv4 from 'uuid/v4'; import { ConnectOptions } from '../browser'; import { BrowserApp } from './browserApp'; -export type SlowMoOptions = { - slowMo?: number, -}; - -export type WebKitArgOptions = { - headless?: boolean, - args?: string[], - userDataDir?: string, -}; - -export type LaunchOptions = WebKitArgOptions & SlowMoOptions & { - executablePath?: string, - ignoreDefaultArgs?: boolean | string[], - handleSIGINT?: boolean, - handleSIGTERM?: boolean, - handleSIGHUP?: boolean, - timeout?: number, - dumpio?: boolean, - env?: {[key: string]: string} | undefined, - webSocket?: boolean, -}; - -export class WKPlaywright implements Playwright { +export class WebKit implements BrowserType { private _projectRoot: string; readonly _revision: string; @@ -151,7 +129,9 @@ export class WKPlaywright implements Playwright { return new BrowserApp(launchedProcess, gracefullyClose, connectOptions); } - async connect(options: ConnectOptions): Promise { + async connect(options: ConnectOptions & { browserURL?: string }): Promise { + if (options.browserURL) + throw new Error('Option "browserURL" is not supported by Firefox'); if (options.transport && options.transport.onmessage) throw new Error('Transport is already in use'); return WKBrowser.connect(options); @@ -169,12 +149,15 @@ export class WKPlaywright implements Playwright { return { TimeoutError }; } - defaultArgs(options: WebKitArgOptions = {}): string[] { + defaultArgs(options: BrowserArgOptions = {}): string[] { const { - headless = true, + devtools = false, + headless = !devtools, args = [], userDataDir = null } = options; + if (devtools) + throw new Error('Option "devtools" is not supported by WebKit'); const webkitArguments = ['--inspector-pipe']; if (userDataDir) webkitArguments.push(`--user-data-dir=${userDataDir}`);