Open GoogleCodeExporter opened 8 years ago
Oh, and I should have mentioned (just to make matters worse): once this error
occurs, your whole JS Test Driver setup is hosed; it won't work again until you
CTRL+C the server and/or refresh the browser window. Hopefully this helps
explain more why it took me an hour just to figure out what was going on ...
Original comment by jer...@syapse.com
on 16 Feb 2012 at 9:52
Console in Google Chrome says:
Exception TypeError: Cannot use 'in' operator to search for 'name' in foo
undefined(undefined):
TypeError: Cannot use 'in' operator to search for 'name' in foo
at Object.serializePropertyOnObject (http://127.0.0.1:42442/static/jstestdrivernamespace.js:1:3584)
at Object.serializeErrorToArray (http://127.0.0.1:42442/static/jstestdrivernamespace.js:1:2734)
at Object.serializeErrors (http://127.0.0.1:42442/static/jstestdrivernamespace.js:1:2509)
at [object Object].serializeError (http://127.0.0.1:42442/static/runner.js:1925:29)
at [object Object].runTest (http://127.0.0.1:42442/static/runner.js:1916:57)
at b (http://127.0.0.1:42442/static/jstestdrivernamespace.js:1:420)
at nextTest (http://127.0.0.1:42442/static/runner.js:1783:16)
at [object Object].pausingRunTestLoop [as runTestLoop_] (http://127.0.0.1:42442/static/runner.js:1795:5)
at [object Object].runTestConfiguration (http://127.0.0.1:42442/static/runner.js:1839:8)
at [object Object].runTestConfiguration (http://127.0.0.1:42442/static/runner.js:2226:33)
runner.js:356 Uncaught TypeError: Cannot use 'in' operator to search for 'name'
in foo
Original comment by vkhomyackov
on 20 Feb 2012 at 2:58
From console of Chrome:
> typeof (function(){try{throw "foo"}catch(ex){return ex}})()
"string"
> "name" in (function(){try{throw "foo"}catch(ex){return ex}})()
TypeError: Cannot use 'in' operator to search for 'name' in foo
throw "foo" returns string (not Object), which cannot be properly tested in
jstestdriver.utils.serializePropertyOnObject()
Original comment by vkhomyackov
on 20 Feb 2012 at 3:29
Maybe this will work (at least in console it causes no errors):
jstestdriver.utils.serializePropertyOnObject = function(b, c, a) {
if(c && c[b]) {
a.push(",");
a.push('"' + b + '":');
this.serializeObjectToArray(c[b], a)
}
};
Original comment by vkhomyackov
on 20 Feb 2012 at 3:32
I have a fix for this.
Your code expects all exceptions to be thrown as an Error object like this:
throw new Error("error message");
But there are many places that throw just a string, or some other type of
object like this:
throw "error message"
This will cause problems in jsTestDriver.
But the code below will check to see if the exception that was caught has a
name property. If not it created an Error object and continues on. This has not
been fully tested for other types of thrown data. We only tested it with
throwing strings.
But with a little more work this can be corrected to allow anything to be
thrown and your code will convert it into what it is expecting internally.
There are three places we do this each marked with the comment:
// FIX: Convert the exception into an error if it does not have e.name
We had changed our code to always throw a new Error(message) but the we noticed
that jQuery and other libraries just throw strings. So we figured the best
place to put the fix was in the RunTest function.
Here is the code:
jstestdriver.plugins.TestRunnerPlugin.prototype.runTest =
function (testCaseName, testCase, testName) {
var testCaseInstance;
var errors = [];
try {
try {
testCaseInstance = new testCase();
} catch (e) {
return new jstestdriver.TestResult(
testCaseName,
testName,
jstestdriver.TestResult.RESULT.ERROR,
testCaseName + ' is not a test case',
'',
0);
}
var start = new this.dateObj_().getTime();
jstestdriver.expectedAssertCount = -1;
jstestdriver.assertCount = 0;
var res = jstestdriver.TestResult.RESULT.PASSED;
try {
if (testCaseInstance.setUp) {
testCaseInstance.setUp();
}
if (!(testName in testCaseInstance)) {
var err = new Error(testName + ' not found in ' + testCaseName);
err.name = 'AssertError';
throw err;
}
testCaseInstance[testName]();
if (jstestdriver.expectedAssertCount != -1 &&
jstestdriver.expectedAssertCount != jstestdriver.assertCount) {
var err = new Error("Expected '" +
jstestdriver.expectedAssertCount +
"' asserts but '" +
jstestdriver.assertCount +
"' encountered.");
err.name = 'AssertError';
throw err;
}
} catch (e) {
// We use the global here because of a circular dependency. The isFailure plugin should be refactored.
var ex = e.name ? e : new Error(e); // FIX: Convert the exception into an error if it does not have e.name
res = jstestdriver.pluginRegistrar.isFailure(ex) ?
jstestdriver.TestResult.RESULT.FAILED :
jstestdriver.TestResult.RESULT.ERROR;
errors.push(ex);
}
try {
if (testCaseInstance.tearDown) {
testCaseInstance.tearDown();
}
this.clearBody_();
} catch (e) {
var ex = e.name ? e : new Error(e); // FIX: Convert the exception into an error if it does not have e.name
if (res == jstestdriver.TestResult.RESULT.PASSED) {
res = jstestdriver.TestResult.RESULT.ERROR;
}
errors.push(ex);
}
var end = new this.dateObj_().getTime();
var msg = this.serializeError(errors);
return new jstestdriver.TestResult(testCaseName, testName, res, msg,
jstestdriver.console.getAndResetLog(), end - start);
} catch (e) {
var ex = e.name ? e : new Error(e); // FIX: Convert the exception into an error if it does not have e.name
errors.push(ex);
return new jstestdriver.TestResult(testCaseName, testName,
'error', 'Unexpected runner error: ' + this.serializeError(errors),
jstestdriver.console.getAndResetLog(), 0);
}
};
Original comment by Intervalia
on 22 Mar 2012 at 11:39
FYI, this doesn't happen in 1.3.3d, which just fails with ["String"], so it's a
regression in both 1.3.4a and 1.3.4b;
Original comment by lrekucki
on 25 Apr 2012 at 9:51
Original issue reported on code.google.com by
jer...@syapse.com
on 16 Feb 2012 at 9:49