Bug 1329556 - Navigation has to switch to top frame before determining load events. draft
authorHenrik Skupin <mail@hskupin.info>
Tue, 10 Jan 2017 15:53:32 +0100
changeset 458566 c4ba19377a5c59c3a13a98562caaca6070b88017
parent 458532 7011ed1427de2b6f075c46cc6f4618d3e9fcd2a4
child 541670 f464b45cefd3a13d2c39409766d998789ed774f1
push id40979
push userbmo:hskupin@gmail.com
push dateTue, 10 Jan 2017 14:54:10 +0000
bugs1329556
milestone53.0a1
Bug 1329556 - Navigation has to switch to top frame before determining load events. The get() method checks if a page load event is expected for a requested URL. By that it also takes the current URL into account. To determine that it currently uses the docshell from the frame's document but not from the content itself. As such the href is different and would cause us to wait for a page load event even if the requested URL is identical to the current one. To solve this we have to switch to the top frame (content) as very first action in get(). MozReview-Commit-ID: HZLNKQ6uZpp
testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py
testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame.py
testing/marionette/listener.js
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py
@@ -103,24 +103,27 @@ class TestNavigate(WindowManagerMixin, M
             "return window.document.getElementById('someDiv') == undefined"))
         self.marionette.refresh()
         # TODO(ato): Bug 1291320
         time.sleep(0.2)
         self.assertEqual("Marionette Test", self.marionette.title)
         self.assertTrue(self.marionette.execute_script(
             "return window.document.getElementById('someDiv') == undefined"))
 
-    @skip("Disabled due to Bug 977899")
-    def test_navigate_frame(self):
-        self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
-        self.marionette.switch_to_frame(0)
-        self.marionette.navigate(self.marionette.absolute_url("empty.html"))
-        self.assertTrue('empty.html' in self.marionette.get_url())
-        self.marionette.switch_to_frame()
-        self.assertTrue('test_iframe.html' in self.marionette.get_url())
+    def test_navigate_in_child_frame_changes_to_top(self):
+        frame_html = self.marionette.absolute_url("frameset.html")
+
+        self.marionette.navigate(frame_html)
+        frame = self.marionette.find_element(By.NAME, "third")
+        self.marionette.switch_to_frame(frame)
+        self.assertRaises(errors.NoSuchElementException,
+                          self.marionette.find_element, By.NAME, "third")
+
+        self.marionette.navigate(frame_html)
+        self.marionette.find_element(By.NAME, "third")
 
     @skip_if_mobile("Bug 1323755 - Socket timeout")
     def test_invalid_protocol(self):
         with self.assertRaises(errors.MarionetteException):
             self.marionette.navigate("thisprotocoldoesnotexist://")
 
     def test_should_navigate_to_requested_about_page(self):
         self.marionette.navigate("about:neterror")
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame.py
@@ -124,26 +124,16 @@ class TestSwitchFrame(MarionetteTestCase
         self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
         count = self.marionette.execute_script("return window.frames.length;")
         self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, count)
 
     def test_switch_to_frame_with_negative_index(self):
         self.marionette.navigate(self.marionette.absolute_url("test_iframe.html"))
         self.assertRaises(NoSuchFrameException, self.marionette.switch_to_frame, -1)
 
-    def test_after_switching_to_child_frame_navigates_changes_top(self):
-        frame_html = self.marionette.absolute_url("frameset.html")
-        self.marionette.navigate(frame_html)
-        frame = self.marionette.find_element(By.NAME, "third")
-        self.marionette.switch_to_frame(frame)
-        self.assertEqual("Unique title", self.marionette.title)
-        test_html = self.marionette.absolute_url("test.html")
-        self.marionette.navigate(test_html)
-        self.assertEqual("Marionette Test", self.marionette.title)
-
     def test_switch_to_parent_frame(self):
         frame_html = self.marionette.absolute_url("frameset.html")
         self.marionette.navigate(frame_html)
         frame = self.marionette.find_element(By.NAME, "third")
         self.marionette.switch_to_frame(frame)
 
         # If we don't find the following element we aren't on the right page
         self.marionette.find_element(By.ID, "checky")
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -946,16 +946,20 @@ function pollForReadyState(msg, start = 
  * 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 {pageTimeout, url, command_id} = msg.json;
 
+  // We need to move to the top frame before navigating
+  sendSyncMessage("Marionette:switchedToFrame", {frameValue: null});
+  curContainer.frame = content;
+
   let docShell = curContainer.frame
       .document
       .defaultView
       .QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIWebNavigation)
       .QueryInterface(Ci.nsIDocShell);
   let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
       .getInterface(Ci.nsIWebProgress);
@@ -1065,22 +1069,16 @@ function get(msg) {
         removeEventListener("DOMContentLoaded", onDOMContentLoaded, false);
       }
       webProgress.removeProgressListener(loadListener);
       sendError(new TimeoutError("Error loading page, timed out (onDOMContentLoaded)"), command_id);
     };
     navTimer.initWithCallback(onTimeout, pageTimeout, Ci.nsITimer.TYPE_ONE_SHOT);
   }
 
-  // in Firefox we need to move to the top frame before navigating
-  if (!isB2G) {
-    sendSyncMessage("Marionette:switchedToFrame", {frameValue: null});
-    curContainer.frame = content;
-  }
-
   if (loadEventExpected) {
     addEventListener("DOMContentLoaded", onDOMContentLoaded, false);
   }
   curContainer.frame.location = requestedURL;
   if (!loadEventExpected) {
     sendOk(command_id);
   }
 }