diff --git a/docs/README.md b/docs/README.md
index 95effd332e..9114c00b68 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -34,6 +34,11 @@
1. Scraping and verification
- Screenshots
- Evaluation
+1. [Navigation and loading](./loading.md)
+ - [Common scenarios](./loading.md#common-scenarios)
+ - [Loading a popup](./loading.md#loading-a-popup)
+ - [Client-side redirects](./loading.md#unusual-client-side-redirects)
+ - [Navigation after a timeout](./loading.md#click-triggers-navigation-after-a-timeout)
1. [Continuous integration](./ci.md)
- [Docker](./ci.md#docker)
- [GitHub Actions](./ci.md#github-actions)
@@ -46,8 +51,7 @@
- Mocha
- Karma
- Jasmine
- - Jasmine
- Storybooks
1. [Extensibility](./extensibility.md)
- [Custom selector engines](./extensibility.md#custom-selector-engines)
-
+1. [API Reference](./api.md)
diff --git a/docs/core-concepts.md b/docs/core-concepts.md
index 8f30dcb4d2..f95fe6b09c 100644
--- a/docs/core-concepts.md
+++ b/docs/core-concepts.md
@@ -54,7 +54,7 @@ const context = await browser.newContext();
```
Browser contexts can also be used to emulate multi-page scenarios involving
-mobile devices, permissions, locale and color scheme.
+mobile devices, permissions, locale and color scheme.
```js
const { devices } = require('playwright');
@@ -78,13 +78,30 @@ const context = await browser.newContext({
## Pages and frames
A Browser context can have multiple pages. A [`Page`](../api.md#class-page)
-refers to a single tab or a popup window within a browser context. A page can be used to navigate
-to URLs and then interact with elements.
+refers to a single tab or a popup window within a browser context. It should be used to navigate to URLs and interact with the page content.
```js
+// Create a page.
const page = await context.newPage();
+```
+
+```js
+// Navigate explicitly, similar to entering a URL in the browser.
await page.goto('http://example.com');
+// Fill an input.
+await page.fill('#search', 'query');
+```
+
+```js
+// Navigate implicitly by clicking a link.
await page.click('#submit');
+// Expect a new url.
+console.log(page.url());
+```
+
+```js
+// Page can navigate from the script - this will be picked up by Playwright.
+window.location.href = 'https://example.com';
```
A page can have one or more [Frame](../api.md#class-frame) objects attached to
@@ -105,6 +122,8 @@ await frame.fill('#username-input', 'John');
- [class `Page`](./api.md#class-page)
- [class `Frame`](./api.md#class-frame)
+To learn more about navigation and loading, read [this document](loading.md).
+
## Selectors
diff --git a/docs/emulation.md b/docs/emulation.md
index 7589d4d753..61f5106bbc 100644
--- a/docs/emulation.md
+++ b/docs/emulation.md
@@ -22,9 +22,9 @@ Most of these parameters are configured during the browser context construction,
## User agent
```js
- const context = await browser.newContext({
- userAgent: 'My user agent'
- });
+const context = await browser.newContext({
+ userAgent: 'My user agent'
+});
```
All pages created in the context above will share the user agent specified.
@@ -40,44 +40,43 @@ All pages created in the context above will share the user agent specified.
Create a context with custom viewport size:
```js
- const context = await browser.newContext({
- viewport: {
- width: 1280,
- height: 1024
- }
- });
-
+const context = await browser.newContext({
+ viewport: {
+ width: 1280,
+ height: 1024
+ }
+});
```
Resize viewport for individual pages:
```js
- await page.setViewportSize({ 'width': 1600, 'height': 1200 });
+await page.setViewportSize({ 'width': 1600, 'height': 1200 });
```
Emulate desktop device with the high-DPI screen and touch support:
```js
- const context = await browser.newContext({
- viewport: {
- width: 2560,
- height: 1440,
- },
- deviceScaleFactor: 2,
- hasTouch: true
- });
+const context = await browser.newContext({
+ viewport: {
+ width: 2560,
+ height: 1440,
+ },
+ deviceScaleFactor: 2,
+ hasTouch: true
+});
```
Create device with the dark color scheme:
```js
- const context = await browser.newContext({
- colorScheme: 'dark'
- });
+const context = await browser.newContext({
+ colorScheme: 'dark'
+});
```
Change color scheme for individual pages:
```js
- await page.emulateMedia({ colorScheme: 'dark' });
+await page.emulateMedia({ colorScheme: 'dark' });
```
#### API reference
@@ -93,13 +92,13 @@ Change color scheme for individual pages:
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 { chromium, devices } = require('playwright');
+const browser = await chromium.launch();
- const pixel2 = devices['Pixel 2'];
- const context = await browser.newContext({
- ...pixel2,
- });
+const pixel2 = devices['Pixel 2'];
+const context = await browser.newContext({
+ ...pixel2,
+});
```
All pages created in the context above will share the same device parameters.
@@ -114,10 +113,10 @@ All pages created in the context above will share the same device parameters.
## Locale & timezone
```js
- const context = await browser.newContext({
- locale: 'de-DE',
- timezoneId: 'Europe/Berlin',
- });
+const context = await browser.newContext({
+ locale: 'de-DE',
+ timezoneId: 'Europe/Berlin',
+});
```
#### API reference
@@ -130,23 +129,24 @@ All pages created in the context above will share the same device parameters.
Allow all pages in the context to show system notifications:
```js
- const context = await browser.newContext({
- permissions: ['notifications'],
- });
+const context = await browser.newContext({
+ permissions: ['notifications'],
+});
```
Grant all pages in the existing context access to current location:
```js
- await context.grantPermissions(['geolocation']);
+await context.grantPermissions(['geolocation']);
```
Grant notifications access from a specific domain:
```js
- await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
+await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
```
+
Revoke all permissions:
```js
- await context.clearPermissions();
+await context.clearPermissions();
```
#### API reference
@@ -160,16 +160,17 @@ Revoke all permissions:
## Geolocation
Create a context with `"geolocation"` permissions granted:
```js
- const context = await browser.newContext({
- geolocation: { longitude: 48.858455, latitude: 2.294474 },
- permissions: ['geolocation']
- });
+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 };
+await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 };
```
+
**Note** you can only change geolocation for all pages in the context.
#### API reference
diff --git a/docs/input.md b/docs/input.md
index 03374febd0..2a97fd9573 100644
--- a/docs/input.md
+++ b/docs/input.md
@@ -31,7 +31,6 @@ await page.fill('#time', '13-15');
//
await page.fill('#local', '2020-03-02T05:15');
-
```
#### API reference
@@ -131,7 +130,7 @@ await page.dblclick('#item');
await page.click('#item', { button: 'right' });
// Shift click element
-await page.click('#item', { modifiers: 'Shift' });
+await page.click('#item', { modifiers: ['Shift'] });
// Hover over element without clicking
await page.hover('#item');
diff --git a/docs/loading.md b/docs/loading.md
index f287d198ae..3c7d7d4c95 100644
--- a/docs/loading.md
+++ b/docs/loading.md
@@ -8,23 +8,23 @@ Page navigation can be either initiated by the Playwright call:
```js
// Load a page
-await page.goto('https://example.com')
+await page.goto('https://example.com');
// Reload a page
-await page.reload()
+await page.reload();
// Click a link
-await page.click('text="Continue"')
+await page.click('text="Continue"');
```
or by the page itself:
```js
// Programmatic navigation
-window.location.href = 'https://example.com'
+window.location.href = 'https://example.com';
// Single page app navigation
-history.pushState({}, 'title', '#deep-link')
+history.pushState({}, 'title', '#deep-link');
```
Navigation intent may result in being canceled, for example transformed into a download or hitting an unresolved DNS address. Only when the navigation succeeds, page starts **loading** the document.
@@ -66,9 +66,9 @@ Explicit loading handling may be required for more complicated scenarios though.
When popup is opened, explicitly calling [`page.waitForLoadState()`](#pagewaitforloadstatestate-options) ensures that popup is loaded to the desired state.
```js
-const { popup } = await Promise.all([
+const [ popup ] = await Promise.all([
page.waitForEvent('popup'),
- page.click('a[target="_blank"]') // <-- opens popup
+ page.click('a[target="_blank"]'), // <-- opens popup
]);
await popup.waitForLoadState('load');
await popup.evaluate(() => window.globalVariableInitializedByOnLoadHandler);
diff --git a/docs/network.md b/docs/network.md
index 84490da69c..bf1f88f8fe 100644
--- a/docs/network.md
+++ b/docs/network.md
@@ -24,7 +24,7 @@ const context = await browser.newContext({
},
});
const page = await context.newPage();
-awat page.goto('https://example.com');
+await page.goto('https://example.com');
```
You can also use [`browserContext.setHTTPCredentials`](./api.md#browsercontextsethttpcredentialshttpcredentials) to update HTTP credentials of an existing context.
@@ -77,7 +77,7 @@ const { chromium, webkit, firefox } = require('playwright');
const browser = await chromium.launch();
const page = await browser.newPage();
- // Subscribe to 'request' and 'response' events.S
+ // Subscribe to 'request' and 'response' events.
page.on('request', request =>
console.log('>>', request.method(), request.url()));
page.on('response', response =>
@@ -91,8 +91,9 @@ const { chromium, webkit, firefox } = require('playwright');
Or wait for a network response after the button click:
```js
+// Use a glob URL pattern
const [response] = await Promise.all([
- page.waitForResponse('/api/fetch_data'),
+ page.waitForResponse('**/api/fetch_data'),
page.click('button#update'),
]);
```
@@ -100,15 +101,15 @@ const [response] = await Promise.all([
#### Variations
```js
-// User glob URL pattern
+// Use a RegExp
const [response] = await Promise.all([
- page.waitForResponse('**/*'),
+ page.waitForResponse(/\.jpeg$/),
page.click('button#update'),
]);
-// User pattern predicate
+// Use a predicate taking a Response object
const [response] = await Promise.all([
- page.waitForResponse(url => url.includes(token)),
+ page.waitForResponse(response => response.url().includes(token)),
page.click('button#update'),
]);
```
@@ -129,7 +130,7 @@ const [response] = await Promise.all([
You can mock API endpoints via handling the network quests in your Playwright script.
```js
-await page.route('/api/fetch_data', route => route.fulfill({
+await page.route('**/api/fetch_data', route => route.fulfill({
status: 200,
body: testData,
}));
@@ -142,7 +143,7 @@ await page.goto('https://example.com');
// Set up route on the entire browser context.
// It will apply to popup windows and opened links.
-await browserContext.route('/api/login', route => route.fulfill({
+await browserContext.route('**/api/login', route => route.fulfill({
status: 200,
body: 'accept',
}));
@@ -177,8 +178,7 @@ You can continue requests with modifications. Example above removes an HTTP head
```js
// Continue requests as POST.
-await page.route('**/*', route =>
- route.continue({method: 'POST'}));
+await page.route('**/*', route => route.continue({method: 'POST'}));
await page.goto('https://chromium.org');
```