Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit 289dbb9

Browse files
committed
fix(util): properly handle exceptions from onPrepare and onExit
1 parent 2572feb commit 289dbb9

File tree

3 files changed

+61
-65
lines changed

3 files changed

+61
-65
lines changed

lib/configParser.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var path = require('path'),
22
glob = require('glob'),
33
util = require('util'),
44
_ = require('lodash'),
5-
protractor = require('./protractor.js');
5+
helper = require('./util');
66

77
// Coffee is required here to enable config files written in coffee-script.
88
try {
@@ -32,7 +32,7 @@ var ConfigParser = function() {
3232
isVerbose: false,
3333
showColors: true,
3434
includeStackTrace: true,
35-
stackFilter: protractor.filterStackTrace,
35+
stackFilter: helper.filterStackTrace,
3636
defaultTimeoutInterval: (30 * 1000)
3737
},
3838
seleniumArgs: [],

lib/protractor.js

+6-51
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var url = require('url');
22
var util = require('util');
33
var webdriver = require('selenium-webdriver');
4+
var helper = require('./util');
45

56
var clientSideScripts = require('./clientsidescripts.js');
67
var ProtractorBy = require('./locators.js').ProtractorBy;
@@ -14,17 +15,6 @@ var WEB_ELEMENT_FUNCTIONS = [
1415
'getSize', 'getLocation', 'isEnabled', 'isSelected', 'submit', 'clear',
1516
'isDisplayed', 'getOuterHtml', 'getInnerHtml', 'getId'];
1617

17-
var STACK_SUBSTRINGS_TO_FILTER = [
18-
'node_modules/minijasminenode/lib/',
19-
'node_modules/selenium-webdriver',
20-
'at Module.',
21-
'at Object.Module.',
22-
'at Function.Module',
23-
'(timers.js:',
24-
'jasminewd/index.js',
25-
'protractor/lib/'
26-
];
27-
2818
var DEFAULT_RESET_URL = 'data:text/html,<html></html>';
2919
var DEFAULT_GET_PAGE_TIMEOUT = 10000;
3020

@@ -1478,21 +1468,11 @@ Protractor.prototype.pause = function(opt_debugPort) {
14781468

14791469
var getDescriptions = function(frameOrTask, descriptions) {
14801470
if (frameOrTask.getDescription) {
1481-
var getRelevantStack = function(stack) {
1482-
return stack.filter(function(line) {
1483-
var include = true;
1484-
for (var i = 0; i < STACK_SUBSTRINGS_TO_FILTER.length; ++i) {
1485-
if (line.toString().indexOf(STACK_SUBSTRINGS_TO_FILTER[i]) !==
1486-
-1) {
1487-
include = false;
1488-
}
1489-
}
1490-
return include;
1491-
});
1492-
};
1471+
var stacktrace = frameOrTask.snapshot_.getStacktrace();
1472+
stacktrace = stacktrace ? stacktrace.join('\n').trim() : '';
14931473
descriptions.push({
14941474
description: frameOrTask.getDescription(),
1495-
stack: getRelevantStack(frameOrTask.snapshot_.getStacktrace())
1475+
stack: helper.filterStackTrace(stacktrace)
14961476
});
14971477
} else {
14981478
for (var i = 0; i < frameOrTask.children_.length; ++i) {
@@ -1510,8 +1490,8 @@ Protractor.prototype.pause = function(opt_debugPort) {
15101490
var asString = '-- WebDriver control flow schedule \n';
15111491
for (var i = 0; i < descriptions.length; ++i) {
15121492
asString += ' |- ' + descriptions[i].description;
1513-
if (descriptions[i].stack.length) {
1514-
asString += '\n |---' + descriptions[i].stack.join('\n |---');
1493+
if (descriptions[i].stack) {
1494+
asString += '\n |---' + descriptions[i].stack.replace(/\n/g, '\n |---');
15151495
}
15161496
if (i != (descriptions.length - 1)) {
15171497
asString += '\n';
@@ -1571,28 +1551,3 @@ exports.setInstance = function(ptor) {
15711551
exports.getInstance = function() {
15721552
return instance;
15731553
};
1574-
1575-
/**
1576-
* Utility function that filters a stack trace to be more readable. It removes
1577-
* Jasmine test frames and webdriver promise resolution.
1578-
* @param {string} text Original stack trace.
1579-
* @return {string}
1580-
*/
1581-
exports.filterStackTrace = function(text) {
1582-
if (!text) {
1583-
return text;
1584-
}
1585-
var lines = [];
1586-
text.split(/\n/).forEach(function(line) {
1587-
var include = true;
1588-
for (var i = 0; i < STACK_SUBSTRINGS_TO_FILTER.length; ++i) {
1589-
if (line.indexOf(STACK_SUBSTRINGS_TO_FILTER[i]) !== -1) {
1590-
include = false;
1591-
}
1592-
}
1593-
if (include) {
1594-
lines.push(line);
1595-
}
1596-
});
1597-
return lines.join('\n');
1598-
};

lib/util.js

+53-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
var q = require('q'),
2-
path = require('path');
2+
path = require('path'),
3+
webdriver = require('selenium-webdriver');
4+
5+
var STACK_SUBSTRINGS_TO_FILTER = [
6+
'node_modules/minijasminenode/lib/',
7+
'node_modules/selenium-webdriver',
8+
'at Module.',
9+
'at Object.Module.',
10+
'at Function.Module',
11+
'(timers.js:',
12+
'jasminewd/index.js',
13+
'protractor/lib/'
14+
];
15+
16+
17+
/**
18+
* Utility function that filters a stack trace to be more readable. It removes
19+
* Jasmine test frames and webdriver promise resolution.
20+
* @param {string} text Original stack trace.
21+
* @return {string}
22+
*/
23+
exports.filterStackTrace = function(text) {
24+
if (!text) {
25+
return text;
26+
}
27+
var lines = text.split(/\n/).filter(function(line) {
28+
for (var i = 0; i < STACK_SUBSTRINGS_TO_FILTER.length; ++i) {
29+
if (line.indexOf(STACK_SUBSTRINGS_TO_FILTER[i]) !== -1) {
30+
return false;
31+
}
32+
}
33+
return true;
34+
});
35+
return lines.join('\n');
36+
};
337

438
/**
539
* Internal helper for abstraction of polymorphic filenameOrFn properties.
@@ -8,20 +42,27 @@ var q = require('q'),
842
* @return {q.Promise} A promise that will resolve when filenameOrFn completes.
943
*/
1044
exports.runFilenameOrFn_ = function(configDir, filenameOrFn, args) {
11-
var returned = null;
12-
if (filenameOrFn) {
13-
if (typeof filenameOrFn === 'function') {
14-
returned = filenameOrFn.apply(null, args);
15-
} else if (typeof filenameOrFn === 'string') {
45+
return q.promise(function(resolve) {
46+
if (filenameOrFn &&
47+
!(typeof filenameOrFn === 'string' || typeof filenameOrFn === 'function')) {
48+
throw 'filenameOrFn must be a string or function';
49+
}
50+
51+
if (typeof filenameOrFn === 'string') {
1652
filenameOrFn = require(path.resolve(configDir, filenameOrFn));
17-
if (typeof filenameOrFn === 'function') {
18-
returned = filenameOrFn.apply(null, args);
19-
}
53+
}
54+
if (typeof filenameOrFn === 'function') {
55+
var results = webdriver.promise.controlFlow().execute(function() {
56+
return filenameOrFn.apply(null, args);
57+
}, 'executing onPrepare').then(null, function(err) {
58+
err.stack = exports.filterStackTrace(err.stack);
59+
throw err;
60+
});
61+
resolve(results);
2062
} else {
21-
throw 'filenameOrFn must be a string or function';
63+
resolve();
2264
}
23-
}
24-
return q(returned);
65+
});
2566
};
2667

2768
/**

0 commit comments

Comments
 (0)