feat(firefox): support page.setDefaultNavigationTimeout (#3969)

This patch supports:
- page.setDefaultNavigationTimeout
- page.setDefaultTimeout
This commit is contained in:
Andrey Lushnikov 2019-02-08 20:37:14 -08:00 committed by GitHub
parent fc18a79e99
commit edb6f62824
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 38 deletions

View File

@ -13,10 +13,11 @@ class FrameManager extends EventEmitter {
* @param {PageSession} session
* @param {Page} page
*/
constructor(session, page) {
constructor(session, page, timeoutSettings) {
super();
this._session = session;
this._page = page;
this._timeoutSettings = timeoutSettings;
this._mainFrame = null;
this._frames = new Map();
this._eventListeners = [
@ -48,7 +49,7 @@ class FrameManager extends EventEmitter {
}
_onFrameAttached(params) {
const frame = new Frame(this._session, this, this._page, params.frameId);
const frame = new Frame(this._session, this, this._page, params.frameId, this._timeoutSettings);
const parentFrame = this._frames.get(params.parentFrameId) || null;
if (parentFrame) {
frame._parentFrame = parentFrame;
@ -90,9 +91,10 @@ class Frame {
* @param {!Page} page
* @param {string} frameId
*/
constructor(session, frameManager, page, frameId) {
constructor(session, frameManager, page, frameId, timeoutSettings) {
this._session = session;
this._frameManager = frameManager;
this._timeoutSettings = timeoutSettings;
this._page = page;
this._frameId = frameId;
/** @type {?Frame} */
@ -230,7 +232,7 @@ class Frame {
waitForFunction(pageFunction, options = {}, ...args) {
const {
polling = 'raf',
timeout = 30000
timeout = this._timeoutSettings.timeout(),
} = options;
return new WaitTask(this, pageFunction, 'function', polling, timeout, ...args).promise;
}
@ -263,7 +265,7 @@ class Frame {
const {
visible: waitForVisible = false,
hidden: waitForHidden = false,
timeout = 30000
timeout = this._timeoutSettings.timeout(),
} = options;
const polling = waitForVisible || waitForHidden ? 'raf' : 'mutation';
const title = `${isXPath ? 'XPath' : 'selector'} "${selectorOrXPath}"${waitForHidden ? ' to be hidden' : ''}`;

View File

@ -1,6 +1,5 @@
const {helper} = require('./helper');
const {Keyboard, Mouse} = require('./Input');
const {constants} = require('./common');
const {Dialog} = require('./Dialog');
const {TimeoutError} = require('./Errors');
const fs = require('fs');
@ -10,6 +9,7 @@ const EventEmitter = require('events');
const {createHandle} = require('./JSHandle');
const {Events} = require('./Events');
const {FrameManager} = require('./FrameManager');
const {TimeoutSettings} = require('./TimeoutSettings');
const writeFileAsync = util.promisify(fs.writeFile);
@ -67,12 +67,13 @@ class Page extends EventEmitter {
*/
constructor(session, target) {
super();
this._timeoutSettings = new TimeoutSettings();
this._session = session;
this._target = target;
this._keyboard = new Keyboard(session);
this._mouse = new Mouse(session, this._keyboard);
this._isClosed = false;
this._frameManager = new FrameManager(session, this);
this._frameManager = new FrameManager(session, this, this._timeoutSettings);
this._eventListeners = [
helper.addEventListener(this._session, 'Page.uncaughtError', this._onUncaughtError.bind(this)),
helper.addEventListener(this._session, 'Page.consoleAPICalled', this._onConsole.bind(this)),
@ -88,6 +89,20 @@ class Page extends EventEmitter {
this._viewport = null;
}
/**
* @param {number} timeout
*/
setDefaultNavigationTimeout(timeout) {
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
}
/**
* @param {number} timeout
*/
setDefaultTimeout(timeout) {
this._timeoutSettings.setDefaultTimeout(timeout);
}
/**
* @param {string} userAgent
*/
@ -214,7 +229,7 @@ class Page extends EventEmitter {
*/
async waitForNavigation(options = {}) {
const {
timeout = constants.DEFAULT_NAVIGATION_TIMEOUT,
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
} = options;
const frame = this._frameManager.mainFrame();
@ -263,7 +278,7 @@ class Page extends EventEmitter {
*/
async goto(url, options = {}) {
const {
timeout = constants.DEFAULT_NAVIGATION_TIMEOUT,
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
} = options;
const frame = this._frameManager.mainFrame();
@ -296,7 +311,7 @@ class Page extends EventEmitter {
*/
async goBack(options = {}) {
const {
timeout = constants.DEFAULT_NAVIGATION_TIMEOUT,
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
} = options;
const frame = this._frameManager.mainFrame();
@ -328,7 +343,7 @@ class Page extends EventEmitter {
*/
async goForward(options = {}) {
const {
timeout = constants.DEFAULT_NAVIGATION_TIMEOUT,
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
} = options;
const frame = this._frameManager.mainFrame();
@ -360,7 +375,7 @@ class Page extends EventEmitter {
*/
async reload(options = {}) {
const {
timeout = constants.DEFAULT_NAVIGATION_TIMEOUT,
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
} = options;
const frame = this._frameManager.mainFrame();

View File

@ -0,0 +1,57 @@
/**
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const DEFAULT_TIMEOUT = 30000;
class TimeoutSettings {
constructor() {
this._defaultTimeout = null;
this._defaultNavigationTimeout = null;
}
/**
* @param {number} timeout
*/
setDefaultTimeout(timeout) {
this._defaultTimeout = timeout;
}
/**
* @param {number} timeout
*/
setDefaultNavigationTimeout(timeout) {
this._defaultNavigationTimeout = timeout;
}
/**
* @return {number}
*/
navigationTimeout() {
if (this._defaultNavigationTimeout !== null)
return this._defaultNavigationTimeout;
if (this._defaultTimeout !== null)
return this._defaultTimeout;
return DEFAULT_TIMEOUT;
}
timeout() {
if (this._defaultTimeout !== null)
return this._defaultTimeout;
return DEFAULT_TIMEOUT;
}
}
module.exports = {TimeoutSettings};

View File

@ -1,20 +0,0 @@
/**
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const constants = {
DEFAULT_NAVIGATION_TIMEOUT: 30000,
};
module.exports = {constants};

View File

@ -131,7 +131,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
expect(error.message).toContain('Navigation Timeout Exceeded: 1ms');
expect(error).toBeInstanceOf(TimeoutError);
});
it_fails_ffox('should fail when exceeding default maximum navigation timeout', async({page, server}) => {
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;
@ -140,7 +140,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
expect(error.message).toContain('Navigation Timeout Exceeded: 1ms');
expect(error).toBeInstanceOf(TimeoutError);
});
it_fails_ffox('should fail when exceeding default maximum timeout', async({page, server}) => {
it('should fail when exceeding default maximum timeout', async({page, server}) => {
// Hang for request to the empty.html
server.setRoute('/empty.html', (req, res) => { });
let error = null;
@ -149,7 +149,7 @@ module.exports.addTests = function({testRunner, expect, Errors, CHROME}) {
expect(error.message).toContain('Navigation Timeout Exceeded: 1ms');
expect(error).toBeInstanceOf(TimeoutError);
});
it_fails_ffox('should prioritize default navigation timeout over default timeout', async({page, server}) => {
it('should prioritize default navigation timeout over default timeout', async({page, server}) => {
// Hang for request to the empty.html
server.setRoute('/empty.html', (req, res) => { });
let error = null;

View File

@ -173,13 +173,12 @@ module.exports.addTests = function({testRunner, expect, product, Errors}) {
expect(error.message).toContain('waiting for function failed: timeout');
expect(error).toBeInstanceOf(TimeoutError);
});
it_fails_ffox('should respect default timeout', async({page}) => {
it('should respect default timeout', async({page}) => {
page.setDefaultTimeout(1);
let error = null;
await page.waitForFunction('false').catch(e => error = e);
expect(error).toBeTruthy();
expect(error.message).toContain('waiting for function failed: timeout');
expect(error).toBeInstanceOf(TimeoutError);
expect(error.message).toContain('waiting for function failed: timeout');
});
it('should disable timeout when its set to 0', async({page}) => {
const watchdog = page.waitForFunction(() => {