diff --git a/docs/README.md b/docs/README.md index c5c34dfe35a3f..dee85ca51a480 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,20 +17,20 @@ - [Keys and shortcuts](./input.md#keys-and-shortcuts) - [Upload files](./input.md#upload-files) - [Focus element](./input.md#focus-element) -1. Emulation - - User agent - - Viewport, color scheme - - Devices - - Locale & Timezone - - Geolocation - - Permissions -1. Network - - Navigation & load - - Waiting for navigation - - Handling downloads - - Network events - - Mocking network - - Aborting requests +1. [Emulation](./emulation.md) + - [User agent](./emulation.md#user-agent) + - [Viewport, color scheme](./emulation.md#viewport-color-scheme) + - [Devices](./emulation.md#select-options) + - [Locale & Timezone](./emulation.md#locale--timezone) + - [Permissions](./emulation.md#permissions) + - [Geolocation](./emulation.md#geolocation) +1. [Network](./network.md) + - [HTTP Authentication](./network.md#http-authentication) + - [Handle file downloads](./network.md#handle-file-downloads) + - [Network events](./network.md#network-events) + - [Handle requests](./network.md#handle-requests) + - [Modify requests](./network.md#modify-requests) + - [Abort requests](./network.md#abort-requests) 1. Scraping and verification - Screenshots - Evaluation diff --git a/docs/core-concepts.md b/docs/core-concepts.md index d6de7a8bf98d0..3647361cfc181 100644 --- a/docs/core-concepts.md +++ b/docs/core-concepts.md @@ -36,6 +36,10 @@ await browser.close(); Launching a browser instance can be expensive, and Playwright is designed to maximize what a single instance can do through multiple browser contexts. +#### API reference + +- [class `Browser`](./api.md#class-browser) +
## Browser contexts @@ -65,6 +69,10 @@ const context = await browser.newContext({ }); ``` +#### API reference + +- [class `BrowserContext`](./api.md#class-browser-context) +
## Pages and frames @@ -92,6 +100,11 @@ const frame = page.frame('frame-login'); await frame.fill('#username-input', 'John'); ``` +#### API reference + +- [class `Page`](./api.md#class-page) +- [class `Frame`](./api.md#class-frame) +
## Selectors @@ -142,6 +155,11 @@ await page.fill('#search', 'query'); await page.click('#search'); ``` +#### API reference + +- [page.click(selector[, options])](./api.md#pageclickselector-options) +- [page.fill(selector, value[, options])](./api.md#pagefillselector-value-options) +
## Execution contexts diff --git a/docs/emulation.md b/docs/emulation.md index ec5b8a6d81446..8870c3472ccb0 100644 --- a/docs/emulation.md +++ b/docs/emulation.md @@ -9,32 +9,33 @@ Playwright allows overriding various parameters of the device where the browser Most of these parameters are configured during the browser context construction, but some of them such as viewport size can be changed for individual pages. -
+#### Contents +- [User agent](#user-agent) +- [Viewport, color scheme](#viewport-color-scheme) +- [Devices](#select-options) +- [Locale & Timezone](#locale--timezone) +- [Permissions](#permissions) +- [Geolocation](#geolocation) -## Emulating popular devices +
-Playwright comes with a registry of device parameters for selected mobile devices. It can be used to simulate browser behavior on a mobile device: +## User agent ```js - const { chromium, devices } = require('playwright'); - const browser = await chromium.launch(); - - const pixel2 = devices['Pixel 2']; const context = await browser.newContext({ - ...pixel2, + userAgent: 'My user agent' }); ``` -All pages created in the context above will share the same device parameters. +All pages created in the context above will share the user agent specified. #### API reference -- [`playwright.devices`](./api.md#playwrightdevices) - [`browser.newContext([options])`](./api.md#browsernewcontextoptions)
-## Configuring screen size, touch support, mobile viewport +## Viewport, color scheme Create a context with custom viewport size: @@ -66,18 +67,7 @@ Emulate desktop device with the high-DPI screen and touch support: }); ``` -#### API reference - -- [`browser.newContext([options])`](./api.md#browsernewcontextoptions) -- [`page.setViewportSize(viewportSize)`](./api.md#pagesetviewportsizeviewportsize) - -
- -## Configuring color scheme - Create device with the dark color scheme: - - ```js const context = await browser.newContext({ colorScheme: 'dark' @@ -93,48 +83,57 @@ Change color scheme for individual pages: #### API reference - [`browser.newContext([options])`](./api.md#browsernewcontextoptions) -- [`page.emulateMedia([options])`](./api.md#pageemulatemediaoptions) +- [`page.setViewportSize(viewportSize)`](./api.md#pagesetviewportsizeviewportsize)
-## Locale and timezone +## Devices + +Playwright comes with a registry of device parameters for selected mobile devices. It can be used to simulate browser behavior on a mobile device: ```js + const { chromium, devices } = require('playwright'); + const browser = await chromium.launch(); + + const pixel2 = devices['Pixel 2']; const context = await browser.newContext({ - locale: 'de-DE', - timezoneId: 'Europe/Berlin', + ...pixel2, }); ``` +All pages created in the context above will share the same device parameters. + #### API reference +- [`playwright.devices`](./api.md#playwrightdevices) - [`browser.newContext([options])`](./api.md#browsernewcontextoptions)
-## Geolocation -Create a context with `"geolocation"` permissions granted: +#### API reference + +- [`browser.newContext([options])`](./api.md#browsernewcontextoptions) +- [`page.emulateMedia([options])`](./api.md#pageemulatemediaoptions) + +
+ +## Locale & timezone + ```js const context = await browser.newContext({ - geolocation: { longitude: 48.858455, latitude: 2.294474 }, - permissions: ['geolocation'] + locale: 'de-DE', + timezoneId: 'Europe/Berlin', }); ``` -Change the location later: - -```js - await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 }; -``` -**Note** you can only change geolocation for all pages in the context. #### API reference - [`browser.newContext([options])`](./api.md#browsernewcontextoptions) -- [`browserContext.setGeolocation(geolocation)`](./api.md#browsercontextsetgeolocationgeolocation)
## Permissions + Allow all pages in the context to show system notifications: ```js const context = await browser.newContext({ @@ -163,3 +162,25 @@ Revoke all permissions: - [`browserContext.clearPermissions()`](./api.md#browsercontextclearpermissions)
+ +## Geolocation +Create a context with `"geolocation"` permissions granted: +```js + const context = await browser.newContext({ + geolocation: { longitude: 48.858455, latitude: 2.294474 }, + permissions: ['geolocation'] + }); +``` +Change the location later: + +```js + await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 }; +``` +**Note** you can only change geolocation for all pages in the context. + +#### API reference + +- [`browser.newContext([options])`](./api.md#browsernewcontextoptions) +- [`browserContext.setGeolocation(geolocation)`](./api.md#browsercontextsetgeolocationgeolocation) + +
diff --git a/docs/input.md b/docs/input.md index bbbfd17176fd6..03374febd09fb 100644 --- a/docs/input.md +++ b/docs/input.md @@ -34,7 +34,7 @@ await page.fill('#local', '2020-03-02T05:15'); ``` -#### Reference +#### API reference - [page.fill(selector, value[, options])](./api.md#pagefillselector-value-options) — main frame - [frame.fill(selector, value[, options])](./api.md#framefillselector-value-options) — given frame @@ -54,7 +54,7 @@ await page.uncheck('#subscribe-label'); This is the easiest way to check and uncheck a checkbox. This method can be used on the `input[type=checkbox]` and on the `label` associated with that input. -#### Reference +#### API reference - [page.check(selector[, options])](./api.md#pagecheckselector-options) — main frame - [page.uncheck(selector[, options])](./api.md#pageuncheckselector-options) — main frame @@ -97,7 +97,7 @@ const option = await page.$('#best-option'); await page.selectOption('select#colors', option); ``` -#### Reference +#### API reference - [page.selectOption(selector, values[, options])](./api.md#pageselectoptionselector-values-options) — main frame - [frame.selectOption(selector, values[, options])](./api.md#frameselectoptionselector-values-options) — given frame @@ -140,7 +140,7 @@ await page.hover('#item'); await page.click('#item', { position: { x: 0, y: 0} }); ``` -#### Reference +#### API reference - [page.click(selector[, options])](./api.md#pageclickselector-options) — main frame - [frame.click(selector[, options])](./api.md#frameclickselector-options) — given frame @@ -166,7 +166,7 @@ Note that most of the time, [`page.fill`](#text-input) will just work. You only But sometimes it is important to type into the field character by character, as if it was a user with a real keyboard. This method will emit all the necessary keyboard events, with all the `keydown`, `keyup`, `keypress` events in place. You can even specify the optional `delay` between the key presses to simulate real user behavior. -#### Reference +#### API reference - [page.type(selector, text[, options])](./api.md#pagetypeselector-text-options) — main frame - [frame.type(selector, text[, options])](./api.md#frametypeselector-text-options) — given frame @@ -224,7 +224,7 @@ Shortcuts such as `"Control+o"` or `"Control+Shift+T"` are supported as well. Wh Note that you still need to specify the capital `A` in `Shift-A` to produce the capital character. `Shift-a` produces a lower-case one as if you had the `CapsLock` toggled. -#### Reference +#### API reference - [page.press(selector, key[, options])](./api.md#pagepressselector-key-options) — main frame - [frame.press(selector, key[, options])](./api.md#framepressselector-key-options) — given frame @@ -260,7 +260,7 @@ await page.setInputFiles('input#upload', { await page.setInputFiles('input#upload', []); ``` -#### Reference +#### API reference - [page.setInputFiles(selector, files[, options])](https://github.com/microsoft/playwright/blob/master/docs/api.md#pagesetinputfilesselector-value-options) - [frame.setInputFiles(selector, files[, options])](https://github.com/microsoft/playwright/blob/master/docs/api.md#framesetinputfilesselector-value-options) @@ -279,7 +279,7 @@ await page.focus('input#name'); For the dynamic pages that handle focus events, you can focus the given element. -#### Reference +#### API reference - [page.focus(selector, [options])](https://github.com/microsoft/playwright/blob/master/docs/api.md#pagefocusselector-options) - [frame.focus(selector, [options])](https://github.com/microsoft/playwright/blob/master/docs/api.md#framefocusselector-options) diff --git a/docs/network.md b/docs/network.md index 326b06018a84b..84490da69c652 100644 --- a/docs/network.md +++ b/docs/network.md @@ -1,14 +1,74 @@ -# Working With Network +# Network Playwright provides APIs to **monitor** and **modify** network traffic, both HTTP and HTTPS. Any requests that page does, including [XHRs](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) and -[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) requests, can be tracked and modified. +[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) requests, can be tracked, modified and handled. +#### Contents + - [HTTP Authentication](#http-authentication) + - [Handle file downloads](#handle-file-downloads) + - [Network events](#network-events) + - [Handle requests](#handle-requests) + - [Modify requests](#modify-requests) + - [Abort requests](#abort-requests) -> **NOTE** As of playwright v0.13.0, Playwright is not yet capable of tracking websocket messages. +
+ +## HTTP Authentication +```js +const context = await browser.newContext({ + httpCredentials: { + username: 'bill', + password: 'pa55w0rd', + }, +}); +const page = await context.newPage(); +awat page.goto('https://example.com'); +``` -## Monitor all network activity in page +You can also use [`browserContext.setHTTPCredentials`](./api.md#browsercontextsethttpcredentialshttpcredentials) to update HTTP credentials of an existing context. + +#### API reference + +- [`browser.newContext([options])`](./api.md#browsernewcontextoptions) +- [`browserContext.setHTTPCredentials(httpCredentials)`](./api.md#browsercontextsethttpcredentialshttpcredentials) + +
+ +## Handle file downloads + +```js +const [ download ] = await Promise.all([ + page.waitForEvent('download'), // <-- start waiting for the download + page.click('button#delayed-download') // <-- perform the action that directly or indirectly initiates it. +]); +const path = await download.path(); +``` + +For every attachment downloaded by the page, [`"download"`](https://github.com/microsoft/playwright/blob/master/docs/api.md#event-download) event is emitted. If you create a browser context with the `acceptDownloads: true`, all these attachments are going to be downloaded into a temporary folder. You can obtain the download url, file system path and payload stream using the [`Download`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-download) object from the event. + +#### Variations + +If you have no idea what initiates the download, you can still handle the event: + +```js +page.on('download', download => download.path().then(console.log)); +``` + +Note that handling the event forks the control flow and makes script harder to follow. Your scenario might end while you are downloading a file since your main control flow is not awaiting for this operation to resolve. + +#### API reference + +- [`Download`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-download) +- [`page.on('download')`](https://github.com/microsoft/playwright/blob/master/docs/api.md#event-download) +- [`page.waitForEvent(event)`](https://github.com/microsoft/playwright/blob/master/docs/api.md##pagewaitforeventevent-optionsorpredicate) + +
+ +## Network events + +You can monitor all the requests and responses: ```js const { chromium, webkit, firefox } = require('playwright'); @@ -28,16 +88,7 @@ const { chromium, webkit, firefox } = require('playwright'); })(); ``` -#### API reference - -- [`Request`](./api.md#class-request) -- [`Response`](./api.md#class-response) -- [`event: 'request'`](./api.md#event-request) -- [`event: 'response'`](./api.md#event-response) - -
- -## Wait for a network response after the button click +Or wait for a network response after the button click: ```js const [response] = await Promise.all([ @@ -46,8 +97,6 @@ const [response] = await Promise.all([ ]); ``` -The snippet above clicks a button and waits for the network response that matches the given pattern. - #### Variations ```js @@ -66,12 +115,18 @@ const [response] = await Promise.all([ #### API reference +- [class `Request`](./api.md#class-request) +- [class `Response`](./api.md#class-response) +- [event `'request'`](./api.md#event-request) +- [event `'response'`](./api.md#event-response) - [`page.waitForRequest(urlOrPredicate[, options])`](./api.md#pagewaitforrequesturlorpredicate-options) - [`page.waitForResponse(urlOrPredicate[, options])`](./api.md#pagewaitforresponseurlorpredicate-options)
-## Mock API endpoint with the test data +## Handle requests + +You can mock API endpoints via handling the network quests in your Playwright script. ```js await page.route('/api/fetch_data', route => route.fulfill({ @@ -81,9 +136,6 @@ await page.route('/api/fetch_data', route => route.fulfill({ await page.goto('https://example.com'); ``` -You can also use [`browserContext.route`](./api.md#browsercontextrouteurl-handler) to mock -API endpoints for all the pages in the context. - #### Variations ```js @@ -107,36 +159,7 @@ await page.goto('https://example.com');
-## Abort selected requests - -```js -const page = await browser.newPage(); -await page.route('**/*.{png,jpg,jpeg}', route => route.abort()); -await page.goto('https://example.com'); -``` - -#### Variations - -```js -// Abort requests based on their type. - -await page.route('**/*', route => { - return route.request().resourceType() === 'image' ? - route.abort() : route.continue(); -}); -await page.goto('https://chromium.org'); -``` - -#### API reference - -- [`page.route(url, handler)`](./api.md#pagerouteurl-handler) -- [`browserContext.route(url, handler)`](./api.md#browsercontextrouteurl-handler) -- [`route.abort([errorCode])`](./api.md#routeaborterrorcode) - -
- -## Modify selected requests - +## Modify requests ```js await page.route('**/*', route => { @@ -161,22 +184,30 @@ await page.goto('https://chromium.org');
-## Setup [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) +## Abort requests ```js -const context = await browser.newContext({ - httpCredentials: { - username: 'bill', - password: 'pa55w0rd', - }, -}); -const page = await context.newPage(); -awat page.goto('https://example.com'); +const page = await browser.newPage(); +await page.route('**/*.{png,jpg,jpeg}', route => route.abort()); +await page.goto('https://example.com'); ``` -You can also use [`browserContext.setHTTPCredentials`](./api.md#browsercontextsethttpcredentialshttpcredentials) to update HTTP credentials of an existing context. +#### Variations + +```js +// Abort requests based on their type. + +await page.route('**/*', route => { + return route.request().resourceType() === 'image' ? + route.abort() : route.continue(); +}); +await page.goto('https://chromium.org'); +``` #### API reference -- [`browser.newContext([options])`](./api.md#browsernewcontextoptions) -- [`browserContext.setHTTPCredentials(httpCredentials)`](./api.md#browsercontextsethttpcredentialshttpcredentials) +- [`page.route(url, handler)`](./api.md#pagerouteurl-handler) +- [`browserContext.route(url, handler)`](./api.md#browsercontextrouteurl-handler) +- [`route.abort([errorCode])`](./api.md#routeaborterrorcode) + +
diff --git a/docs/upload-download.md b/docs/upload-download.md deleted file mode 100644 index 556580cc31ad4..0000000000000 --- a/docs/upload-download.md +++ /dev/null @@ -1,102 +0,0 @@ -# Uploading and downloading files - -## Upload a file - -```js -// - -await page.setInputFiles('input#upload', 'myfile.pdf'); -``` - -You can select input files for upload using the `page.setInputFiles` method. It expects first argument to point to an [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) with the type `"file"`. Multiple files can be passed in the array. If some of the file paths are relative, they are resolved relative to the [current working directory](https://nodejs.org/api/process.html#process_process_cwd). Empty array clears the selected files. - -#### Variations - -```js -// Select multiple files. -page.setInputFiles('input#upload', ['file1.txt', 'file2.txt']); - -// Upload buffer from memory, without reading from file. -page.setInputFiles('input#upload', { - name: 'file.txt', - mimeType: 'text/plain', - buffer: Buffer.from('this is test') -}); - -// Remove all the selected files -page.setInputFiles('input#upload', []); -``` - -#### API reference - -- [`page.setInputFiles(selector, files[, options])`](https://github.com/microsoft/playwright/blob/master/docs/api.md#pagesetinputfilesselector-value-options) -- [`frame.setInputFiles(selector, files[, options])`](https://github.com/microsoft/playwright/blob/master/docs/api.md#framesetinputfilesselector-value-options) -- [`elementHandle.setInputFiles(files[, options])`](https://github.com/microsoft/playwright/blob/master/docs/api.md#elementhandlesetinputfilesfiles-options) - -
-
- -## Uploading file using dynamic input element - -Sometimes element that picks files appears dynamically. When this happens, [`"filechooser"`](https://github.com/microsoft/playwright/blob/master/docs/api.md#event-filechooser) event is emitted on the page. It contains the [`FileChooser`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-filechooser) object that can be used to select files: - -```js -const [ fileChooser ] = await Promise.all([ - page.waitForEvent('filechooser'), // <-- start waiting for the file chooser - page.click('button#delayed-select-files') // <-- perform the action that directly or indirectly initiates it. -]); -// Now that both operations resolved, we can use the returned value to select files. -await fileChooser.setFiles(['file1.txt', 'file2.txt']) -``` - -#### Variations - -If you have no idea what invokes the file chooser, you can still handle the event and select files from it: - -```js -page.on('filechooser', async (fileChooser) => { - await fileChooser.setFiles(['file1.txt', 'file2.txt']); -}); -``` - -Note that handling the event forks the control flow and makes script harder to follow. Your scenario might end while you are setting the files since your main control flow is not awaiting for this operation to resolve. - -#### API reference - -- [`FileChooser`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-filechooser) -- [`page.on('filechooser')`](https://github.com/microsoft/playwright/blob/master/docs/api.md#event-filechooser) -- [`page.waitForEvent(event)`](https://github.com/microsoft/playwright/blob/master/docs/api.md##pagewaitforeventevent-optionsorpredicate) - -
-
- -## Handle file downloads - -```js -const [ download ] = await Promise.all([ - page.waitForEvent('download'), // <-- start waiting for the download - page.click('button#delayed-download') // <-- perform the action that directly or indirectly initiates it. -]); -const path = await download.path(); -``` - -For every attachment downloaded by the page, [`"download"`](https://github.com/microsoft/playwright/blob/master/docs/api.md#event-download) event is emitted. If you create a browser context with the `acceptDownloads: true`, all these attachments are going to be downloaded into a temporary folder. You can obtain the download url, file system path and payload stream using the [`Download`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-download) object from the event. - -#### Variations - -If you have no idea what initiates the download, you can still handle the event: - -```js -page.on('download', download => download.path().then(console.log)); -``` - -Note that handling the event forks the control flow and makes script harder to follow. Your scenario might end while you are downloading a file since your main control flow is not awaiting for this operation to resolve. - -#### API reference - -- [`Download`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-download) -- [`page.on('download')`](https://github.com/microsoft/playwright/blob/master/docs/api.md#event-download) -- [`page.waitForEvent(event)`](https://github.com/microsoft/playwright/blob/master/docs/api.md##pagewaitforeventevent-optionsorpredicate) - -
-