feat(Page): Add global navigation timeout setting (#1728)
This patch introduces `page.setDefaultNavigationTimeout` method to override the default 30 seconds navigation timeout. Fixes #1514
This commit is contained in:
parent
3985dee54e
commit
ec8e40f1cb
21
docs/api.md
21
docs/api.md
@ -79,6 +79,7 @@
|
|||||||
* [page.select(selector, ...values)](#pageselectselector-values)
|
* [page.select(selector, ...values)](#pageselectselector-values)
|
||||||
* [page.setContent(html)](#pagesetcontenthtml)
|
* [page.setContent(html)](#pagesetcontenthtml)
|
||||||
* [page.setCookie(...cookies)](#pagesetcookiecookies)
|
* [page.setCookie(...cookies)](#pagesetcookiecookies)
|
||||||
|
* [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout)
|
||||||
* [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders)
|
* [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders)
|
||||||
* [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled)
|
* [page.setJavaScriptEnabled(enabled)](#pagesetjavascriptenabledenabled)
|
||||||
* [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled)
|
* [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled)
|
||||||
@ -837,7 +838,7 @@ If there's no element matching `selector`, the method throws an error.
|
|||||||
|
|
||||||
#### page.goBack(options)
|
#### page.goBack(options)
|
||||||
- `options` <[Object]> Navigation parameters which might have the following properties:
|
- `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.
|
- `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:
|
- `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.
|
- `load` - consider navigation to be finished when the `load` event is fired.
|
||||||
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
||||||
@ -850,7 +851,7 @@ Navigate to the previous page in history.
|
|||||||
|
|
||||||
#### page.goForward(options)
|
#### page.goForward(options)
|
||||||
- `options` <[Object]> Navigation parameters which might have the following properties:
|
- `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.
|
- `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:
|
- `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.
|
- `load` - consider navigation to be finished when the `load` event is fired.
|
||||||
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
||||||
@ -864,7 +865,7 @@ Navigate to the next page in history.
|
|||||||
#### page.goto(url, options)
|
#### page.goto(url, options)
|
||||||
- `url` <[string]> URL to navigate page to. The url should include scheme, e.g. `https://`.
|
- `url` <[string]> URL to navigate page to. The url should include scheme, e.g. `https://`.
|
||||||
- `options` <[Object]> Navigation parameters which might have the following properties:
|
- `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.
|
- `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:
|
- `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.
|
- `load` - consider navigation to be finished when the `load` event is fired.
|
||||||
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
||||||
@ -1004,7 +1005,7 @@ Shortcut for [page.mainFrame().executionContext().queryObjects(prototypeHandle)]
|
|||||||
|
|
||||||
#### page.reload(options)
|
#### page.reload(options)
|
||||||
- `options` <[Object]> Navigation parameters which might have the following properties:
|
- `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.
|
- `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:
|
- `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.
|
- `load` - consider navigation to be finished when the `load` event is fired.
|
||||||
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
||||||
@ -1058,6 +1059,16 @@ Shortcut for [page.mainFrame().select()](#frameselectselector-values)
|
|||||||
- `sameSite` <[string]> `"Strict"` or `"Lax"`.
|
- `sameSite` <[string]> `"Strict"` or `"Lax"`.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
#### page.setDefaultNavigationTimeout(timeout)
|
||||||
|
- `timeout` <[number]> Maximum navigation time in milliseconds
|
||||||
|
|
||||||
|
This setting will change the default maximum navigation time of 30 seconds for the following methods:
|
||||||
|
- [page.goto(url, options)](#pagegotourl-options)
|
||||||
|
- [page.goBack(options)](#pagegobackoptions)
|
||||||
|
- [page.goForward(options)](#pagegoforwardoptions)
|
||||||
|
- [page.reload(options)](#pagereloadoptions)
|
||||||
|
- [page.waitForNavigation(options)](#pagewaitfornavigationoptions)
|
||||||
|
|
||||||
#### page.setExtraHTTPHeaders(headers)
|
#### page.setExtraHTTPHeaders(headers)
|
||||||
- `headers` <[Object]> An object containing additional http headers to be sent with every request. All header values must be strings.
|
- `headers` <[Object]> An object containing additional http headers to be sent with every request. All header values must be strings.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
@ -1209,7 +1220,7 @@ Shortcut for [page.mainFrame().waitForFunction(pageFunction[, options[, ...args]
|
|||||||
|
|
||||||
#### page.waitForNavigation(options)
|
#### page.waitForNavigation(options)
|
||||||
- `options` <[Object]> Navigation parameters which might have the following properties:
|
- `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.
|
- `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:
|
- `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.
|
- `load` - consider navigation to be finished when the `load` event is fired.
|
||||||
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
- `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired.
|
||||||
|
@ -21,9 +21,10 @@ class NavigatorWatcher {
|
|||||||
/**
|
/**
|
||||||
* @param {!FrameManager} frameManager
|
* @param {!FrameManager} frameManager
|
||||||
* @param {!Puppeteer.Frame} frame
|
* @param {!Puppeteer.Frame} frame
|
||||||
|
* @param {number} timeout
|
||||||
* @param {!Object=} options
|
* @param {!Object=} options
|
||||||
*/
|
*/
|
||||||
constructor(frameManager, frame, options = {}) {
|
constructor(frameManager, frame, timeout, options = {}) {
|
||||||
console.assert(options.networkIdleTimeout === undefined, 'ERROR: networkIdleTimeout option is no longer supported.');
|
console.assert(options.networkIdleTimeout === undefined, 'ERROR: networkIdleTimeout option is no longer supported.');
|
||||||
console.assert(options.networkIdleInflight === undefined, 'ERROR: networkIdleInflight option is no longer supported.');
|
console.assert(options.networkIdleInflight === undefined, 'ERROR: networkIdleInflight option is no longer supported.');
|
||||||
console.assert(options.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead');
|
console.assert(options.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead');
|
||||||
@ -41,7 +42,7 @@ class NavigatorWatcher {
|
|||||||
this._frameManager = frameManager;
|
this._frameManager = frameManager;
|
||||||
this._frame = frame;
|
this._frame = frame;
|
||||||
this._initialLoaderId = frame._loaderId;
|
this._initialLoaderId = frame._loaderId;
|
||||||
this._timeout = typeof options.timeout === 'number' ? options.timeout : 30000;
|
this._timeout = timeout;
|
||||||
this._eventListeners = [
|
this._eventListeners = [
|
||||||
helper.addEventListener(this._frameManager, FrameManager.Events.LifecycleEvent, this._checkLifecycleComplete.bind(this)),
|
helper.addEventListener(this._frameManager, FrameManager.Events.LifecycleEvent, this._checkLifecycleComplete.bind(this)),
|
||||||
helper.addEventListener(this._frameManager, FrameManager.Events.FrameDetached, this._checkLifecycleComplete.bind(this))
|
helper.addEventListener(this._frameManager, FrameManager.Events.FrameDetached, this._checkLifecycleComplete.bind(this))
|
||||||
|
18
lib/Page.js
18
lib/Page.js
@ -79,6 +79,7 @@ class Page extends EventEmitter {
|
|||||||
this._pageBindings = new Map();
|
this._pageBindings = new Map();
|
||||||
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||||
this._coverage = new Coverage(client);
|
this._coverage = new Coverage(client);
|
||||||
|
this._defaultNavigationTimeout = 30000;
|
||||||
|
|
||||||
this._screenshotTaskQueue = screenshotTaskQueue;
|
this._screenshotTaskQueue = screenshotTaskQueue;
|
||||||
|
|
||||||
@ -170,6 +171,13 @@ class Page extends EventEmitter {
|
|||||||
return this._networkManager.setOfflineMode(enabled);
|
return this._networkManager.setOfflineMode(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} timeout
|
||||||
|
*/
|
||||||
|
setDefaultNavigationTimeout(timeout) {
|
||||||
|
this._defaultNavigationTimeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!Object} event
|
* @param {!Object} event
|
||||||
*/
|
*/
|
||||||
@ -471,7 +479,7 @@ class Page extends EventEmitter {
|
|||||||
* @param {!Object=} options
|
* @param {!Object=} options
|
||||||
* @return {!Promise<?Response>}
|
* @return {!Promise<?Response>}
|
||||||
*/
|
*/
|
||||||
async goto(url, options) {
|
async goto(url, options = {}) {
|
||||||
const referrer = this._networkManager.extraHTTPHeaders()['referer'];
|
const referrer = this._networkManager.extraHTTPHeaders()['referer'];
|
||||||
|
|
||||||
const requests = new Map();
|
const requests = new Map();
|
||||||
@ -480,7 +488,8 @@ class Page extends EventEmitter {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const mainFrame = this._frameManager.mainFrame();
|
const mainFrame = this._frameManager.mainFrame();
|
||||||
const watcher = new NavigatorWatcher(this._frameManager, mainFrame, options);
|
const timeout = typeof options.timeout === 'number' ? options.timeout : this._defaultNavigationTimeout;
|
||||||
|
const watcher = new NavigatorWatcher(this._frameManager, mainFrame, timeout, options);
|
||||||
const navigationPromise = watcher.navigationPromise();
|
const navigationPromise = watcher.navigationPromise();
|
||||||
let error = await Promise.race([
|
let error = await Promise.race([
|
||||||
navigate(this._client, url, referrer),
|
navigate(this._client, url, referrer),
|
||||||
@ -527,9 +536,10 @@ class Page extends EventEmitter {
|
|||||||
* @param {!Object=} options
|
* @param {!Object=} options
|
||||||
* @return {!Promise<!Response>}
|
* @return {!Promise<!Response>}
|
||||||
*/
|
*/
|
||||||
async waitForNavigation(options) {
|
async waitForNavigation(options = {}) {
|
||||||
const mainFrame = this._frameManager.mainFrame();
|
const mainFrame = this._frameManager.mainFrame();
|
||||||
const watcher = new NavigatorWatcher(this._frameManager, mainFrame, options);
|
const timeout = typeof options.timeout === 'number' ? options.timeout : this._defaultNavigationTimeout;
|
||||||
|
const watcher = new NavigatorWatcher(this._frameManager, mainFrame, timeout, options);
|
||||||
|
|
||||||
const responses = new Map();
|
const responses = new Map();
|
||||||
const listener = helper.addEventListener(this._networkManager, NetworkManager.Events.Response, response => responses.set(response.url(), response));
|
const listener = helper.addEventListener(this._networkManager, NetworkManager.Events.Response, response => responses.set(response.url(), response));
|
||||||
|
@ -1063,6 +1063,14 @@ describe('Page', function() {
|
|||||||
await page.goto(server.PREFIX + '/empty.html', {timeout: 1}).catch(e => error = e);
|
await page.goto(server.PREFIX + '/empty.html', {timeout: 1}).catch(e => error = e);
|
||||||
expect(error.message).toContain('Navigation Timeout Exceeded: 1ms');
|
expect(error.message).toContain('Navigation Timeout Exceeded: 1ms');
|
||||||
});
|
});
|
||||||
|
it('should fail when exceeding default maximum navigation timeout', async({page, server}) => {
|
||||||
|
// Hang for request to the empty.html
|
||||||
|
server.setRoute('/empty.html', (req, res) => { });
|
||||||
|
let error = null;
|
||||||
|
page.setDefaultNavigationTimeout(1);
|
||||||
|
await page.goto(server.PREFIX + '/empty.html').catch(e => error = e);
|
||||||
|
expect(error.message).toContain('Navigation Timeout Exceeded: 1ms');
|
||||||
|
});
|
||||||
it('should disable timeout when its set to 0', async({page, server}) => {
|
it('should disable timeout when its set to 0', async({page, server}) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
let loaded = false;
|
let loaded = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user