mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(docs): fix snippets, integrate navigations to ToC and core concepts (#1884)
This commit is contained in:
parent
d1a95518be
commit
3485ffb4e6
@ -34,6 +34,11 @@
|
|||||||
1. Scraping and verification
|
1. Scraping and verification
|
||||||
- Screenshots
|
- Screenshots
|
||||||
- Evaluation
|
- 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)
|
1. [Continuous integration](./ci.md)
|
||||||
- [Docker](./ci.md#docker)
|
- [Docker](./ci.md#docker)
|
||||||
- [GitHub Actions](./ci.md#github-actions)
|
- [GitHub Actions](./ci.md#github-actions)
|
||||||
@ -46,8 +51,7 @@
|
|||||||
- Mocha
|
- Mocha
|
||||||
- Karma
|
- Karma
|
||||||
- Jasmine
|
- Jasmine
|
||||||
- Jasmine
|
|
||||||
- Storybooks
|
- Storybooks
|
||||||
1. [Extensibility](./extensibility.md)
|
1. [Extensibility](./extensibility.md)
|
||||||
- [Custom selector engines](./extensibility.md#custom-selector-engines)
|
- [Custom selector engines](./extensibility.md#custom-selector-engines)
|
||||||
|
1. [API Reference](./api.md)
|
||||||
|
@ -54,7 +54,7 @@ const context = await browser.newContext();
|
|||||||
```
|
```
|
||||||
|
|
||||||
Browser contexts can also be used to emulate multi-page scenarios involving
|
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
|
```js
|
||||||
const { devices } = require('playwright');
|
const { devices } = require('playwright');
|
||||||
@ -78,13 +78,30 @@ const context = await browser.newContext({
|
|||||||
## Pages and frames
|
## Pages and frames
|
||||||
|
|
||||||
A Browser context can have multiple pages. A [`Page`](../api.md#class-page)
|
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
|
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.
|
||||||
to URLs and then interact with elements.
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// Create a page.
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Navigate explicitly, similar to entering a URL in the browser.
|
||||||
await page.goto('http://example.com');
|
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');
|
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
|
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 `Page`](./api.md#class-page)
|
||||||
- [class `Frame`](./api.md#class-frame)
|
- [class `Frame`](./api.md#class-frame)
|
||||||
|
|
||||||
|
To learn more about navigation and loading, read [this document](loading.md).
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
## Selectors
|
## Selectors
|
||||||
|
@ -22,9 +22,9 @@ Most of these parameters are configured during the browser context construction,
|
|||||||
## User agent
|
## User agent
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
userAgent: 'My user agent'
|
userAgent: 'My user agent'
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
All pages created in the context above will share the user agent specified.
|
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:
|
Create a context with custom viewport size:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
viewport: {
|
viewport: {
|
||||||
width: 1280,
|
width: 1280,
|
||||||
height: 1024
|
height: 1024
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
```
|
```
|
||||||
Resize viewport for individual pages:
|
Resize viewport for individual pages:
|
||||||
|
|
||||||
```js
|
```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:
|
Emulate desktop device with the high-DPI screen and touch support:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
viewport: {
|
viewport: {
|
||||||
width: 2560,
|
width: 2560,
|
||||||
height: 1440,
|
height: 1440,
|
||||||
},
|
},
|
||||||
deviceScaleFactor: 2,
|
deviceScaleFactor: 2,
|
||||||
hasTouch: true
|
hasTouch: true
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Create device with the dark color scheme:
|
Create device with the dark color scheme:
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
colorScheme: 'dark'
|
colorScheme: 'dark'
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Change color scheme for individual pages:
|
Change color scheme for individual pages:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await page.emulateMedia({ colorScheme: 'dark' });
|
await page.emulateMedia({ colorScheme: 'dark' });
|
||||||
```
|
```
|
||||||
|
|
||||||
#### API reference
|
#### 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:
|
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
|
```js
|
||||||
const { chromium, devices } = require('playwright');
|
const { chromium, devices } = require('playwright');
|
||||||
const browser = await chromium.launch();
|
const browser = await chromium.launch();
|
||||||
|
|
||||||
const pixel2 = devices['Pixel 2'];
|
const pixel2 = devices['Pixel 2'];
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
...pixel2,
|
...pixel2,
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
All pages created in the context above will share the same device parameters.
|
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
|
## Locale & timezone
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
locale: 'de-DE',
|
locale: 'de-DE',
|
||||||
timezoneId: 'Europe/Berlin',
|
timezoneId: 'Europe/Berlin',
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### API reference
|
#### 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:
|
Allow all pages in the context to show system notifications:
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
permissions: ['notifications'],
|
permissions: ['notifications'],
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Grant all pages in the existing context access to current location:
|
Grant all pages in the existing context access to current location:
|
||||||
```js
|
```js
|
||||||
await context.grantPermissions(['geolocation']);
|
await context.grantPermissions(['geolocation']);
|
||||||
```
|
```
|
||||||
|
|
||||||
Grant notifications access from a specific domain:
|
Grant notifications access from a specific domain:
|
||||||
```js
|
```js
|
||||||
await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
|
await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
|
||||||
```
|
```
|
||||||
|
|
||||||
Revoke all permissions:
|
Revoke all permissions:
|
||||||
```js
|
```js
|
||||||
await context.clearPermissions();
|
await context.clearPermissions();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### API reference
|
#### API reference
|
||||||
@ -160,16 +160,17 @@ Revoke all permissions:
|
|||||||
## Geolocation
|
## Geolocation
|
||||||
Create a context with `"geolocation"` permissions granted:
|
Create a context with `"geolocation"` permissions granted:
|
||||||
```js
|
```js
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
geolocation: { longitude: 48.858455, latitude: 2.294474 },
|
geolocation: { longitude: 48.858455, latitude: 2.294474 },
|
||||||
permissions: ['geolocation']
|
permissions: ['geolocation']
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
Change the location later:
|
Change the location later:
|
||||||
|
|
||||||
```js
|
```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.
|
**Note** you can only change geolocation for all pages in the context.
|
||||||
|
|
||||||
#### API reference
|
#### API reference
|
||||||
|
@ -31,7 +31,6 @@ await page.fill('#time', '13-15');
|
|||||||
|
|
||||||
// <input id=local type=datetime-local>
|
// <input id=local type=datetime-local>
|
||||||
await page.fill('#local', '2020-03-02T05:15');
|
await page.fill('#local', '2020-03-02T05:15');
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### API reference
|
#### API reference
|
||||||
@ -131,7 +130,7 @@ await page.dblclick('#item');
|
|||||||
await page.click('#item', { button: 'right' });
|
await page.click('#item', { button: 'right' });
|
||||||
|
|
||||||
// Shift click element
|
// Shift click element
|
||||||
await page.click('#item', { modifiers: 'Shift' });
|
await page.click('#item', { modifiers: ['Shift'] });
|
||||||
|
|
||||||
// Hover over element without clicking
|
// Hover over element without clicking
|
||||||
await page.hover('#item');
|
await page.hover('#item');
|
||||||
|
@ -8,23 +8,23 @@ Page navigation can be either initiated by the Playwright call:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// Load a page
|
// Load a page
|
||||||
await page.goto('https://example.com')
|
await page.goto('https://example.com');
|
||||||
|
|
||||||
// Reload a page
|
// Reload a page
|
||||||
await page.reload()
|
await page.reload();
|
||||||
|
|
||||||
// Click a link
|
// Click a link
|
||||||
await page.click('text="Continue"')
|
await page.click('text="Continue"');
|
||||||
```
|
```
|
||||||
|
|
||||||
or by the page itself:
|
or by the page itself:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Programmatic navigation
|
// Programmatic navigation
|
||||||
window.location.href = 'https://example.com'
|
window.location.href = 'https://example.com';
|
||||||
|
|
||||||
// Single page app navigation
|
// 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.
|
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.
|
When popup is opened, explicitly calling [`page.waitForLoadState()`](#pagewaitforloadstatestate-options) ensures that popup is loaded to the desired state.
|
||||||
```js
|
```js
|
||||||
const { popup } = await Promise.all([
|
const [ popup ] = await Promise.all([
|
||||||
page.waitForEvent('popup'),
|
page.waitForEvent('popup'),
|
||||||
page.click('a[target="_blank"]') // <-- opens popup
|
page.click('a[target="_blank"]'), // <-- opens popup
|
||||||
]);
|
]);
|
||||||
await popup.waitForLoadState('load');
|
await popup.waitForLoadState('load');
|
||||||
await popup.evaluate(() => window.globalVariableInitializedByOnLoadHandler);
|
await popup.evaluate(() => window.globalVariableInitializedByOnLoadHandler);
|
||||||
|
@ -24,7 +24,7 @@ const context = await browser.newContext({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const page = await context.newPage();
|
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.
|
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 browser = await chromium.launch();
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|
||||||
// Subscribe to 'request' and 'response' events.S
|
// Subscribe to 'request' and 'response' events.
|
||||||
page.on('request', request =>
|
page.on('request', request =>
|
||||||
console.log('>>', request.method(), request.url()));
|
console.log('>>', request.method(), request.url()));
|
||||||
page.on('response', response =>
|
page.on('response', response =>
|
||||||
@ -91,8 +91,9 @@ const { chromium, webkit, firefox } = require('playwright');
|
|||||||
Or wait for a network response after the button click:
|
Or wait for a network response after the button click:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// Use a glob URL pattern
|
||||||
const [response] = await Promise.all([
|
const [response] = await Promise.all([
|
||||||
page.waitForResponse('/api/fetch_data'),
|
page.waitForResponse('**/api/fetch_data'),
|
||||||
page.click('button#update'),
|
page.click('button#update'),
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
@ -100,15 +101,15 @@ const [response] = await Promise.all([
|
|||||||
#### Variations
|
#### Variations
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// User glob URL pattern
|
// Use a RegExp
|
||||||
const [response] = await Promise.all([
|
const [response] = await Promise.all([
|
||||||
page.waitForResponse('**/*'),
|
page.waitForResponse(/\.jpeg$/),
|
||||||
page.click('button#update'),
|
page.click('button#update'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// User pattern predicate
|
// Use a predicate taking a Response object
|
||||||
const [response] = await Promise.all([
|
const [response] = await Promise.all([
|
||||||
page.waitForResponse(url => url.includes(token)),
|
page.waitForResponse(response => response.url().includes(token)),
|
||||||
page.click('button#update'),
|
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.
|
You can mock API endpoints via handling the network quests in your Playwright script.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await page.route('/api/fetch_data', route => route.fulfill({
|
await page.route('**/api/fetch_data', route => route.fulfill({
|
||||||
status: 200,
|
status: 200,
|
||||||
body: testData,
|
body: testData,
|
||||||
}));
|
}));
|
||||||
@ -142,7 +143,7 @@ await page.goto('https://example.com');
|
|||||||
// Set up route on the entire browser context.
|
// Set up route on the entire browser context.
|
||||||
// It will apply to popup windows and opened links.
|
// 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,
|
status: 200,
|
||||||
body: 'accept',
|
body: 'accept',
|
||||||
}));
|
}));
|
||||||
@ -177,8 +178,7 @@ You can continue requests with modifications. Example above removes an HTTP head
|
|||||||
```js
|
```js
|
||||||
// Continue requests as POST.
|
// Continue requests as POST.
|
||||||
|
|
||||||
await page.route('**/*', route =>
|
await page.route('**/*', route => route.continue({method: 'POST'}));
|
||||||
route.continue({method: 'POST'}));
|
|
||||||
await page.goto('https://chromium.org');
|
await page.goto('https://chromium.org');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user