Bug 1261842 - Make Marionette listener ensure that the loaded document is the one that was actually requested. r?ato
Before, it was assumed that the next load was the one that the Marionette client had
asked for, when this might not be the case. For example, when a new window opens,
it's possible for the initial about:blank load to be fired in content after the
parent has asked for a page to be loaded.
MozReview-Commit-ID: GPoJgbCvSju
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -25,16 +25,18 @@ Cu.import("chrome://marionette/content/i
Cu.import("chrome://marionette/content/logging.js");
Cu.import("chrome://marionette/content/proxy.js");
Cu.import("chrome://marionette/content/simpletest.js");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.importGlobalProperties(["URL"]);
+
var contentLog = new logging.ContentLogger();
var isB2G = false;
var marionetteTestName;
var winUtil = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
var listenerId = null; // unique ID of this listener
@@ -922,44 +924,50 @@ function pollForReadyState(msg, start, c
/**
* Navigate to the given URL. The operation will be performed on the
* current browsing context, which means it handles the case where we
* navigate within an iframe. All other navigation is handled by the
* driver (in chrome space).
*/
function get(msg) {
let start = new Date().getTime();
+ let requestedURL = new URL(msg.json.url).toString();
// Prevent DOMContentLoaded events from frames from invoking this
// code, unless the event is coming from the frame associated with
// the current window (i.e. someone has used switch_to_frame).
onDOMContentLoaded = function onDOMContentLoaded(event) {
- if (!event.originalTarget.defaultView.frameElement ||
- event.originalTarget.defaultView.frameElement == curContainer.frame.frameElement) {
+ let correctFrame =
+ !event.originalTarget.defaultView.frameElement ||
+ event.originalTarget.defaultView.frameElement == curContainer.frame.frameElement;
+
+ let correctURL = curContainer.frame.location == requestedURL;
+
+ if (correctFrame && correctURL) {
pollForReadyState(msg, start, () => {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
});
}
};
function timerFunc() {
removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
sendError(new TimeoutError("Error loading page, timed out (onDOMContentLoaded)"), msg.json.command_id);
}
if (msg.json.pageTimeout != null) {
navTimer.initWithCallback(timerFunc, msg.json.pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT);
}
addEventListener("DOMContentLoaded", onDOMContentLoaded, false);
if (isB2G) {
- curContainer.frame.location = msg.json.url;
+ curContainer.frame.location = requestedURL;
} else {
// We need to move to the top frame before navigating
sendSyncMessage("Marionette:switchedToFrame", { frameValue: null });
curContainer.frame = content;
- curContainer.frame.location = msg.json.url;
+ curContainer.frame.location = requestedURL;
}
}
/**
* Cancel the polling and remove the event listener associated with a current
* navigation request in case we're interupted by an onbeforeunload handler
* and navigation doesn't complete.
*/