From 3485ffb4e67ce51147ebb6fd7a5089a352cc9eb2 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 20 Apr 2020 14:04:49 -0700 Subject: [PATCH] fix(docs): fix snippets, integrate navigations to ToC and core concepts (#1884) --- docs/README.md | 8 +++- docs/core-concepts.md | 25 ++++++++++-- docs/emulation.md | 89 ++++++++++++++++++++++--------------------- docs/input.md | 3 +- docs/loading.md | 14 +++---- docs/network.md | 22 +++++------ 6 files changed, 92 insertions(+), 69 deletions(-) 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'); ```