Skip to content

Commit b37d237

Browse files
inikulinhelen-dikareva
authored andcommitted
Hybrid function execution error (#241) (#512)
1 parent 5b7302a commit b37d237

File tree

9 files changed

+109
-26
lines changed

9 files changed

+109
-26
lines changed

src/client/driver/command-executors/execute-hybrid-fn-command.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import hammerhead from '../deps/hammerhead';
22
import DriverStatus from '../status';
3+
import { UncaughtErrorInClientExecutedCode } from '../../../errors/test-run';
34

45
var Promise = hammerhead.Promise;
56

@@ -14,5 +15,8 @@ export default function executeHybridFnCommand (command) {
1415
})
1516
.then(fn => fn.apply(window, command.args))
1617
.then(result => new DriverStatus({ isCommandResult: true, result }))
17-
.catch(err => new DriverStatus({ isCommandResult: true, result: err.message }));
18+
.catch(err => new DriverStatus({
19+
isCommandResult: true,
20+
executionError: new UncaughtErrorInClientExecutedCode(err)
21+
}));
1822
}

src/compiler/es-next/compile-hybrid-function.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const TRAILING_SEMICOLON_RE = /;\s*$/;
1212
const REGENERATOR_FOOTPRINTS_RE = /(_regenerator(\d+).default|regeneratorRuntime).wrap\(function _callee\$\(_context\)/;
1313
const ASYNC_TO_GENERATOR_OUTPUT_CODE = asyncToGenerator(noop).toString();
1414

15-
1615
var babelArtifactPolyfills = {
1716
'Promise': {
1817
re: /_promise(\d+)\.default/,

src/errors/test-run/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ export class UncaughtNonErrorObjectInTestCode extends UncaughtError {
8686
}
8787
}
8888

89+
export class UncaughtErrorInClientExecutedCode extends UncaughtError {
90+
constructor (err) {
91+
super(TYPE.uncaughtErrorInClientExecutedCode);
92+
93+
this.errMsg = String(err);
94+
}
95+
}
96+
8997

9098
// Assertion errors
9199
//--------------------------------------------------------------------

src/errors/test-run/templates.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ export default {
5656
${err.getCallsiteMarkup()}
5757
`),
5858

59+
[TYPE.uncaughtErrorInClientExecutedCode]: err => markup(err, `
60+
An error occurred in code executed on the client:
61+
62+
<code>${escapeHtml(err.errMsg)}</code>
63+
64+
${err.getCallsiteMarkup()}
65+
`),
66+
5967
[TYPE.uncaughtNonErrorObjectInTestCode]: err => markup(err, `
6068
Uncaught ${err.objType} "${escapeHtml(err.objStr)}" was thrown. Throw <code>Error</code> instead.
6169
`),

src/errors/test-run/type.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
// -------------------------------------------------------------
55

66
export default {
7-
uncaughtErrorOnPage: 'uncaughtErrorOnPage',
8-
uncaughtErrorInTestCode: 'uncaughtErrorInTestCode',
9-
uncaughtNonErrorObjectInTestCode: 'uncaughtNonErrorObjectInTestCode',
7+
uncaughtErrorOnPage: 'uncaughtErrorOnPage',
8+
uncaughtErrorInTestCode: 'uncaughtErrorInTestCode',
9+
uncaughtNonErrorObjectInTestCode: 'uncaughtNonErrorObjectInTestCode',
10+
uncaughtErrorInClientExecutedCode: 'uncaughtErrorInClientExecutedCode',
1011

1112
missingAwaitError: 'missingAwaitError',
1213

test/functional/fixtures/api/es-next/hybrid-function/test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,22 @@ describe('[API] Hybrid function', function () {
101101
it('Should polyfill Babel artifacts', function () {
102102
return runTests('./testcafe-fixtures/hybrid-fn-test.js', 'Babel artifacts polyfills');
103103
});
104+
105+
it('Should handle error in Hybrid code', function () {
106+
return runTests('./testcafe-fixtures/hybrid-fn-test.js', 'Error in code', { shouldFail: true })
107+
.catch(function (errs) {
108+
expect(errs[0]).contains('An error occurred in code executed on the client:');
109+
expect(errs[0]).contains('Error: Hey ya!');
110+
expect(errs[0]).contains('> 123 | await fn();');
111+
});
112+
});
113+
114+
it('Should handle error in Promise in Hybrid code', function () {
115+
return runTests('./testcafe-fixtures/hybrid-fn-test.js', 'Error in Promise', { shouldFail: true })
116+
.catch(function (errs) {
117+
expect(errs[0]).contains('An error occurred in code executed on the client:');
118+
expect(errs[0]).contains('Error: 42');
119+
expect(errs[0]).contains('> 133 | await fn();');
120+
});
121+
});
104122
});

test/functional/fixtures/api/es-next/hybrid-function/testcafe-fixtures/hybrid-fn-test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,21 @@ test('Babel artifacts polyfills', async () => {
114114

115115
expect(JSON.parse(res)).eql(['1', '2']);
116116
});
117+
118+
test('Error in code', async () => {
119+
var fn = Hybrid(() => {
120+
throw new Error('Hey ya!');
121+
});
122+
123+
await fn();
124+
});
125+
126+
test('Error in Promise', async () => {
127+
var fn = Hybrid(() => {
128+
return Promise.resolve().then(()=> {
129+
throw new Error('42');
130+
});
131+
});
132+
133+
await fn();
134+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Chrome 15.0.874 / Mac OS X 10.8.1
2+
CATEGORY=uncaughtError
3+
An error occurred in code executed on the client:
4+
5+
Error: Some error.
6+
7+
18 |function func1 () {
8+
19 | record = createCallsiteRecord('func1');
9+
20 |}
10+
21 |
11+
22 |(function func2 () {
12+
> 23 | func1();
13+
24 |})();
14+
25 |
15+
26 |stackTrace.filter.deattach(stackFilter);
16+
27 |
17+
28 |module.exports = record;
18+
19+
at func2 (testfile.js:23:5)
20+
at Object.<anonymous> (testfile.js:24:3)
21+
22+
Screenshot: /unix/path/with/<tag>

test/server/test-run-error-formatting-test.js

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
var expect = require('chai').expect;
2-
var read = require('read-file-relative').readSync;
3-
var remove = require('lodash').pull;
4-
var escapeRe = require('lodash').escapeRegExp;
5-
var ReporterPluginHost = require('../../lib/reporter/plugin-host');
6-
var TYPE = require('../../lib/errors/test-run/type');
7-
var TestRunErrorFormattableAdapter = require('../../lib/errors/test-run/formattable-adapter');
8-
var testCallsite = require('./data/test-callsite');
9-
var ActionIntegerOptionError = require('../../lib/errors/test-run').ActionIntegerOptionError;
10-
var ActionPositiveIntegerOptionError = require('../../lib/errors/test-run').ActionPositiveIntegerOptionError;
11-
var ActionIntegerArgumentError = require('../../lib/errors/test-run').ActionIntegerArgumentError;
12-
var ActionPositiveIntegerArgumentError = require('../../lib/errors/test-run').ActionPositiveIntegerArgumentError;
13-
var ActionBooleanOptionError = require('../../lib/errors/test-run').ActionBooleanOptionError;
14-
var ActionSelectorTypeError = require('../../lib/errors/test-run').ActionSelectorTypeError;
15-
var ActionOptionsTypeError = require('../../lib/errors/test-run').ActionOptionsTypeError;
16-
var ActionStringArgumentError = require('../../lib/errors/test-run').ActionStringArgumentError;
17-
var ActionAdditionalSelectorTypeError = require('../../lib/errors/test-run').ActionAdditionalSelectorTypeError;
18-
var UncaughtErrorOnPage = require('../../lib/errors/test-run').UncaughtErrorOnPage;
19-
var UncaughtErrorInTestCode = require('../../lib/errors/test-run').UncaughtErrorInTestCode;
20-
var UncaughtNonErrorObjectInTestCode = require('../../lib/errors/test-run').UncaughtNonErrorObjectInTestCode;
21-
var ActionElementNotFoundError = require('../../lib/errors/test-run').ActionElementNotFoundError;
1+
var expect = require('chai').expect;
2+
var read = require('read-file-relative').readSync;
3+
var remove = require('lodash').pull;
4+
var escapeRe = require('lodash').escapeRegExp;
5+
var ReporterPluginHost = require('../../lib/reporter/plugin-host');
6+
var TYPE = require('../../lib/errors/test-run/type');
7+
var TestRunErrorFormattableAdapter = require('../../lib/errors/test-run/formattable-adapter');
8+
var testCallsite = require('./data/test-callsite');
9+
var ActionIntegerOptionError = require('../../lib/errors/test-run').ActionIntegerOptionError;
10+
var ActionPositiveIntegerOptionError = require('../../lib/errors/test-run').ActionPositiveIntegerOptionError;
11+
var ActionIntegerArgumentError = require('../../lib/errors/test-run').ActionIntegerArgumentError;
12+
var ActionPositiveIntegerArgumentError = require('../../lib/errors/test-run').ActionPositiveIntegerArgumentError;
13+
var ActionBooleanOptionError = require('../../lib/errors/test-run').ActionBooleanOptionError;
14+
var ActionSelectorTypeError = require('../../lib/errors/test-run').ActionSelectorTypeError;
15+
var ActionOptionsTypeError = require('../../lib/errors/test-run').ActionOptionsTypeError;
16+
var ActionStringArgumentError = require('../../lib/errors/test-run').ActionStringArgumentError;
17+
var ActionAdditionalSelectorTypeError = require('../../lib/errors/test-run').ActionAdditionalSelectorTypeError;
18+
var UncaughtErrorOnPage = require('../../lib/errors/test-run').UncaughtErrorOnPage;
19+
var UncaughtErrorInTestCode = require('../../lib/errors/test-run').UncaughtErrorInTestCode;
20+
var UncaughtErrorInClientExecutedCode = require('../../lib/errors/test-run').UncaughtErrorInClientExecutedCode;
21+
var UncaughtNonErrorObjectInTestCode = require('../../lib/errors/test-run').UncaughtNonErrorObjectInTestCode;
22+
var ActionElementNotFoundError = require('../../lib/errors/test-run').ActionElementNotFoundError;
2223
var ActionElementIsInvisibleError = require('../../lib/errors/test-run').ActionElementIsInvisibleError;
2324
var ActionAdditionalElementNotFoundError = require('../../lib/errors/test-run').ActionAdditionalElementNotFoundError;
2425
var ActionAdditionalElementIsInvisibleError = require('../../lib/errors/test-run').ActionAdditionalElementIsInvisibleError;
@@ -187,6 +188,10 @@ describe('Error formatting', function () {
187188
it('Should format "externalAssertionLibraryError', function () {
188189
assertErrorMessage('external-assertion-library-error', new ExternalAssertionLibraryError(testAssertionError, testCallsite));
189190
});
191+
192+
it('Should format "uncaughtErrorInClientExecutedCode"', function () {
193+
assertErrorMessage('uncaught-error-in-client-executed-code', new UncaughtErrorInClientExecutedCode(new Error('Some error.')));
194+
});
190195
});
191196

192197
describe('Test coverage', function () {

0 commit comments

Comments
 (0)