Skip to content

Commit

Permalink
'Loading panel' is shown during assertion execution (closes #1011) (#…
Browse files Browse the repository at this point in the history
…1278)

* 'Loading panel' is shown during assertion execution (closes #1011)

* loading panel for waiting assertions

* renamed
  • Loading branch information
helen-dikareva authored and AlexanderMoskovkin committed Mar 6, 2017
1 parent ea8fad1 commit 0d4c037
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 196 deletions.
80 changes: 80 additions & 0 deletions src/assertions/executor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { EventEmitter } from 'events';
import delay from '../utils/delay';
import { ExternalAssertionLibraryError } from '../errors/test-run';
import ClientFunctionResultPromise from '../client-functions/result-promise';
import getFn from './get-fn';

const ASSERTION_DELAY = 200;

export default class AssertionExecutor extends EventEmitter {
constructor (command, callsite) {
super();

this.command = command;
this.callsite = callsite;

this.startTime = null;
this.passed = false;
this.inRetry = false;

var fn = getFn(this.command);

this.fn = this.command.actual instanceof ClientFunctionResultPromise ?
this._wrapFunction(fn) : fn;
}

_getTimeLeft () {
return this.command.options.timeout - (new Date() - this.startTime);
}

_onExecutionFinished () {
if (this.inRetry)
this.emit('end-assertion-retries', this.passed);
}

_wrapFunction (fn) {
return async () => {
var resultPromise = this.command.actual;

while (!this.passed) {
this.command.actual = await resultPromise._reExecute();

try {
fn();
this.passed = true;
this._onExecutionFinished();
}

catch (err) {
if (this._getTimeLeft() <= 0) {
this._onExecutionFinished();
throw err;
}

await delay(ASSERTION_DELAY);

this.inRetry = true;
this.emit('start-assertion-retries', this._getTimeLeft());
}
}
};
}

async run () {
this.startTime = new Date();

try {
await this.fn();
}

catch (err) {
if (err.name === 'AssertionError' || err.constructor.name === 'AssertionError')
throw new ExternalAssertionLibraryError(err, this.callsite);

if (err.isTestCafeError)
err.callsite = this.callsite;

throw err;
}
}
}
57 changes: 57 additions & 0 deletions src/assertions/get-fn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { assert, expect } from 'chai';

export default function getFn (command) {
switch (command.assertionType) {
case 'eql':
return () => assert.deepEqual(command.actual, command.expected, command.message);

case 'notEql':
return () => assert.notDeepEqual(command.actual, command.expected, command.message);

case 'ok':
return () => assert.isOk(command.actual, command.message);

case 'notOk':
return () => assert.isNotOk(command.actual, command.message);

case 'contains':
return () => assert.include(command.actual, command.expected, command.message);

case 'notContains':
return () => assert.notInclude(command.actual, command.expected, command.message);

case 'typeOf':
return () => assert.typeOf(command.actual, command.expected, command.message);

case 'notTypeOf':
return () => assert.notTypeOf(command.actual, command.expected, command.message);

case 'gt':
return () => assert.isAbove(command.actual, command.expected, command.message);

case 'gte':
return () => assert.isAtLeast(command.actual, command.expected, command.message);

case 'lt':
return () => assert.isBelow(command.actual, command.expected, command.message);

case 'lte':
return () => assert.isAtMost(command.actual, command.expected, command.message);

case 'within':
return () => expect(command.actual).to.be.within(command.expected, command.expected2, command.message);

case 'notWithin':
return () => expect(command.actual).not.to.be.within(command.expected, command.expected2, command.message);

case 'match':
return () => assert.match(command.actual, command.expected, command.message);

case 'notMatch':
return () => assert.notMatch(command.actual, command.expected, command.message);

default:
return () => {
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export default class SelectorExecutor extends ClientFunctionExecutor {

this.createNotFoundError = createNotFoundError;
this.createIsInvisibleError = createIsInvisibleError;
this.timeout = typeof command.timeout === 'number' ? command.timeout : globalTimeout;
this.statusBar = statusBar;
this.timeout = typeof command.timeout === 'number' ? command.timeout : globalTimeout;
this.counterMode = this.dependencies.filterOptions.counterMode;

if (startTime) {
Expand Down Expand Up @@ -88,7 +88,7 @@ export default class SelectorExecutor extends ClientFunctionExecutor {
var error = null;
var element = null;

this.statusBar.setWaitingStatus(this.timeout);
this.statusBar.showWaitingElementStatus(this.timeout);

return this
._ensureExists(args, startTime)
Expand All @@ -101,14 +101,14 @@ export default class SelectorExecutor extends ClientFunctionExecutor {
.catch(err => {
error = err;

return this.statusBar.resetWaitingStatus(false);
return this.statusBar.hideWaitingElementStatus(false);
})
.then(el => {
if (error)
throw error;

element = el;
return this.statusBar.resetWaitingStatus(!!el);
return this.statusBar.hideWaitingElementStatus(!!el);
})
.then(() => element);
}
Expand Down
25 changes: 20 additions & 5 deletions src/client/driver/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ export default class Driver {
hammerhead.on(hammerhead.EVENTS.uncaughtJsError, err => this._onJsError(err));
}

_setDebuggingStatus () {
_showDebuggingStatus () {
return transport
.queuedAsyncServiceMsg({ cmd: TEST_RUN_MESSAGES.showDebuggerMessage })
.then(() => this.statusBar.setDebuggingStatus())
.then(() => this.statusBar.showDebuggingStatus())
.then(stopAfterNextAction => this.contextStorage.setItem(STOP_AFTER_NEXT_ACTION, stopAfterNextAction));
}

Expand Down Expand Up @@ -391,7 +391,7 @@ export default class Driver {
}

_onDebugCommand () {
this._setDebuggingStatus()
this._showDebuggingStatus()
.then(() => this._onReady(new DriverStatus({ isCommandResult: true })));
}

Expand All @@ -400,6 +400,16 @@ export default class Driver {
this._onReady(new DriverStatus({ isCommandResult: true }));
}

_onShowAssertionRetriesStatusCommand (command) {
this.statusBar.showWaitingAssertionRetriesStatus(command.timeout);
this._onReady(new DriverStatus({ isCommandResult: true }));
}

_onHideAssertionRetriesStatusCommand (command) {
this.statusBar.hideWaitingAssertionRetriesStatus(command.success)
.then(() => this._onReady(new DriverStatus({ isCommandResult: true })));
}

_onTestDone (status) {
this.contextStorage.setItem(TEST_DONE_SENT_FLAG, true);

Expand All @@ -418,7 +428,7 @@ export default class Driver {
isVisualManipulationCommand(command);

if (isDebugging) {
this._setDebuggingStatus()
this._showDebuggingStatus()
.then(() => this._onCommand(command));
}
else
Expand Down Expand Up @@ -465,6 +475,11 @@ export default class Driver {
else if (command.type === COMMAND_TYPE.setTestSpeed)
this._onSetTestSpeedCommand(command);

else if (command.type === COMMAND_TYPE.showAssertionRetriesStatus)
this._onShowAssertionRetriesStatusCommand(command);

else if (command.type === COMMAND_TYPE.hideAssertionRetriesStatus)
this._onHideAssertionRetriesStatusCommand(command);
else
this._onActionCommand(command);
}
Expand Down Expand Up @@ -511,7 +526,7 @@ export default class Driver {

this.statusBar = new StatusBar(this.userAgent, this.fixtureName, this.testName);

this.readyPromise.then(() => this.statusBar.resetPageLoadingStatus());
this.readyPromise.then(() => this.statusBar.hidePageLoadingStatus());

var pendingStatus = this.contextStorage.getItem(PENDING_STATUS);

Expand Down
20 changes: 15 additions & 5 deletions src/client/ui/status-bar/iframe-status-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,23 @@ export default class IframeStatusBar extends StatusBar {
}

//API
setWaitingStatus (timeout) {
messageSandbox.sendServiceMsg({ cmd: MESSAGES.startWaitingForElement, timeout }, window.top);
showWaitingElementStatus (timeout) {
messageSandbox.sendServiceMsg({ cmd: MESSAGES.startWaitingElement, timeout }, window.top);
}

resetWaitingStatus (waitingSuccess) {
var msg = { cmd: MESSAGES.stopWaitingForElementRequest, waitingSuccess };
hideWaitingElementStatus (waitingSuccess) {
var msg = { cmd: MESSAGES.endWaitingElementRequest, waitingSuccess };

return sendRequestToFrame(msg, MESSAGES.stopWaitingForElementResponse, window.top);
return sendRequestToFrame(msg, MESSAGES.endWaitingElementResponse, window.top);
}

showWaitingAssertionRetriesStatus (timeout) {
messageSandbox.sendServiceMsg({ cmd: MESSAGES.startWaitingAssertionRetries, timeout }, window.top);
}

hideWaitingAssertionRetriesStatus (waitingSuccess) {
var msg = { cmd: MESSAGES.endWaitingAssertionRetriesRequest, waitingSuccess };

return sendRequestToFrame(msg, MESSAGES.endWaitingAssertionRetriesResponse, window.top);
}
}
Loading

0 comments on commit 0d4c037

Please sign in to comment.