Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
25 changes: 22 additions & 3 deletions docs/core-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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
Expand All @@ -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).

<br/>

## Selectors
Expand Down
89 changes: 45 additions & 44 deletions docs/emulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
3 changes: 1 addition & 2 deletions docs/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ await page.fill('#time', '13-15');

// <input id=local type=datetime-local>
await page.fill('#local', '2020-03-02T05:15');

```

#### API reference
Expand Down Expand Up @@ -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');
Expand Down
14 changes: 7 additions & 7 deletions docs/loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 11 additions & 11 deletions docs/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 =>
Expand All @@ -91,24 +91,25 @@ 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'),
]);
```

#### 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'),
]);
```
Expand All @@ -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,
}));
Expand All @@ -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',
}));
Expand Down Expand Up @@ -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');
```

Expand Down