Skip to content

Commit

Permalink
Unify errors rendering (closes #600) (#622)
Browse files Browse the repository at this point in the history
* Implement `t.select`

* Unify error messages: test run errors

* Fix rebase errors

* Unify error messages: runtime errors

* Move buildReporterPlugin to embedding utils

* Bump version
  • Loading branch information
inikulin authored and AlexanderMoskovkin committed Jun 27, 2016
1 parent e5330f8 commit 97329b2
Show file tree
Hide file tree
Showing 56 changed files with 227 additions and 255 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "testcafe",
"version": "0.0.17",
"version": "0.0.18",
"main": "lib/index",
"bin": {
"testcafe": "./bin/testcafe"
Expand Down
26 changes: 13 additions & 13 deletions src/errors/runtime/message.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions src/errors/test-run/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,8 @@ export class ActionUnsupportedDeviceTypeError extends ActionArgumentErrorBase {

// Selector errors
export class ActionSelectorError extends TestRunErrorBase {
constructor (errMsg) {
super(TYPE.actionSelectorError);

this.errMsg = errMsg;
}
}

export class ActionAdditionalSelectorError extends TestRunErrorBase {
constructor (selectorName, errMsg) {
super(TYPE.actionAdditionalSelectorError);
super(TYPE.actionSelectorError);

this.selectorName = selectorName;
this.errMsg = errMsg;
Expand Down
54 changes: 23 additions & 31 deletions src/errors/test-run/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ function markup (err, msgMarkup) {

export default {
[TYPE.actionPositiveIntegerOptionError]: err => markup(err, `
The <code>${err.optionName}</code> option is expected to be a positive integer, but it was <code>${err.actualValue}</code>.
The "${err.optionName}" option is expected to be a positive integer, but it was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),

[TYPE.actionBooleanOptionError]: err => markup(err, `
The <code>${err.optionName}</code> option is expected to be a boolean value, but it was <code>${err.actualValue}</code>.
The "${err.optionName}" option is expected to be a boolean value, but it was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),
Expand All @@ -54,61 +54,61 @@ export default {
`),

[TYPE.uncaughtErrorInClientFunctionCode]: err => markup(err, `
An error occurred in <code>${err.instantiationCallsiteName}</code> code:
An error occurred in ${err.instantiationCallsiteName} code:
${escapeHtml(err.errMsg)}
${err.getCallsiteMarkup()}
`),

[TYPE.clientFunctionExecutionInterruptionError]: err => markup(err, `
<code>${err.instantiationCallsiteName}</code> execution was interrupted by page unload. This problem may appear if you trigger page navigation from <code>${err.instantiationCallsiteName}</code> code.
${err.instantiationCallsiteName} execution was interrupted by page unload. This problem may appear if you trigger page navigation from ${err.instantiationCallsiteName} code.
${err.getCallsiteMarkup()}
`),

[TYPE.uncaughtNonErrorObjectInTestCode]: err => markup(err, `
Uncaught ${err.objType} "${escapeHtml(err.objStr)}" was thrown. Throw <code>Error</code> instead.
Uncaught ${err.objType} "${escapeHtml(err.objStr)}" was thrown. Throw Error instead.
`),

[TYPE.actionOptionsTypeError]: err => markup(err, `
Action options is expected to be an object, <code>null</code> or <code>undefined</code> but it was <code>${err.actualType}</code>.
Action options is expected to be an object, null or undefined but it was ${err.actualType}.
${err.getCallsiteMarkup()}
`),

[TYPE.actionUnsupportedUrlProtocolError]: err => markup(err, `
The <code>${err.argumentName}</code> argument specifies a URL that uses an unsupported <code>${err.protocol}://</code> protocol. Only HTTP and HTTPS are supported, as well as protocol-relative and relative URLs.
The "${err.argumentName}" argument specifies a URL that uses an unsupported ${err.protocol}:// protocol. Only HTTP and HTTPS are supported, as well as protocol-relative and relative URLs.
${err.getCallsiteMarkup()}
`),

[TYPE.actionStringArgumentError]: err => markup(err, `
The <code>${err.argumentName}</code> argument is expected to be a non-empty string, but it was <code>${err.actualValue}</code>.
The "${err.argumentName}" argument is expected to be a non-empty string, but it was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),

[TYPE.actionStringOrStringArrayArgumentError]: err => markup(err, `
The <code>${err.argumentName}</code> argument is expected to be a non-empty string or a string array, but it was ${err.actualValue}.
The "${err.argumentName}" argument is expected to be a non-empty string or a string array, but it was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),

[TYPE.actionStringArrayElementError]: err => markup(err, `
Elements of the <code>${err.argumentName}</code> argument are expected to be non-empty strings, but the element at index <code>${err.elementIndex}</code> was ${err.actualValue}.
Elements of the "${err.argumentName}" argument are expected to be non-empty strings, but the element at index ${err.elementIndex} was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),

[TYPE.actionIntegerArgumentError]: err => markup(err, `
The <code>${err.argumentName}</code> argument is expected to be an integer, but it was <code>${err.actualValue}</code>.
The "${err.argumentName}" argument is expected to be an integer, but it was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),

[TYPE.actionPositiveIntegerArgumentError]: err => markup(err, `
The <code>${err.argumentName}</code> argument is expected to be a positive integer, but it was <code>${err.actualValue}</code>.
The "${err.argumentName}" argument is expected to be a positive integer, but it was ${err.actualValue}.
${err.getCallsiteMarkup()}
`),
Expand All @@ -126,13 +126,13 @@ export default {
`),

[TYPE.actionAdditionalElementNotFoundError]: err => markup(err, `
The specified <code>${err.argumentName}</code> does not match any element in the DOM tree.
The specified "${err.argumentName}" does not match any element in the DOM tree.
${err.getCallsiteMarkup()}
`),

[TYPE.actionAdditionalElementIsInvisibleError]: err => markup(err, `
The element that matches the specified <code>${err.argumentName}</code> is not visible.
The element that matches the specified "${err.argumentName}" is not visible.
${err.getCallsiteMarkup()}
`),
Expand All @@ -144,7 +144,7 @@ export default {
`),

[TYPE.actionElementNonContentEditableError]: err => markup(err, `
The element that matches the specified <code>${err.argumentName}</code> is expected to have the contentEditable attribute enabled or the entire document should be in design mode.
The element that matches the specified "${err.argumentName}" is expected to have the contentEditable attribute enabled or the entire document should be in design mode.
${err.getCallsiteMarkup()}
`),
Expand All @@ -169,25 +169,25 @@ export default {
`),

[TYPE.actionElementNotTextAreaError]: err => markup(err, `
The action element is expected to be a textarea.
The action element is expected to be a &lt;textarea&gt;.
${err.getCallsiteMarkup()}
`),

[TYPE.actionElementNotIframeError]: err => markup(err, `
The action element is expected to be an iframe.
The action element is expected to be an &lt;iframe&gt.
${err.getCallsiteMarkup()}
`),

[TYPE.actionIncorrectKeysError]: err => markup(err, `
The <code>${err.argumentName}</code> argument contains an incorrect key or key combination.
The "${err.argumentName}" argument contains an incorrect key or key combination.
${err.getCallsiteMarkup()}
`),

[TYPE.actionUnsupportedDeviceTypeError]: err => markup(err, `
The <code>${err.argumentName}</code> argument specifies an unsupported <code>${err.actualValue}</code> device. For a list of supported devices, refer to <a href="http://viewportsizes.com">http://viewportsizes.com</a>
The "${err.argumentName}" argument specifies an unsupported "${err.actualValue}" device. For a list of supported devices, refer to <a href="http://viewportsizes.com">http://viewportsizes.com</a>.
${err.getCallsiteMarkup()}
`),
Expand Down Expand Up @@ -217,7 +217,7 @@ export default {
`),

[TYPE.missingAwaitError]: err => markup(err, `
A call to an async function is not awaited. Use the <code>await</code> keyword before actions, assertions or chains of them to ensure that they run in the right sequence.
A call to an async function is not awaited. Use the "await" keyword before actions, assertions or chains of them to ensure that they run in the right sequence.
${err.getCallsiteMarkup()}
`),
Expand All @@ -229,27 +229,19 @@ export default {
`),

[TYPE.domNodeClientFunctionResultError]: err => markup(err, `
<code>${err.instantiationCallsiteName}</code> cannot return DOM elements. Use <code>Selector</code> functions for this purpose.
${err.instantiationCallsiteName} cannot return DOM elements. Use Selector functions for this purpose.
${err.getCallsiteMarkup()}
`),

[TYPE.nonDomNodeSelectorResultError]: err => markup(err, `
<code>${err.instantiationCallsiteName}</code> can only return a DOM node, <code>null</code> or <code>undefined</code>. Use ClientFunction to return other values.
${err.instantiationCallsiteName} can only return a DOM node, null or undefined. Use ClientFunction to return other values.
${err.getCallsiteMarkup()}
`),

[TYPE.actionSelectorError]: err => markup(err, `
Action <code>selector</code> error:
${escapeHtml(err.errMsg)}
${err.getCallsiteMarkup()}
`),

[TYPE.actionAdditionalSelectorError]: err => markup(err, `
Action <code>${err.selectorName}</code> error:
Action "${err.selectorName}" argument error:
${escapeHtml(err.errMsg)}
Expand Down
1 change: 0 additions & 1 deletion src/errors/test-run/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export default {
actionIntegerArgumentError: 'actionIntegerArgumentError',
actionPositiveIntegerArgumentError: 'actionPositiveIntegerArgumentError',
actionSelectorError: 'actionSelectorError',
actionAdditionalSelectorError: 'actionAdditionalSelectorError',
actionUnsupportedUrlProtocolError: 'actionUnsupportedUrlProtocolError',
actionElementNotFoundError: 'actionElementNotFoundError',
actionElementIsInvisibleError: 'actionElementIsInvisibleError',
Expand Down
11 changes: 4 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,17 @@ async function createTestCafe (hostname, port1, port2) {
return new TestCafe(hostname, port1, port2);
}

// Plugin testing utils
createTestCafe.pluginTestingUtils = {
// Embedding utils
createTestCafe.embeddingUtils = {
TestRunErrorFormattableAdapter: TestRunErrorFormattableAdapter,

buildReporterPlugin (pluginFactory, outStream) {
var plugin = pluginFactory();

return new ReporterPluginHost(plugin, outStream);
}
};

// Embedding utils
createTestCafe.embeddingUtils = {
TestRunErrorFormattableAdapter: TestRunErrorFormattableAdapter
};

// Common API
Object.keys(commonAPI).forEach(key => createTestCafe[key] = commonAPI[key]);

Expand Down
2 changes: 1 addition & 1 deletion src/reporter/plugin-host.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default class ReporterPluginHost {
createErrorDecorator () {
return {
'span step-name': str => `"${str}"`,
'span user-agent': str => this.chalk.gray(str),
'span user-agent': str => this.chalk.red(str),

'span subtitle': str => `- ${this.chalk.bold(str)} -\n`,

Expand Down
35 changes: 15 additions & 20 deletions src/test-run/commands/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,23 @@ import {
stringOrStringArrayArgument
} from './validations/argument';

import { ActionSelectorError, ActionAdditionalSelectorError } from '../../errors/test-run';
import { ActionSelectorError } from '../../errors/test-run';
import { APIError } from '../../errors/runtime';


// Initializers
function createSelectorInitializer (createError) {
return (name, val) => {
try {
var factory = new SelectorFactory(val, null, { instantiation: 'Selector' });

return factory.getCommand([], { visibilityCheck: true });
}
catch (err) {
var msg = err.constructor === APIError ? err.rawMessage : err.message;

throw createError(name, msg);
}
};
}
function initSelector (name, val) {
try {
var factory = new SelectorFactory(val, null, { instantiation: 'Selector' });

return factory.getCommand([], { visibilityCheck: true });
}
catch (err) {
var msg = err.constructor === APIError ? err.rawMessage : err.message;

var initSelector = createSelectorInitializer((name, msg) => new ActionSelectorError(msg));
var initAdditionalSelector = createSelectorInitializer((name, msg) => new ActionAdditionalSelectorError(name, msg));
throw new ActionSelectorError(name, msg);
}
}

function initClickOptions (name, val) {
return new ClickOptions(val, true);
Expand Down Expand Up @@ -184,7 +179,7 @@ export class DragToElementCommand extends Assignable {
_getAssignableProperties () {
return [
{ name: 'selector', init: initSelector, required: true },
{ name: 'destinationSelector', init: initAdditionalSelector, required: true },
{ name: 'destinationSelector', init: initSelector, required: true },
{ name: 'options', type: actionOptions, init: initMouseOptions, required: true }
];
}
Expand Down Expand Up @@ -224,8 +219,8 @@ export class SelectEditableContentCommand extends Assignable {

_getAssignableProperties () {
return [
{ name: 'startSelector', init: initAdditionalSelector, required: true },
{ name: 'endSelector', init: initAdditionalSelector }
{ name: 'startSelector', init: initSelector, required: true },
{ name: 'endSelector', init: initSelector }
];
}
}
Expand Down
6 changes: 3 additions & 3 deletions test/functional/fixtures/api/es-next/click/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('[API] t.click()', function () {
only: 'chrome'
})
.catch(function (errs) {
expect(errs[0]).to.contains('The offsetX option is expected to be a positive integer, but it was -3.');
expect(errs[0]).to.contains('The "offsetX" option is expected to be a positive integer, but it was -3.');
expect(errs[0]).to.contains(
' 11 |test(\'Incorrect action selector\', async t => {' +
' 12 | await t.click(123);' +
Expand All @@ -50,9 +50,9 @@ describe('[API] t.click()', function () {
})
.catch(function (errs) {
expect(errs[0]).to.contains(
'Action selector error: Selector is expected to be initialized with a ' +
'Action "selector" argument error: Selector is expected to be initialized with a ' +
'function, CSS selector string, another Selector, node snapshot or a Promise returned ' +
'by a Selector, but "number" was passed.'
'by a Selector, but number was passed.'
);
expect(errs[0]).to.contains(
'7 | .page `http://localhost:3000/fixtures/api/es-next/click/pages/index.html`;' +
Expand Down

0 comments on commit 97329b2

Please sign in to comment.