Skip to content

Commit

Permalink
Implement --page-load-timeout (closes DevExpress#1645)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderMoskovkin committed Jul 25, 2017
1 parent ccd4b1f commit 875be7f
Show file tree
Hide file tree
Showing 26 changed files with 296 additions and 19 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"stack-chain": "^1.3.6",
"strip-bom": "^2.0.0",
"testcafe-browser-tools": "1.2.4",
"testcafe-hammerhead": "11.0.3",
"testcafe-hammerhead": "11.1.0",
"testcafe-legacy-api": "3.0.0",
"testcafe-reporter-json": "^2.1.0",
"testcafe-reporter-list": "^2.1.0",
Expand Down
5 changes: 5 additions & 0 deletions src/api/test-controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
SetNativeDialogHandlerCommand,
GetNativeDialogHistoryCommand,
SetTestSpeedCommand,
SetPageLoadTimeoutCommand,
UseRoleCommand
} from '../../test-run/commands/actions';

Expand Down Expand Up @@ -250,6 +251,10 @@ export default class TestController {
return this._enqueueCommand('setTestSpeed', SetTestSpeedCommand, { speed });
}

_setPageLoadTimeout$ (duration) {
return this._enqueueCommand('setPageLoadTimeout', SetPageLoadTimeoutCommand, { duration });
}

_useRole$ (role) {
return this._enqueueCommand('useRole', UseRoleCommand, { role });
}
Expand Down
10 changes: 10 additions & 0 deletions src/cli/argument-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export default class CLIArgumentParser {
.option('--app-init-delay <ms>', 'specify how much time it takes for the tested app to initialize')
.option('--selector-timeout <ms>', 'set the amount of time within which selectors make attempts to obtain a node to be returned')
.option('--assertion-timeout <ms>', 'set the amount of time within which assertion should pass')
.option('--page-load-timeout <ms>', 'set the amount of time within which TestCafe waits for the `window.load` event to fire before starting the test')
.option('--speed <factor>', 'set the speed of test execution (0.01 ... 1)')
.option('--ports <port1,port2>', 'specify custom port numbers')
.option('--hostname <name>', 'specify the hostname')
Expand Down Expand Up @@ -171,6 +172,14 @@ export default class CLIArgumentParser {
}
}

_parsePageLoadTimeout () {
if (this.opts.pageLoadTimeout) {
assertType(is.nonNegativeNumberString, null, 'Page load timeout', this.opts.pageLoadTimeout);

this.opts.pageLoadTimeout = parseInt(this.opts.pageLoadTimeout, 10);
}
}

