Bug 755036 - Re-use the execution sandbox in marionette's executeScript and executeAsyncScript in chrome scope when requested. r=jgriffin

This commit is contained in:
Chris Manchester 2015-01-07 14:52:07 -05:00
parent 1889255041
commit a70eb22433
3 changed files with 50 additions and 47 deletions

View File

@ -104,14 +104,8 @@ class TestExecuteAsyncChrome(TestExecuteAsyncContent):
def test_execute_async_unload(self):
pass
def test_same_context(self):
pass
def test_execute_permission(self):
self.assertEqual(5, self.marionette.execute_async_script("""
var c = Components.classes;
marionetteScriptFinished(5);
"""))
def test_sandbox_reuse(self):
pass

View File

@ -104,6 +104,3 @@ class TestExecuteChrome(TestExecuteContent):
actual = self.marionette.execute_script(
"return document.querySelectorAll('textbox')")
self.assertEqual(expected, actual)
def test_sandbox_reuse(self):
pass

View File

@ -163,6 +163,7 @@ function MarionetteServerConnection(aPrefix, aTransport, aServer)
this.currentFrameElement = null;
this.testName = null;
this.mozBrowserClose = null;
this.sandbox = null;
this.oopFrameId = null; // frame ID of current remote frame, used for mozbrowserclose events
this.sessionCapabilities = {
// Mandated capabilities
@ -786,6 +787,7 @@ MarionetteServerConnection.prototype = {
let _chromeSandbox = new Cu.Sandbox(aWindow,
{ sandboxPrototype: aWindow, wantXrays: false, sandboxName: ''});
_chromeSandbox.global = _chromeSandbox;
_chromeSandbox.__namedArgs = this.curBrowser.elementManager.applyNamedArgs(args);
_chromeSandbox.__marionetteParams = args;
_chromeSandbox.testUtils = utils;
@ -876,17 +878,18 @@ MarionetteServerConnection.prototype = {
let timeout = aRequest.parameters.scriptTimeout ? aRequest.parameters.scriptTimeout : this.scriptTimeout;
let command_id = this.command_id = this.getCommandId();
let script;
if (aRequest.parameters.newSandbox == undefined) {
let newSandbox = aRequest.parameters.newSandbox;
if (newSandbox == undefined) {
//if client does not send a value in newSandbox,
//then they expect the same behaviour as webdriver
aRequest.parameters.newSandbox = true;
newSandbox = true;
}
if (this.context == "content") {
this.sendAsync("executeScript",
{
script: aRequest.parameters.script,
args: aRequest.parameters.args,
newSandbox: aRequest.parameters.newSandbox,
newSandbox: newSandbox,
timeout: timeout,
specialPowers: aRequest.parameters.specialPowers,
filename: aRequest.parameters.filename,
@ -919,24 +922,27 @@ MarionetteServerConnection.prototype = {
}
}
let curWindow = this.getCurrentWindow();
let marionette = new Marionette(this, curWindow, "chrome",
this.marionetteLog,
timeout, this.heartbeatCallback, this.testName);
let _chromeSandbox = this.createExecuteSandbox(curWindow,
marionette,
aRequest.parameters.args,
aRequest.parameters.specialPowers,
command_id);
if (!_chromeSandbox)
return;
if (!this.sandbox || newSandbox) {
let curWindow = this.getCurrentWindow();
let marionette = new Marionette(this, curWindow, "chrome",
this.marionetteLog,
timeout, this.heartbeatCallback, this.testName);
this.sandbox = this.createExecuteSandbox(curWindow,
marionette,
aRequest.parameters.args,
aRequest.parameters.specialPowers,
command_id);
if (!this.sandbox)
return;
}
try {
_chromeSandbox.finish = function chromeSandbox_finish() {
this.sandbox.finish = function chromeSandbox_finish() {
if (that.inactivityTimer != null) {
that.inactivityTimer.cancel();
}
return marionette.generate_results();
return that.sandbox.generate_results();
};
if (directInject) {
@ -948,7 +954,7 @@ MarionetteServerConnection.prototype = {
"};" +
"func.apply(null, __marionetteParams);";
}
this.executeScriptInSandbox(_chromeSandbox, script, directInject,
this.executeScriptInSandbox(this.sandbox, script, directInject,
false, command_id, timeout);
}
catch (e) {
@ -1042,10 +1048,11 @@ MarionetteServerConnection.prototype = {
let timeout = aRequest.parameters.scriptTimeout ? aRequest.parameters.scriptTimeout : this.scriptTimeout;
let command_id = this.command_id = this.getCommandId();
let script;
if (aRequest.parameters.newSandbox == undefined) {
let newSandbox = aRequest.parameters.newSandbox;
if (newSandbox == undefined) {
//if client does not send a value in newSandbox,
//then they expect the same behaviour as webdriver
aRequest.parameters.newSandbox = true;
newSandbox = true;
}
if (this.context == "content") {
@ -1054,7 +1061,7 @@ MarionetteServerConnection.prototype = {
script: aRequest.parameters.script,
args: aRequest.parameters.args,
id: this.command_id,
newSandbox: aRequest.parameters.newSandbox,
newSandbox: newSandbox,
timeout: timeout,
inactivityTimeout: inactivityTimeout,
specialPowers: aRequest.parameters.specialPowers,
@ -1088,10 +1095,6 @@ MarionetteServerConnection.prototype = {
let curWindow = this.getCurrentWindow();
let original_onerror = curWindow.onerror;
that.timeout = timeout;
let marionette = new Marionette(this, curWindow, "chrome",
this.marionetteLog,
timeout, this.heartbeatCallback, this.testName);
marionette.command_id = this.command_id;
function chromeAsyncReturnFunc(value, status, stacktrace) {
if (that._emu_cbs && Object.keys(that._emu_cbs).length) {
@ -1102,7 +1105,8 @@ MarionetteServerConnection.prototype = {
if (value == undefined)
value = null;
if (that.command_id == marionette.command_id) {
if (command_id == that.command_id) {
if (that.timer != null) {
that.timer.cancel();
that.timer = null;
@ -1112,14 +1116,15 @@ MarionetteServerConnection.prototype = {
if (status == 0 || status == undefined) {
that.sendToClient({from: that.actorID, value: that.curBrowser.elementManager.wrapValue(value), status: status},
marionette.command_id);
that.command_id);
}
else {
let error_msg = {message: value, status: status, stacktrace: stacktrace};
that.sendToClient({from: that.actorID, error: error_msg},
marionette.command_id);
that.command_id);
}
}
if (that.inactivityTimer != null) {
that.inactivityTimer.cancel();
}
@ -1131,16 +1136,21 @@ MarionetteServerConnection.prototype = {
};
function chromeAsyncFinish() {
chromeAsyncReturnFunc(marionette.generate_results(), 0);
chromeAsyncReturnFunc(that.sandbox.generate_results(), 0);
}
let _chromeSandbox = this.createExecuteSandbox(curWindow,
marionette,
aRequest.parameters.args,
aRequest.parameters.specialPowers,
command_id);
if (!_chromeSandbox)
return;
if (!this.sandbox || newSandbox) {
let marionette = new Marionette(this, curWindow, "chrome",
this.marionetteLog,
timeout, this.heartbeatCallback, this.testName);
this.sandbox = this.createExecuteSandbox(curWindow,
marionette,
aRequest.parameters.args,
aRequest.parameters.specialPowers,
command_id);
if (!this.sandbox)
return;
}
try {
@ -1151,8 +1161,8 @@ MarionetteServerConnection.prototype = {
}, that.timeout, Ci.nsITimer.TYPE_ONE_SHOT);
}
_chromeSandbox.returnFunc = chromeAsyncReturnFunc;
_chromeSandbox.finish = chromeAsyncFinish;
this.sandbox.returnFunc = chromeAsyncReturnFunc;
this.sandbox.finish = chromeAsyncFinish;
if (directInject) {
script = aRequest.parameters.script;
@ -1164,7 +1174,7 @@ MarionetteServerConnection.prototype = {
+ '__marionetteFunc.apply(null, __marionetteParams);';
}
this.executeScriptInSandbox(_chromeSandbox, script, directInject,
this.executeScriptInSandbox(this.sandbox, script, directInject,
true, command_id, timeout);
} catch (e) {
let error = createStackMessage(e,
@ -1499,6 +1509,8 @@ MarionetteServerConnection.prototype = {
if (aRequest.parameters.name == win.name ||
aRequest.parameters.name == contentWindowId ||
aRequest.parameters.name == outerId) {
// As in content, switching to a new window invalidates a sandbox for reuse.
this.sandbox = null;
if (this.browsers[outerId] === undefined) {
//enable Marionette in that browser window
this.startBrowser(win, false);