--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -369,16 +369,29 @@ MarionetteServerConnection.prototype = {
let type = null;
if (appName != "B2G" && this.context == "content") {
type = 'navigator:browser';
}
return Services.wm.getEnumerator(type);
},
/**
+ */
+ addFrameCloseListener: function MDA_addFrameCloseListener(action) {
+ let curWindow = this.getCurrentWindow();
+ let self = this;
+ this.mozBrowserClose = function() {
+ curWindow.removeEventListener('mozbrowserclose', self.mozBrowserClose, true);
+ self.switchToGlobalMessageManager();
+ self.sendError("The frame closed during the " + action + ", recovering to allow further communications", 500, null, self.command_id);
+ };
+ curWindow.addEventListener('mozbrowserclose', this.mozBrowserClose, true);
+ },
+
+ /**
* Create a new BrowserObj for window and add to known browsers
*
* @param nsIDOMWindow win
* Window for which we will create a BrowserObj
*
* @return string
* Returns the unique server-assigned ID of the window
*/
@@ -1521,16 +1534,17 @@ MarionetteServerConnection.prototype = {
this.command_id = this.getCommandId();
let serId = aRequest.parameters.id;
let x = aRequest.parameters.x;
let y = aRequest.parameters.y;
if (this.context == "chrome") {
this.sendError("Command 'singleTap' is not available in chrome context", 500, null, this.command_id);
}
else {
+ this.addFrameCloseListener("tap");
this.sendAsync("singleTap",
{
id: serId,
corx: x,
cory: y
},
this.command_id);
}
@@ -1543,16 +1557,17 @@ MarionetteServerConnection.prototype = {
* 'value' represents a nested array: inner array represents each event; outer array represents collection of events
*/
actionChain: function MDA_actionChain(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Command 'actionChain' is not available in chrome context", 500, null, this.command_id);
}
else {
+ this.addFrameCloseListener("action chain");
this.sendAsync("actionChain",
{
chain: aRequest.parameters.chain,
nextId: aRequest.parameters.nextId
},
this.command_id);
}
},
@@ -1567,16 +1582,17 @@ MarionetteServerConnection.prototype = {
*/
multiAction: function MDA_multiAction(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Command 'multiAction' is not available in chrome context", 500, null, this.command_id);
}
else {
+ this.addFrameCloseListener("multi action chain");
this.sendAsync("multiAction",
{
value: aRequest.parameters.value,
maxlen: aRequest.parameters.max_length
},
this.command_id);
}
},
@@ -1729,24 +1745,17 @@ MarionetteServerConnection.prototype = {
this.sendError(e.message, e.code, e.stack, command_id);
}
}
else {
// We need to protect against the click causing an OOP frame to close.
// This fires the mozbrowserclose event when it closes so we need to
// listen for it and then just send an error back. The person making the
// call should be aware something isnt right and handle accordingly
- let curWindow = this.getCurrentWindow();
- let self = this;
- this.mozBrowserClose = function() {
- curWindow.removeEventListener('mozbrowserclose', self.mozBrowserClose, true);
- self.switchToGlobalMessageManager();
- self.sendError("The frame closed during the click, recovering to allow further communications", 500, null, command_id);
- };
- curWindow.addEventListener('mozbrowserclose', this.mozBrowserClose, true);
+ this.addFrameCloseListener("click");
this.sendAsync("clickElement",
{ id: aRequest.parameters.id },
command_id);
}
},
/**
* Get a given attribute of an element