_parseSpeed () {
if (this.opts.speed)
this.opts.speed = parseFloat(this.opts.speed);
Expand Down Expand Up @@ -266,6 +275,7 @@ export default class CLIArgumentParser {
this._parseFilteringOptions();
this._parseSelectorTimeout();
this._parseAssertionTimeout();
this._parsePageLoadTimeout();
this._parseAppInitDelay();
this._parseSpeed();
this._parsePorts();
Expand Down
21 changes: 16 additions & 5 deletions src/client/core/utils/event.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import hammerhead from '../deps/hammerhead';
import delay from './delay';
import * as domUtils from './dom';


var Promise = hammerhead.Promise;
var nativeMethods = hammerhead.nativeMethods;
var listeners = hammerhead.eventSandbox.listeners;

export const RECORDING_LISTENED_EVENTS = [
'click', 'mousedown', 'mouseup', 'dblclick', 'contextmenu', 'mousemove', 'mouseover', 'mouseout',
Expand Down Expand Up @@ -33,15 +35,21 @@ export function unbind (el, event, handler, useCapture) {
nativeMethods.removeEventListener.call(el, event, handler, useCapture);
}


export function documentReady () {
export function documentReady (pageLoadTimeout = 0) {
return new Promise(resolve => {
var isReady = false;
var isReady = false;
var windowLoadRaised = false;

function ready () {
function ready (forced) {
if (isReady)
return;

if (!forced && listeners.getEventListeners(window, 'load').length && !windowLoadRaised) {
// NOTE: wait for window.load
delay(pageLoadTimeout).then(() => ready(true));
return;
}

if (!document.body) {
nativeMethods.setTimeout.call(window, ready, 1);
return;
Expand All @@ -67,7 +75,10 @@ export function documentReady () {
nativeMethods.setTimeout.call(window, onContentLoaded, 1);
else {
bind(document, 'DOMContentLoaded', onContentLoaded);
bind(window, 'load', ready);
bind(window, 'load', () => {
windowLoadRaised = true;
ready();
});
}
});
}
3 changes: 2 additions & 1 deletion src/client/driver/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export default class Driver {
this.fixtureName = runInfo.fixtureName;
this.testName = runInfo.testName;
this.selectorTimeout = options.selectorTimeout;
this.pageLoadTimeout = options.pageLoadTimeout;
this.initialSpeed = options.speed;
this.skipJsErrors = options.skipJsErrors;
this.dialogHandler = options.dialogHandler;
Expand All @@ -101,7 +102,7 @@ export default class Driver {
this.pageInitialRequestBarrier = new RequestBarrier();

this.readyPromise = eventUtils
.documentReady()
.documentReady(this.pageLoadTimeout)
.then(() => this.pageInitialRequestBarrier.wait(true));

this._initChildDriverListening();
Expand Down
1 change: 1 addition & 0 deletions src/client/test-run/iframe.js.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
var IframeDriver = window['%testCafeIframeDriver%'];
var driver = new IframeDriver({ testRun: {{{testRunId}}} }, {
selectorTimeout: {{{selectorTimeout}}},
pageLoadTimeout: {{{pageLoadTimeout}}},
dialogHandler: {{{dialogHandler}}},
speed: {{{speed}}}
});
Expand Down
2 changes: 2 additions & 0 deletions src/client/test-run/index.js.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
var testRunId = {{{testRunId}}};
var browserId = {{{browserId}}};
var selectorTimeout = {{{selectorTimeout}}};
var pageLoadTimeout = {{{pageLoadTimeout}}};
var speed = {{{speed}}};
var browserHeartbeatUrl = {{{browserHeartbeatUrl}}};
var browserStatusUrl = {{{browserStatusUrl}}};
Expand All @@ -21,6 +22,7 @@
{ userAgent: userAgent, fixtureName: fixtureName, testName: testName },
{
selectorTimeout: selectorTimeout,
pageLoadTimeout: pageLoadTimeout,
skipJsErrors: skipJsErrors,
dialogHandler: dialogHandler,
speed: speed
Expand Down
7 changes: 5 additions & 2 deletions src/runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import MESSAGE from '../errors/runtime/message';

const DEFAULT_SELECTOR_TIMEOUT = 10000;
const DEFAULT_ASSERTION_TIMEOUT = 3000;
const DEFAULT_PAGE_LOAD_TIMEOUT = 5000;


export default class Runner extends EventEmitter {
Expand All @@ -31,7 +32,8 @@ export default class Runner extends EventEmitter {
quarantineMode: false,
debugMode: false,
reportOutStream: void 0,
selectorTimeout: DEFAULT_SELECTOR_TIMEOUT
selectorTimeout: DEFAULT_SELECTOR_TIMEOUT,
pageLoadTimeout: DEFAULT_PAGE_LOAD_TIMEOUT
};
}

Expand Down Expand Up @@ -182,12 +184,13 @@ export default class Runner extends EventEmitter {
return this;
}

run ({ skipJsErrors, quarantineMode, debugMode, selectorTimeout, assertionTimeout, speed = 1 } = {}) {
run ({ skipJsErrors, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1 } = {}) {
this.opts.skipJsErrors = !!skipJsErrors;
this.opts.quarantineMode = !!quarantineMode;
this.opts.debugMode = !!debugMode;
this.opts.selectorTimeout = selectorTimeout === void 0 ? DEFAULT_SELECTOR_TIMEOUT : selectorTimeout;
this.opts.assertionTimeout = assertionTimeout === void 0 ? DEFAULT_ASSERTION_TIMEOUT : assertionTimeout;
this.opts.pageLoadTimeout = pageLoadTimeout === void 0 ? DEFAULT_PAGE_LOAD_TIMEOUT : pageLoadTimeout;

if (typeof speed !== 'number' || isNaN(speed) || speed < 0.01 || speed > 1)
throw new GeneralError(MESSAGE.invalidSpeedValue);
Expand Down
23 changes: 17 additions & 6 deletions src/test-run/bookmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SwitchToIframeCommand,
SetNativeDialogHandlerCommand,
SetTestSpeedCommand,
SetPageLoadTimeoutCommand,
NavigateToCommand
} from './commands/actions';

Expand All @@ -20,12 +21,13 @@ export default class TestRunBookmark {
this.testRun = testRun;
this.role = role;

this.url = 'about:blank';
this.dialogHandler = testRun.activeDialogHandler;
this.iframeSelector = testRun.activeIframeSelector;
this.speed = testRun.speed;
this.ctx = testRun.ctx;
this.fixtureCtx = testRun.fixtureCtx;
this.url = 'about:blank';
this.dialogHandler = testRun.activeDialogHandler;
this.iframeSelector = testRun.activeIframeSelector;
this.speed = testRun.speed;
this.pageLoadTimeout = testRun.pageLoadTimeout;
this.ctx = testRun.ctx;
this.fixtureCtx = testRun.fixtureCtx;
}

async init () {
Expand All @@ -52,6 +54,14 @@ export default class TestRunBookmark {
}
}

async _restorePageLoadTimeout () {
if (this.testRun.pageLoadTimeout !== this.pageLoadTimeout) {
var restorePageLoadTimeoutCommand = new SetPageLoadTimeoutCommand({ duration: this.pageLoadTimeout });

await this.testRun.executeCommand(restorePageLoadTimeoutCommand);
}
}

async _restoreWorkingFrame () {
if (this.testRun.activeIframeSelector !== this.iframeSelector) {
var switchWorkingFrameCommand = this.iframeSelector ?
Expand Down Expand Up @@ -89,6 +99,7 @@ export default class TestRunBookmark {

try {
await this._restoreSpeed();
await this._restorePageLoadTimeout();
await this._restoreDialogHandler();

if (this.role.opts.preserveUrl)
Expand Down
17 changes: 17 additions & 0 deletions src/test-run/commands/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,23 @@ export class SetTestSpeedCommand extends Assignable {
}
}

export class SetPageLoadTimeoutCommand extends Assignable {
constructor (obj) {
super(obj);

this.type = TYPE.setPageLoadTimeout;
this.duration = null;

this._assignFrom(obj, true);
}

_getAssignableProperties () {
return [
{ name: 'duration', type: positiveIntegerArgument, required: true }
];
}
}

export class UseRoleCommand extends Assignable {
constructor (obj) {
super(obj);
Expand Down
6 changes: 5 additions & 1 deletion src/test-run/commands/from-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
SwitchToIframeCommand,
SwitchToMainWindowCommand,
SetNativeDialogHandlerCommand,
SetTestSpeedCommand
SetTestSpeedCommand,
SetPageLoadTimeoutCommand
} from './actions';

import AssertionCommand from './assertion';
Expand Down Expand Up @@ -105,6 +106,9 @@ export default function createCommandFromObject (obj) {
case TYPE.setTestSpeed:
return new SetTestSpeedCommand(obj);

case TYPE.setPageLoadTimeout:
return new SetPageLoadTimeoutCommand(obj);

case TYPE.assertion:
return new AssertionCommand(obj);

Expand Down
1 change: 1 addition & 0 deletions src/test-run/commands/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default {
setNativeDialogHandler: 'set-native-dialog-handler',
getNativeDialogHistory: 'get-native-dialog-history',
setTestSpeed: 'set-test-speed',
setPageLoadTimeout: 'set-page-load-timeout',
debug: 'debug',
assertion: 'assertion',
useRole: 'useRole',
Expand Down
19 changes: 18 additions & 1 deletion src/test-run/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import ClientFunctionBuilder from '../client-functions/client-function-builder';


import { TakeScreenshotOnFailCommand } from './commands/browser-manipulation';
import { SetNativeDialogHandlerCommand, SetTestSpeedCommand } from './commands/actions';
import { SetNativeDialogHandlerCommand, SetTestSpeedCommand, SetPageLoadTimeoutCommand } from './commands/actions';


import {
Expand Down Expand Up @@ -69,6 +69,7 @@ export default class TestRun extends Session {
this.activeDialogHandler = null;
this.activeIframeSelector = null;
this.speed = this.opts.speed;
this.pageLoadTimeout = this.opts.pageLoadTimeout;

this.pendingRequest = null;
this.pendingPageError = null;
Expand Down Expand Up @@ -117,6 +118,7 @@ export default class TestRun extends Session {
testName: JSON.stringify(this.test.name),
fixtureName: JSON.stringify(this.test.fixture.name),
selectorTimeout: this.opts.selectorTimeout,
pageLoadTimeout: this.pageLoadTimeout,
skipJsErrors: this.opts.skipJsErrors,
speed: this.speed,
dialogHandler: JSON.stringify(this.activeDialogHandler)
Expand All @@ -127,6 +129,7 @@ export default class TestRun extends Session {
return Mustache.render(IFRAME_TEST_RUN_TEMPLATE, {
testRunId: JSON.stringify(this.id),
selectorTimeout: this.opts.selectorTimeout,
pageLoadTimeout: this.pageLoadTimeout,
speed: this.speed,
dialogHandler: JSON.stringify(this.activeDialogHandler)
});
Expand Down Expand Up @@ -367,6 +370,9 @@ export default class TestRun extends Session {
else if (command.type === COMMAND_TYPE.setTestSpeed)
this.speed = command.speed;

else if (command.type === COMMAND_TYPE.setPageLoadTimeout)
this.pageLoadTimeout = command.duration;

else if (command.type === COMMAND_TYPE.debug)
this.debugging = true;
}
Expand Down Expand Up @@ -402,6 +408,11 @@ export default class TestRun extends Session {
if (command.type === COMMAND_TYPE.assertion)
return this._executeAssertion(command, callsite);

if (command.type === COMMAND_TYPE.setPageLoadTimeout) {
this.pageLoadTimeout = command.duration;
return Promise.resolve();
}

return this._enqueueCommand(command, callsite);
}

Expand Down Expand Up @@ -440,6 +451,12 @@ export default class TestRun extends Session {

await this.executeCommand(setSpeedCommand);
}

if (this.pageLoadTimeout !== this.opts.pageLoadTimeout) {
var setPageLoadTimeoutCommand = new SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout });

await this.executeCommand(setPageLoadTimeoutCommand);
}
}

async _getStateSnapshotFromRole (role) {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>PageLoadTimeout (window load long)</title>
</head>
<body>
<img src="./img.png?delay=10000" />
<script>
window.pageOpenedTime = Date.now();
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>PageLoadTimeout (window load long)</title>
</head>
<body>
<img src="./img.png?delay=10000" />
<script>
window.pageOpenedTime = Date.now();

window.addEventListener('load', function () {
window.loadEventRaised = true;
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>PageLoadTimeout (window load)</title>
</head>
<body>
<img src="./img.png?delay=1000" />
<script>
window.addEventListener('load', function () {
window.loadEventRaised = true;
});
</script>
</body>
</html>
Loading

0 comments on commit 875be7f

Please sign in to comment.