Bug 1208018 - Improve marionette stack info and dump it when executeJSScript throws. r=jgriffin

This commit is contained in:
Alexandre Poirot 2015-09-29 03:02:48 -07:00
parent a1a700a030
commit 0896aa8eee
4 changed files with 33 additions and 9 deletions

View File

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import urllib
import os
from marionette_driver import By, errors
from marionette.marionette_test import MarionetteTestCase, skip_if_b2g
@ -16,7 +17,18 @@ elements = inline("<p>foo</p> <p>bar</p>")
class TestExecuteContent(MarionetteTestCase):
def test_stack_trace(self):
def test_execute_js_script_stack_trace(self):
try:
self.marionette.execute_js_script("""
let a = 1;
throwHere();
""", filename="file.js")
self.assertFalse(True)
except errors.JavascriptException as inst:
self.assertIn('throwHere is not defined', inst.msg)
self.assertIn('@file.js:2', inst.stacktrace)
def test_execute_script_stack_trace(self):
try:
self.marionette.execute_script("""
let a = 1;
@ -24,7 +36,10 @@ class TestExecuteContent(MarionetteTestCase):
""")
self.assertFalse(True)
except errors.JavascriptException as inst:
self.assertTrue('return b' in inst.stacktrace)
# By default execute_script pass the name of the python file
self.assertIn(os.path.basename(__file__.replace(".pyc", ".py")), inst.stacktrace)
self.assertIn('b is not defined', inst.msg)
self.assertIn('return b', inst.stacktrace)
def test_execute_simple(self):
self.assertEqual(1, self.marionette.execute_script("return 1;"))

View File

@ -816,6 +816,9 @@ GeckoDriver.prototype.applyArgumentsToSandbox = function(win, sb, args) {
* True if the script is asynchronous.
* @param {number} timeout
* When to interrupt script in milliseconds.
* @param {string} filename
* Optional. URI or name of the file we are executing.
* (Used to improve stack trace readability)
*/
GeckoDriver.prototype.executeScriptInSandbox = function(
resp,
@ -823,7 +826,8 @@ GeckoDriver.prototype.executeScriptInSandbox = function(
script,
directInject,
async,
timeout) {
timeout,
filename) {
if (directInject && async && (timeout === null || timeout === 0)) {
throw new TimeoutError("Please set a timeout");
}
@ -837,7 +841,7 @@ GeckoDriver.prototype.executeScriptInSandbox = function(
script = data + script;
}
let res = Cu.evalInSandbox(script, sandbox, "1.8", "dummy file", 0);
let res = Cu.evalInSandbox(script, sandbox, "1.8", filename ? filename : "dummy file", 0);
if (directInject && !async &&
(typeof res == "undefined" || typeof res.passed == "undefined")) {
@ -945,7 +949,8 @@ GeckoDriver.prototype.execute = function(cmd, resp, directInject) {
script,
directInject,
false /* async */,
scriptTimeout);
scriptTimeout,
filename);
} catch (e) {
throw new JavaScriptError(e, "execute_script", filename, line, script);
}
@ -1180,7 +1185,8 @@ GeckoDriver.prototype.executeWithCallback = function(cmd, resp, directInject) {
script,
directInject,
true /* async */,
scriptTimeout);
scriptTimeout,
filename);
} catch (e) {
chromeAsyncError(e, "execute_async_script", filename, line, script);
}

View File

@ -207,6 +207,7 @@ this.JavaScriptError = function(err, fnName, file, line, script) {
"inline javascript, line " + jsLine + "\n" +
"src: \"" + src + "\"";
}
trace += "\nStack:\n" + String(err.stack);
}
WebDriverError.call(this, msg);

View File

@ -576,6 +576,7 @@ function executeScript(msg, directInject) {
asyncTestCommandId = msg.json.command_id;
let script = msg.json.script;
let filename = msg.json.filename;
sandboxName = msg.json.sandboxName;
if (msg.json.newSandbox ||
@ -602,7 +603,7 @@ function executeScript(msg, directInject) {
stream.close();
script = data + script;
}
let res = Cu.evalInSandbox(script, sandbox, "1.8", "dummy file" ,0);
let res = Cu.evalInSandbox(script, sandbox, "1.8", filename ? filename : "dummy file" ,0);
sendSyncMessage("Marionette:shareData",
{log: elementManager.wrapValue(marionetteLogObj.getLogs())});
marionetteLogObj.clearLogs();
@ -633,7 +634,7 @@ function executeScript(msg, directInject) {
stream.close();
script = data + script;
}
let res = Cu.evalInSandbox(script, sandbox, "1.8", "dummy file", 0);
let res = Cu.evalInSandbox(script, sandbox, "1.8", filename ? filename : "dummy file", 0);
sendSyncMessage("Marionette:shareData",
{log: elementManager.wrapValue(marionetteLogObj.getLogs())});
marionetteLogObj.clearLogs();
@ -724,6 +725,7 @@ function executeWithCallback(msg, useFinish) {
}
let script = msg.json.script;
let filename = msg.json.filename;
asyncTestCommandId = msg.json.command_id;
sandboxName = msg.json.sandboxName;
@ -788,7 +790,7 @@ function executeWithCallback(msg, useFinish) {
stream.close();
scriptSrc = data + scriptSrc;
}
Cu.evalInSandbox(scriptSrc, sandbox, "1.8", "dummy file", 0);
Cu.evalInSandbox(scriptSrc, sandbox, "1.8", filename ? filename : "dummy file", 0);
} catch (e) {
let err = new JavaScriptError(
e,