Bug 1261842 - Make Marionette listener ensure that the loaded document is the one that was actually requested. r=ato
authorMike Conley <mconley@mozilla.com>
Fri, 27 May 2016 16:26:16 -0400
changeset 346293 88b8a25293238ee0d32def24cdbd74599c883271
parent 346292 c4ede6a823d39f390ecd09776a51a4ea702bcc97
child 346294 645432ac4faaf2f6ee4d42176d88733d0f26a24a
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersato
bugs1261842
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
testing/marionette/listener.js
--- 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.
  */