2020-04-20 05:42:40 +03:00
# Network
2020-04-16 19:39:33 +03:00
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
2020-04-20 05:42:40 +03:00
[fetch ](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ) requests, can be tracked, modified and handled.
2020-04-16 19:39:33 +03:00
2020-05-11 19:54:03 +03:00
<!-- GEN:toc - top - level -->
- [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 )
<!-- GEN:stop -->
2020-04-16 19:39:33 +03:00
2020-04-20 05:42:40 +03:00
< br / >
## HTTP Authentication
2020-04-16 19:39:33 +03:00
2020-04-20 05:42:40 +03:00
```js
const context = await browser.newContext({
httpCredentials: {
username: 'bill',
password: 'pa55w0rd',
},
});
const page = await context.newPage();
2020-04-21 00:04:49 +03:00
await page.goto('https://example.com');
2020-04-20 05:42:40 +03:00
```
2020-04-16 19:39:33 +03:00
2020-04-20 05:42:40 +03:00
#### API reference
- [`browser.newContext([options])`](./api.md#browsernewcontextoptions)
< br / >
## Handle file downloads
```js
const [ download ] = await Promise.all([
2020-05-07 22:33:35 +03:00
page.waitForEvent('download'), // < -- start waiting for the download
page.click('button#delayed-download') // < -- perform the action that directly or indirectly initiates it .
2020-04-20 05:42:40 +03:00
]);
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 )
< br / >
## Network events
You can monitor all the requests and responses:
2020-04-16 19:39:33 +03:00
```js
2020-04-16 20:48:38 +03:00
const { chromium, webkit, firefox } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
2020-04-21 00:04:49 +03:00
// Subscribe to 'request' and 'response' events.
2020-04-16 20:48:38 +03:00
page.on('request', request =>
console.log('>>', request.method(), request.url()));
page.on('response', response =>
console.log('< < ', response.status(), response.url()));
await page.goto('https://example.com');
await browser.close();
})();
2020-04-16 19:39:33 +03:00
```
2020-04-20 05:42:40 +03:00
Or wait for a network response after the button click:
2020-04-16 19:39:33 +03:00
```js
2020-04-21 00:04:49 +03:00
// Use a glob URL pattern
2020-04-16 19:39:33 +03:00
const [response] = await Promise.all([
2020-04-21 00:04:49 +03:00
page.waitForResponse('**/api/fetch_data'),
2020-04-16 20:48:38 +03:00
page.click('button#update'),
]);
```
#### Variations
```js
2020-04-21 00:04:49 +03:00
// Use a RegExp
2020-04-16 20:48:38 +03:00
const [response] = await Promise.all([
2020-04-21 00:04:49 +03:00
page.waitForResponse(/\.jpeg$/),
2020-04-16 20:48:38 +03:00
page.click('button#update'),
]);
2020-04-21 00:04:49 +03:00
// Use a predicate taking a Response object
2020-04-16 20:48:38 +03:00
const [response] = await Promise.all([
2020-04-21 00:04:49 +03:00
page.waitForResponse(response => response.url().includes(token)),
2020-04-16 20:48:38 +03:00
page.click('button#update'),
2020-04-16 19:39:33 +03:00
]);
```
#### API reference
2020-04-20 05:42:40 +03:00
- [class `Request` ](./api.md#class-request )
- [class `Response` ](./api.md#class-response )
- [event `'request'` ](./api.md#event-request )
- [event `'response'` ](./api.md#event-response )
2020-04-16 19:39:33 +03:00
- [`page.waitForRequest(urlOrPredicate[, options])`](./api.md#pagewaitforrequesturlorpredicate-options)
- [`page.waitForResponse(urlOrPredicate[, options])`](./api.md#pagewaitforresponseurlorpredicate-options)
2020-04-16 20:48:38 +03:00
< br / >
2020-04-16 19:39:33 +03:00
2020-04-20 05:42:40 +03:00
## Handle requests
2020-04-16 19:39:33 +03:00
```js
2020-04-21 00:04:49 +03:00
await page.route('**/api/fetch_data', route => route.fulfill({
2020-04-16 19:39:33 +03:00
status: 200,
body: testData,
}));
await page.goto('https://example.com');
```
2020-05-03 03:21:46 +03:00
You can mock API endpoints via handling the network quests in your Playwright script.
2020-04-16 20:48:38 +03:00
#### Variations
```js
// Set up route on the entire browser context.
// It will apply to popup windows and opened links.
2020-04-21 00:04:49 +03:00
await browserContext.route('**/api/login', route => route.fulfill({
2020-04-16 20:48:38 +03:00
status: 200,
body: 'accept',
}));
await page.goto('https://example.com');
```
2020-04-16 19:39:33 +03:00
#### API reference
- [`browserContext.route(url, handler)` ](./api.md#browsercontextrouteurl-handler )
2020-04-16 20:48:38 +03:00
- [`browserContext.unroute(url[, handler])`](./api.md#browsercontextunrouteurl-handler)
- [`page.route(url, handler)` ](./api.md#pagerouteurl-handler )
- [`page.unroute(url[, handler])`](./api.md#pageunrouteurl-handler)
- [`Route` ](./api.md#class-route )
2020-04-16 19:39:33 +03:00
2020-04-16 20:48:38 +03:00
< br / >
2020-04-16 19:39:33 +03:00
2020-04-20 05:42:40 +03:00
## Modify requests
2020-04-16 20:48:38 +03:00
```js
2020-05-03 03:21:46 +03:00
// Delete header
2020-04-16 20:48:38 +03:00
await page.route('**/*', route => {
const headers = route.request().headers();
delete headers['X-Secret'];
route.continue({headers});
});
// Continue requests as POST.
2020-04-21 00:04:49 +03:00
await page.route('**/*', route => route.continue({method: 'POST'}));
2020-04-16 20:48:38 +03:00
```
2020-04-16 19:39:33 +03:00
2020-05-03 03:21:46 +03:00
You can continue requests with modifications. Example above removes an HTTP header from the outgoing requests.
2020-04-16 19:39:33 +03:00
2020-04-20 05:42:40 +03:00
## Abort requests
2020-04-16 19:39:33 +03:00
```js
2020-04-20 05:42:40 +03:00
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
2020-05-03 03:21:46 +03:00
// Abort based on the request type
2020-04-20 05:42:40 +03:00
await page.route('**/*', route => {
return route.request().resourceType() === 'image' ?
route.abort() : route.continue();
});
```
2020-04-16 19:39:33 +03:00
#### API reference
2020-04-20 05:42:40 +03:00
- [`page.route(url, handler)` ](./api.md#pagerouteurl-handler )
- [`browserContext.route(url, handler)` ](./api.md#browsercontextrouteurl-handler )
- [`route.abort([errorCode])`](./api.md#routeaborterrorcode)
< br / >