feat(frame): introduce Frame.goto and Frame.waitForNavigation (#3276)

This patch introduces API to manage frame navigations.
As a drive-by, the `response.frame()` method is added as a shortcut
for `response.request().frame()`.

Fixes #2918.
This commit is contained in:
Andrey Lushnikov
2018-09-20 11:31:19 -07:00
committed by GitHub
parent ad49f792a4
commit 5acf953104
8 changed files with 193 additions and 20 deletions

View File

@@ -194,6 +194,7 @@
* [frame.evaluateHandle(pageFunction, ...args)](#frameevaluatehandlepagefunction-args)
* [frame.executionContext()](#frameexecutioncontext)
* [frame.focus(selector)](#framefocusselector)
* [frame.goto(url, options)](#framegotourl-options)
* [frame.hover(selector)](#framehoverselector)
* [frame.isDetached()](#frameisdetached)
* [frame.name()](#framename)
@@ -206,6 +207,7 @@
* [frame.url()](#frameurl)
* [frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#framewaitforselectororfunctionortimeout-options-args)
* [frame.waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args)
* [frame.waitForNavigation(options)](#framewaitfornavigationoptions)
* [frame.waitForSelector(selector[, options])](#framewaitforselectorselector-options)
* [frame.waitForXPath(xpath[, options])](#framewaitforxpathxpath-options)
- [class: ExecutionContext](#class-executioncontext)
@@ -261,6 +263,7 @@
* [request.url()](#requesturl)
- [class: Response](#class-response)
* [response.buffer()](#responsebuffer)
* [response.frame()](#responseframe)
* [response.fromCache()](#responsefromcache)
* [response.fromServiceWorker()](#responsefromserviceworker)
* [response.headers()](#responseheaders)
@@ -1364,7 +1367,9 @@ The `page.goto` will throw an error if:
> **NOTE** `page.goto` either throw or return a main resource response. The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
> **NOTE** Headless mode doesn't match any nodest navigating to a PDF document. See the [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
> **NOTE** Headless mode doesn't support navigation to a PDF document. See the [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
Shortcut for [page.mainFrame().goto(url, options)](#framegotourl-options)
#### page.hover(selector)
- `selector` <[string]> A [selector] to search for element to hover. If there are multiple elements satisfying the selector, the first will be hovered.
@@ -1801,13 +1806,16 @@ This resolves when the page navigates to a new URL or reloads. It is useful for
which will indirectly cause the page to navigate. Consider this example:
```js
const navigationPromise = page.waitForNavigation();
await page.click('a.my-link'); // Clicking the link will indirectly cause a navigation
await navigationPromise; // The navigationPromise resolves after navigation has finished
const [response] = await Promise.all([
page.waitForNavigation(), // The promise resolves after navigation has finished
page.click('a.my-link'), // Clicking the link will indirectly cause a navigation
]);
```
**NOTE** Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered a navigation.
Shortcut for [page.mainFrame().waitForNavigation(options)](#framewaitfornavigationoptions).
#### page.waitForRequest(urlOrPredicate, options)
- `urlOrPredicate` <[string]|[Function]> A URL or predicate to wait for.
- `options` <[Object]> Optional waiting parameters
@@ -2368,6 +2376,29 @@ Returns promise that resolves to the frame's default execution context.
This method fetches an element with `selector` and focuses it.
If there's no element matching `selector`, the method throws an error.
#### frame.goto(url, options)
- `url` <[string]> URL to navigate frame to. The url should include scheme, e.g. `https://`.
- `options` <[Object]> Navigation parameters which might have the following properties:
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) method.
- `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either:
- `load` - consider navigation to be finished when the `load` event is fired.
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
- `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms.
- `networkidle2` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms.
- `referer` <[string]> Referer header value. If provided it will take preference over the referer header value set by [page.setExtraHTTPHeaders()](#pagesetextrahttpheadersheaders).
- returns: <[Promise]<?[Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
The `frame.goto` will throw an error if:
- there's an SSL error (e.g. in case of self-signed certificates).
- target URL is invalid.
- the `timeout` is exceeded during navigation.
- the main resource failed to load.
> **NOTE** `frame.goto` either throw or return a main resource response. The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.
> **NOTE** Headless mode doesn't support navigation to a PDF document. See the [upstream issue](https://bugs.chromium.org/p/chromium/issues/detail?id=761295).
#### frame.hover(selector)
- `selector` <[string]> A [selector] to search for element to hover. If there are multiple elements satisfying the selector, the first will be hovered.
- returns: <[Promise]> Promise which resolves when the element matching `selector` is successfully hovered. Promise gets rejected if there's no element matching `selector`.
@@ -2499,6 +2530,29 @@ const selector = '.foo';
await page.waitForFunction(selector => !!document.querySelector(selector), {}, selector);
```
#### frame.waitForNavigation(options)
- `options` <[Object]> Navigation parameters which might have the following properties:
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) method.
- `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either:
- `load` - consider navigation to be finished when the `load` event is fired.
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
- `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms.
- `networkidle2` - consider navigation to be finished when there are no more than 2 network connections for at least `500` ms.
- returns: <[Promise]<[?Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`.
This resolves when the frame navigates to a new URL. It is useful for when you run code
which will indirectly cause the frame to navigate. Consider this example:
```js
const [response] = await Promise.all([
frame.waitForNavigation(), // The navigation promise resolves after navigation has finished
frame.click('a.my-link'), // Clicking the link will indirectly cause a navigation
]);
```
**NOTE** Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered a navigation.
#### frame.waitForSelector(selector[, options])
- `selector` <[string]> A [selector] of an element to wait for
- `options` <[Object]> Optional waiting parameters
@@ -2989,7 +3043,7 @@ page.on('requestfailed', request => {
```
#### request.frame()
- returns: <?[Frame]> A matching [Frame] object, or `null` if navigating to error pages.
- returns: <?[Frame]> A [Frame] that initiated this request, or `null` if navigating to error pages.
#### request.headers()
- returns: <[Object]> An object with HTTP headers associated with the request. All header names are lower-case.
@@ -3079,6 +3133,9 @@ page.on('request', request => {
#### response.buffer()
- returns: <Promise<[Buffer]>> Promise which resolves to a buffer with response body.
#### response.frame()
- returns: <?[Frame]> A [Frame] that initiated this response, or `null` if navigating to error pages.
#### response.fromCache()
- returns: <[boolean]>