Skip to content

Commit

Permalink
Add the capability to get browser console messages (closes DevExpress…
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderMoskovkin committed Sep 26, 2017
1 parent 4d66894 commit 03f0969
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/api/test-controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
SwitchToMainWindowCommand,
SetNativeDialogHandlerCommand,
GetNativeDialogHistoryCommand,
GetConsoleMessagesCommand,
SetTestSpeedCommand,
SetPageLoadTimeoutCommand,
UseRoleCommand
Expand Down Expand Up @@ -239,6 +240,12 @@ export default class TestController {
return this.testRun.executeCommand(new GetNativeDialogHistoryCommand(), callsite);
}

_getConsoleMessages$ () {
var callsite = getCallsiteForMethod('getConsoleMessages');

return this.testRun.executeCommand(new GetConsoleMessagesCommand(), callsite);
}

_expect$ (actual) {
return new Assertion(actual, this);
}
Expand Down
45 changes: 45 additions & 0 deletions src/client/driver/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const ACTIVE_IFRAME_SELECTOR = 'testcafe|driver|active-iframe-sele
const TEST_SPEED = 'testcafe|driver|test-speed';
const ASSERTION_RETRIES_TIMEOUT = 'testcafe|driver|assertion-retries-timeout';
const ASSERTION_RETRIES_START_TIME = 'testcafe|driver|assertion-retries-start-time';
const CONSOLE_MESSAGES = 'testcafe|driver|console-messages';
const CHECK_IFRAME_DRIVER_LINK_DELAY = 500;

const ACTION_IFRAME_ERROR_CTORS = {
Expand Down Expand Up @@ -114,6 +115,7 @@ export default class Driver {

hammerhead.on(hammerhead.EVENTS.uncaughtJsError, err => this._onJsError(err));
hammerhead.on(hammerhead.EVENTS.unhandledRejection, err => this._onJsError(err));
hammerhead.on(hammerhead.EVENTS.consoleMethCalled, e => this._onConsoleMessage(e));
}

set speed (val) {
Expand All @@ -124,6 +126,19 @@ export default class Driver {
return this.contextStorage.getItem(TEST_SPEED);
}

get consoleMessages () {
return this.contextStorage.getItem(CONSOLE_MESSAGES) || {
log: [],
info: [],
error: [],
warn: []
};
}

set consoleMessages (messages) {
return this.contextStorage.setItem(CONSOLE_MESSAGES, messages);
}

// Error handling
_onJsError (err) {
// NOTE: we should not send any message to the server if we've
Expand Down Expand Up @@ -156,6 +171,26 @@ export default class Driver {
return false;
}

// Console messages
_onConsoleMessage (e) {
const meth = e.meth;

const args = e.args.map(arg => {
if (arg === null)
return 'null';

if (arg === void 0)
return 'undefined';

return arg.toString();
});

const messages = this.consoleMessages;

messages[meth].push(Array.prototype.slice.call(args).join(' '));

this.consoleMessages = messages;
}

// Status
_addPendingErrorToStatus (status) {
Expand Down Expand Up @@ -327,6 +362,13 @@ export default class Driver {
}));
}

_onGetConsoleMessagesCommand () {
this._onReady(new DriverStatus({
isCommandResult: true,
result: this.consoleMessages
}));
}

_onNavigateToCommand (command) {
this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, true);

Expand Down Expand Up @@ -489,6 +531,9 @@ export default class Driver {
else if (command.type === COMMAND_TYPE.getNativeDialogHistory)
this._onGetNativeDialogHistoryCommand(command);

else if (command.type === COMMAND_TYPE.getConsoleMessages)
this._onGetConsoleMessagesCommand(command);

else if (command.type === COMMAND_TYPE.setTestSpeed)
this._onSetTestSpeedCommand(command);

Expand Down
6 changes: 6 additions & 0 deletions src/test-run/commands/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,12 @@ export class GetNativeDialogHistoryCommand {
}
}

export class GetConsoleMessagesCommand {
constructor () {
this.type = TYPE.getConsoleMessages;
}
}

export class SetTestSpeedCommand extends Assignable {
constructor (obj) {
super(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 @@ -34,6 +34,7 @@ export default {
switchToMainWindow: 'switch-to-main-window',
setNativeDialogHandler: 'set-native-dialog-handler',
getNativeDialogHistory: 'get-native-dialog-history',
getConsoleMessages: 'get-console-messages',
setTestSpeed: 'set-test-speed',
setPageLoadTimeout: 'set-page-load-timeout',
debug: 'debug',
Expand Down
8 changes: 8 additions & 0 deletions test/functional/fixtures/api/es-next/console/pages/empty.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Console messages (empty page)</title>
</head>
<body>
</body>
</html>
27 changes: 27 additions & 0 deletions test/functional/fixtures/api/es-next/console/pages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title>Console messages</title>
</head>
<body>
<button id="trigger-messages">Trigger Messages</button>

<a id="reload" href="./empty.html">Reload</a>

<script>
var counter = 1;

function triggerMessages () {
console.log('log' + counter);
console.warn('warn' + counter);
console.error('error' + counter);
console.info('info' + counter);

counter++;
}

triggerMessages();
document.querySelector('#trigger-messages').addEventListener('click', triggerMessages);
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions test/functional/fixtures/api/es-next/console/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
describe('[API] t.getConsoleMessages()', function () {
it('Should return messages from the console', function () {
return runTests('./testcafe-fixtures/console-test.js', 't.getConsoleMessages');
});

it('Should format messages if several args were passed', function () {
return runTests('./testcafe-fixtures/console-test.js', 'messages formatting');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
fixture `Double Click`;


test
.page `http://localhost:3000/fixtures/api/es-next/console/pages/index.html`
('t.getConsoleMessages', async t => {
let messages = await t.getConsoleMessages();

await t
.expect(messages.error).eql(['error1'])
.expect(messages.warn).eql(['warn1'])
.expect(messages.log).eql(['log1'])
.expect(messages.info).eql(['info1'])

.click('#trigger-messages')

// Check the driver keeps the messages between page reloads
.click('#reload');

messages = await t.getConsoleMessages();

await t
.expect(messages.error).eql(['error1', 'error2'])
.expect(messages.warn).eql(['warn1', 'warn2'])
.expect(messages.log).eql(['log1', 'log2'])
.expect(messages.info).eql(['info1', 'info2']);
});

test
.page `http://localhost:3000/fixtures/api/es-next/console/pages/empty.html`
('messages formatting', async t => {
/* eslint-disable no-console */
await t.eval(() => console.log('a', 1, null, void 0, ['b', 2], { c: 3 }));
/* eslint-enable no-console */

const { log } = await t.getConsoleMessages();

await t.expect(log[0]).eql('a 1 null undefined b,2 [object Object]');
});
38 changes: 35 additions & 3 deletions test/server/data/test-suites/typescript-defs/test-controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference path="../../../../../ts-defs/index.d.ts" />
import { Selector, ClientFunction } from 'testcafe';
import { expect } from 'chai';
import {Selector, ClientFunction} from 'testcafe';
import {expect} from 'chai';

fixture(`TestController`)
.page(`http://localhost:3000/fixtures/api/es-next/assertions/pages/index.html`);
Expand Down Expand Up @@ -704,7 +704,7 @@ test('Take a screenshot in quarantine mode', async t => {


test('Type text in input', async t => {
await t.typeText('#input', 'a', { replace: true });
await t.typeText('#input', 'a', {replace: true});
});


Expand Down Expand Up @@ -746,3 +746,35 @@ test('Chaining callsites', async t => {
.click('#error')
.click('#btn3');
});

test('t.getConsoleMessages', async t => {
let messages = await t.getConsoleMessages();

await t
.expect(messages.error).eql(['error1'])
.expect(messages.warn).eql(['warn1'])
.expect(messages.log).eql(['log1'])
.expect(messages.info).eql(['info1'])

.click('#trigger-messages')

// Check the driver keeps the messages between page reloads
.click('#reload');

messages = await t.getConsoleMessages();

await t
.expect(messages.error).eql(['error1', 'error2'])
.expect(messages.warn).eql(['warn1', 'warn2'])
.expect(messages.log).eql(['log1', 'log2'])
.expect(messages.info).eql(['info1', 'info2']);
});

test('messages formatting', async t => {
// Several arguments
await t.eval(() => console.log('a', 1, null, void 0, ['b', 2], {c: 3}))

let {log} = await t.getConsoleMessages();

await t.expect(log[0]).eql('a 1 null undefined b,2 [object Object]');
});
23 changes: 23 additions & 0 deletions ts-defs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,25 @@ interface NativeDialogHistoryItem {
url: string;
}

interface ConsoleMessagesCollection {
/**
* TODO:
*/
log: string[],
/**
* TODO:
*/
warn: string[],
/**
* TODO:
*/
error: string[],
/**
* TODO:
*/
info: string[]
}

interface TestController {
/**
* Dictionary that is shared between test hook functions and test code.
Expand Down Expand Up @@ -1004,6 +1023,10 @@ interface TestController {
* corresponds to a certain native dialog that appears in the main window or in an `<iframe>`.
*/
getNativeDialogHistory(): Promise<NativeDialogHistoryItem[]>;
/**
* TODO: Returns a collection of browser console messages.
*/
getConsoleMessages(): Promise<ConsoleMessagesCollection>;
/**
* Starts an assertion chain and specifies assertion actual value.
*
Expand Down

0 comments on commit 03f0969

Please sign in to comment.