Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Bug 839675 - Prevent out-of-sync problems. r=mdas, a=akeybl

  • Loading branch information...
commit 70dd74b7767ac34546d924671a271481f1fb485a 1 parent 6ab89f6
@jonallengriffin jonallengriffin authored
View
60 testing/marionette/marionette-actors.js
@@ -259,17 +259,23 @@ MarionetteDriverActor.prototype = {
* Used to distinguish the asynchronous responses.
*/
sendToClient: function MDA_sendToClient(msg, command_id) {
- logger.info("sendToClient: " + JSON.stringify(msg) + ", " + command_id + ", " + this.command_id);
+ logger.info("sendToClient: " + JSON.stringify(msg) + ", " + command_id +
+ ", " + this.command_id);
if (!command_id) {
logger.warn("got a response with no command_id");
+ return;
}
- else if (this.command_id &&
- this.command_id != command_id) {
+ else if (this.command_id && command_id != -1 &&
+ this.command_id != command_id) {
+ // a command_id of -1 is used for emulator callbacks
logger.warn("ignoring out-of-sync response");
return;
}
this.conn.send(msg);
- if (command_id != null) {
+ if (command_id != -1) {
+ // Don't unset this.command_id if this message is to process an
+ // emulator callback, since another response for this command_id is
+ // expected, after the containing call to execute_async_script finishes.
this.command_id = null;
}
},
@@ -470,6 +476,7 @@ MarionetteDriverActor.prototype = {
*/
newSession: function MDA_newSession() {
this.command_id = this.getCommandId();
+ this.newSessionCommandId = this.command_id;
this.scriptTimeout = 10000;
@@ -620,12 +627,12 @@ MarionetteDriverActor.prototype = {
* @return Sandbox
* Returns the sandbox
*/
- createExecuteSandbox: function MDA_createExecuteSandbox(aWindow, marionette, args, specialPowers) {
+ createExecuteSandbox: function MDA_createExecuteSandbox(aWindow, marionette, args, specialPowers, command_id) {
try {
args = this.curBrowser.elementManager.convertWrappedArguments(args, aWindow);
}
catch(e) {
- this.sendError(e.message, e.code, e.stack);
+ this.sendError(e.message, e.code, e.stack, command_id);
return;
}
@@ -740,7 +747,8 @@ MarionetteDriverActor.prototype = {
let _chromeSandbox = this.createExecuteSandbox(curWindow,
marionette,
aRequest.args,
- aRequest.specialPowers);
+ aRequest.specialPowers,
+ command_id);
if (!_chromeSandbox)
return;
@@ -837,6 +845,7 @@ MarionetteDriverActor.prototype = {
*/
executeWithCallback: function MDA_executeWithCallback(aRequest, directInject) {
let command_id = this.command_id = this.getCommandId();
+ this.logRequest("executeWithCallback", aRequest);
if (aRequest.newSandbox == undefined) {
//if client does not send a value in newSandbox,
//then they expect the same behaviour as webdriver
@@ -863,6 +872,9 @@ MarionetteDriverActor.prototype = {
marionette.command_id = this.command_id;
function chromeAsyncReturnFunc(value, status) {
+ logger.info("chromeAsyncReturn");
+ logger.info("that.command_id=" + that.command_id);
+ logger.info("marionette.command_id=" + marionette.command_id);
if (that._emu_cbs && Object.keys(that._emu_cbs).length) {
value = "Emulator callback still pending when finish() called";
status = 500;
@@ -900,7 +912,11 @@ MarionetteDriverActor.prototype = {
chromeAsyncReturnFunc(marionette.generate_results(), 0);
}
- let _chromeSandbox = this.createExecuteSandbox(curWindow, marionette, aRequest.args, aRequest.specialPowers);
+ let _chromeSandbox = this.createExecuteSandbox(curWindow,
+ marionette,
+ aRequest.args,
+ aRequest.specialPowers,
+ command_id);
if (!_chromeSandbox)
return;
@@ -1772,7 +1788,7 @@ MarionetteDriverActor.prototype = {
}
this._emu_cbs[this._emu_cb_id] = callback;
}
- this.sendToClient({emulator_cmd: cmd, id: this._emu_cb_id});
+ this.sendToClient({emulator_cmd: cmd, id: this._emu_cb_id}, -1);
this._emu_cb_id += 1;
},
@@ -1792,10 +1808,11 @@ MarionetteDriverActor.prototype = {
return;
}
try {
+ logger.info("calling callback");
cb(message.result);
}
catch(e) {
- this.sendError(e.message, e.code, e.stack);
+ this.sendError(e.message, e.code, e.stack, -1);
return;
}
},
@@ -1832,7 +1849,8 @@ MarionetteDriverActor.prototype = {
*/
screenShot: function MDA_saveScreenshot(aRequest) {
this.sendAsync("screenShot", {element: aRequest.element,
- highlights: aRequest.highlights});
+ highlights: aRequest.highlights,
+ command_id: this.getCommandId()});
},
/**
@@ -1849,10 +1867,6 @@ MarionetteDriverActor.prototype = {
*/
receiveMessage: function MDA_receiveMessage(message) {
switch (message.name) {
- case "DOMContentLoaded":
- this.sendOk();
- this.messageManager.removeMessageListener("DOMContentLoaded", this, true);
- break;
case "Marionette:done":
this.sendResponse(message.json.value, message.json.command_id);
break;
@@ -1876,7 +1890,7 @@ MarionetteDriverActor.prototype = {
}
break;
case "Marionette:runEmulatorCmd":
- this.sendToClient(message.json);
+ this.sendToClient(message.json, -1);
break;
case "Marionette:switchToFrame":
// Switch to a remote frame.
@@ -1956,21 +1970,13 @@ MarionetteDriverActor.prototype = {
if (nullPrevious && (this.curBrowser.curFrameId != null)) {
this.sendAsync("newSession", {B2G: (appName == "B2G")});
if (this.curBrowser.newSession) {
- this.sendResponse(reg.id);
+ this.sendResponse(reg.id, this.newSessionCommandId);
+ this.newSessionCommandId = null;
}
}
return reg;
}
- },
- /**
- * for non-e10s eventListening
- */
- handleEvent: function MDA_handleEvent(evt) {
- if (evt.type == "DOMContentLoaded") {
- this.sendOk();
- this.curBrowser.browser.removeEventListener("DOMContentLoaded", this, false);
- }
- },
+ }
};
MarionetteDriverActor.prototype.requestTypes = {
View
39 testing/marionette/marionette-listener.js
@@ -46,6 +46,9 @@ let importedScripts = null;
// createExecuteContentSandbox().
let sandbox;
+// the unload handler
+let onunload;
+
// Flag to indicate whether an async script is currently running or not.
let asyncTestRunning = false;
let asyncTestCommandId;
@@ -270,13 +273,6 @@ function resetValues() {
curWindow = content;
}
-/**
- * send error when we detect an unload event during async scripts
- */
-function errUnload() {
- sendError("unload was called", 17, null);
-}
-
/*
* Marionette Methods
*/
@@ -311,7 +307,7 @@ function createExecuteContentSandbox(aWindow, timeout, specialPowers) {
}
sandbox.asyncComplete = function sandbox_asyncComplete(value, status) {
- curWindow.removeEventListener("unload", errUnload, false);
+ curWindow.removeEventListener("unload", onunload, false);
/* clear all timeouts potentially generated by the script*/
for (let i = 0; i <= asyncTestTimeoutId; i++) {
@@ -361,7 +357,7 @@ function createExecuteContentSandbox(aWindow, timeout, specialPowers) {
* or directly (for 'mochitest' like JS Marionette tests)
*/
function executeScript(msg, directInject) {
- let asyncTestCommandId = msg.json.command_id;
+ asyncTestCommandId = msg.json.command_id;
let script = msg.json.value;
if (msg.json.newSandbox || !sandbox) {
@@ -369,7 +365,7 @@ function executeScript(msg, directInject) {
msg.json.timeout,
msg.json.specialPowers);
if (!sandbox) {
- sendError("Could not create sandbox!", asyncTestCommandId);
+ sendError("Could not create sandbox!", 500, null, asyncTestCommandId);
return;
}
}
@@ -464,16 +460,20 @@ function executeJSScript(msg) {
* method is called, or if it times out.
*/
function executeWithCallback(msg, useFinish) {
- curWindow.addEventListener("unload", errUnload, false);
let script = msg.json.value;
- let asyncTestCommandId = msg.json.command_id;
+ asyncTestCommandId = msg.json.command_id;
+
+ onunload = function() {
+ sendError("unload was called", 17, null, asyncTestCommandId);
+ };
+ curWindow.addEventListener("unload", onunload, false);
if (msg.json.newSandbox || !sandbox) {
sandbox = createExecuteContentSandbox(curWindow,
msg.json.timeout,
msg.json.specialPowers);
if (!sandbox) {
- sendError("Could not create sandbox!");
+ sendError("Could not create sandbox!", 17, null, asyncTestCommandId);
return;
}
}
@@ -485,12 +485,12 @@ function executeWithCallback(msg, useFinish) {
// http://code.google.com/p/selenium/source/browse/trunk/javascript/firefox-driver/js/evaluate.js.
// We'll stay compatible with the Selenium code.
asyncTestTimeoutId = curWindow.setTimeout(function() {
- sandbox.asyncComplete('timed out', 28);
+ sandbox.asyncComplete('timed out', 28, null, asyncTestCommandId);
}, msg.json.timeout);
originalOnError = curWindow.onerror;
curWindow.onerror = function errHandler(errMsg, url, line) {
- sandbox.asyncComplete(errMsg, 17);
+ sandbox.asyncComplete(errMsg, 17, null, asyncTestCommandId);
curWindow.onerror = originalOnError;
};
@@ -528,7 +528,8 @@ function executeWithCallback(msg, useFinish) {
Cu.evalInSandbox(scriptSrc, sandbox, "1.8");
} catch (e) {
// 17 = JavascriptException
- sandbox.asyncComplete(e.name + ': ' + e.message, 17);
+ sandbox.asyncComplete(e.name + ': ' + e.message, 17,
+ e.stack, asyncTestCommandId);
}
}
@@ -1121,7 +1122,7 @@ function emulatorCmdResult(msg) {
cb(message.result);
}
catch(e) {
- sendError(e.message, e.code, e.stack);
+ sendError(e.message, e.code, e.stack, -1);
return;
}
}
@@ -1156,7 +1157,7 @@ function screenShot(msg) {
node = elementManager.getKnownElement(msg.json.element, curWindow)
}
catch (e) {
- sendResponse(e.message, e.code, e.stack);
+ sendResponse(e.message, e.code, e.stack, msg.json.command_id);
return;
}
}
@@ -1225,7 +1226,7 @@ function screenShot(msg) {
// Return the Base64 String back to the client bindings and they can manage
// saving the file to disk if it is required
- sendResponse({value:canvas.toDataURL("image/png","")});
+ sendResponse({value:canvas.toDataURL("image/png","")}, msg.json.command_id);
}
//call register self when we get loaded
Please sign in to comment.
Something went wrong with that request. Please try again.