summaryrefslogtreecommitdiffstats
path: root/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py')
-rw-r--r--testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py447
1 files changed, 447 insertions, 0 deletions
diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py
new file mode 100644
index 000000000..75ed37ecd
--- /dev/null
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py
@@ -0,0 +1,447 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import contextlib
+import time
+import urllib
+
+from marionette_driver import By, errors, expected, Wait
+from marionette_harness import (
+ MarionetteTestCase,
+ run_if_e10s,
+ run_if_manage_instance,
+ skip,
+ skip_if_mobile,
+ WindowManagerMixin,
+)
+
+
+def inline(doc):
+ return "data:text/html;charset=utf-8,%s" % urllib.quote(doc)
+
+
+class TestBackForwardNavigation(WindowManagerMixin, MarionetteTestCase):
+
+ def setUp(self):
+ super(TestBackForwardNavigation, self).setUp()
+
+ self.test_page = self.marionette.absolute_url('test.html')
+
+ def open_with_link():
+ link = self.marionette.find_element(By.ID, "new-blank-tab")
+ link.click()
+
+ # Always use a blank new tab for an empty history
+ self.marionette.navigate(self.marionette.absolute_url("windowHandles.html"))
+ self.new_tab = self.open_tab(open_with_link)
+ self.marionette.switch_to_window(self.new_tab)
+ Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
+ lambda _: self.history_length == 1,
+ message="The newly opened tab doesn't have a browser history length of 1")
+
+ def tearDown(self):
+ self.marionette.switch_to_parent_frame()
+ self.close_all_tabs()
+
+ super(TestBackForwardNavigation, self).tearDown()
+
+ @property
+ def history_length(self):
+ return self.marionette.execute_script("return window.history.length;")
+
+ def run_test(self, test_pages):
+ # Helper method to run simple back and forward testcases.
+ for index, page in enumerate(test_pages):
+ if "error" in page:
+ with self.assertRaises(page["error"]):
+ self.marionette.navigate(page["url"])
+ else:
+ self.marionette.navigate(page["url"])
+ self.assertEqual(page["url"], self.marionette.get_url())
+ self.assertEqual(self.history_length, index + 1)
+
+ for page in test_pages[-2::-1]:
+ if "error" in page:
+ with self.assertRaises(page["error"]):
+ self.marionette.go_back()
+ else:
+ self.marionette.go_back()
+ self.assertEqual(page["url"], self.marionette.get_url())
+
+ for page in test_pages[1::]:
+ if "error" in page:
+ with self.assertRaises(page["error"]):
+ self.marionette.go_forward()
+ else:
+ self.marionette.go_forward()
+ self.assertEqual(page["url"], self.marionette.get_url())
+
+ def test_no_history_items(self):
+ # Both methods should not raise a failure if no navigation is possible
+ self.marionette.go_back()
+ self.marionette.go_forward()
+
+ def test_data_urls(self):
+ test_pages = [
+ {"url": inline("<p>foobar</p>")},
+ {"url": self.test_page},
+ {"url": inline("<p>foobar</p>")},
+ ]
+ self.run_test(test_pages)
+
+ def test_same_document_hash_change(self):
+ test_pages = [
+ {"url": "{}#23".format(self.test_page)},
+ {"url": self.test_page},
+ {"url": "{}#42".format(self.test_page)},
+ ]
+ self.run_test(test_pages)
+
+ @skip("Causes crashes for JS GC (bug 1344863) and a11y (bug 1344868)")
+ def test_frameset(self):
+ test_pages = [
+ {"url": self.marionette.absolute_url("frameset.html")},
+ {"url": self.test_page},
+ {"url": self.marionette.absolute_url("frameset.html")},
+ ]
+ self.run_test(test_pages)
+
+ def test_frameset_after_navigating_in_frame(self):
+ test_element_locator = (By.ID, "email")
+
+ self.marionette.navigate(self.test_page)
+ self.assertEqual(self.marionette.get_url(), self.test_page)
+ self.assertEqual(self.history_length, 1)
+ page = self.marionette.absolute_url("frameset.html")
+ self.marionette.navigate(page)
+ self.assertEqual(self.marionette.get_url(), page)
+ self.assertEqual(self.history_length, 2)
+ frame = self.marionette.find_element(By.ID, "fifth")
+ self.marionette.switch_to_frame(frame)
+ link = self.marionette.find_element(By.ID, "linkId")
+ link.click()
+
+ # We cannot use get_url() to wait until the target page has been loaded,
+ # because it will return the URL of the top browsing context and doesn't
+ # wait for the page load to be complete.
+ Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
+ expected.element_present(*test_element_locator),
+ message="Target element 'email' has not been found")
+ self.assertEqual(self.history_length, 3)
+
+ # Go back to the frame the click navigated away from
+ self.marionette.go_back()
+ self.assertEqual(self.marionette.get_url(), page)
+ with self.assertRaises(errors.NoSuchElementException):
+ self.marionette.find_element(*test_element_locator)
+
+ # Go back to the non-frameset page
+ self.marionette.switch_to_parent_frame()
+ self.marionette.go_back()
+ self.assertEqual(self.marionette.get_url(), self.test_page)
+
+ # Go forward to the frameset page
+ self.marionette.go_forward()
+ self.assertEqual(self.marionette.get_url(), page)
+
+ # Go forward to the frame the click navigated to
+ # TODO: See above for automatic browser context switches. Hard to do here
+ frame = self.marionette.find_element(By.ID, "fifth")
+ self.marionette.switch_to_frame(frame)
+ self.marionette.go_forward()
+ self.marionette.find_element(*test_element_locator)
+ self.assertEqual(self.marionette.get_url(), page)
+
+ def test_image_document_to_html(self):
+ test_pages = [
+ {"url": self.marionette.absolute_url('black.png')},
+ {"url": self.test_page},
+ {"url": self.marionette.absolute_url('white.png')},
+ ]
+ self.run_test(test_pages)
+
+ def test_image_document_to_image_document(self):
+ test_pages = [
+ {"url": self.marionette.absolute_url('black.png')},
+ {"url": self.marionette.absolute_url('white.png')},
+ ]
+ self.run_test(test_pages)
+
+ @run_if_e10s("Requires e10s mode enabled")
+ def test_remoteness_change(self):
+ # TODO: Verify that a remoteness change happened
+ # like: self.assertNotEqual(self.marionette.current_window_handle, self.new_tab)
+
+ # about:robots is always a non-remote page for now
+ test_pages = [
+ {"url": "about:robots"},
+ {"url": self.test_page},
+ {"url": "about:robots"},
+ ]
+ self.run_test(test_pages)
+
+ def test_navigate_to_requested_about_page_after_error_page(self):
+ test_pages = [
+ {"url": "about:neterror"},
+ {"url": self.marionette.absolute_url("test.html")},
+ {"url": "about:blocked"},
+ ]
+ self.run_test(test_pages)
+
+ def test_timeout_error(self):
+ # Bug 1354908 - Disabled on Windows XP due to intermittent failures
+ caps = self.marionette.session_capabilities
+ if caps["platformName"] == "windows_nt" and float(caps["platformVersion"]) < 6:
+ return
+
+ urls = [
+ self.marionette.absolute_url('slow'),
+ self.test_page,
+ self.marionette.absolute_url('slow'),
+ ]
+
+ # First, load all pages completely to get them added to the cache
+ for index, url in enumerate(urls):
+ self.marionette.navigate(url)
+ self.assertEqual(url, self.marionette.get_url())
+ self.assertEqual(self.history_length, index + 1)
+
+ self.marionette.go_back()
+ self.assertEqual(urls[1], self.marionette.get_url())
+
+ # Force triggering a timeout error
+ self.marionette.timeout.page_load = 0.1
+ with self.assertRaises(errors.TimeoutException):
+ self.marionette.go_back()
+ self.assertEqual(urls[0], self.marionette.get_url())
+ self.marionette.timeout.page_load = 300000
+
+ self.marionette.go_forward()
+ self.assertEqual(urls[1], self.marionette.get_url())
+
+ # Force triggering a timeout error
+ self.marionette.timeout.page_load = 0.1
+ with self.assertRaises(errors.TimeoutException):
+ self.marionette.go_forward()
+ self.assertEqual(urls[2], self.marionette.get_url())
+ self.marionette.timeout.page_load = 300000
+
+ def test_certificate_error(self):
+ test_pages = [
+ {"url": self.fixtures.where_is("/test.html", on="https"),
+ "error": errors.InsecureCertificateException},
+ {"url": self.test_page},
+ {"url": self.fixtures.where_is("/test.html", on="https"),
+ "error": errors.InsecureCertificateException},
+ ]
+ self.run_test(test_pages)
+
+
+class TestNavigate(WindowManagerMixin, MarionetteTestCase):
+
+ def setUp(self):
+ super(TestNavigate, self).setUp()
+
+ self.marionette.navigate("about:")
+ self.test_doc = self.marionette.absolute_url("test.html")
+ self.iframe_doc = self.marionette.absolute_url("test_iframe.html")
+
+ def tearDown(self):
+ self.marionette.timeout.reset()
+ self.close_all_tabs()
+
+ super(TestNavigate, self).tearDown()
+
+ @property
+ def location_href(self):
+ # Windows 8 has recently seen a proliferation of intermittent
+ # test failures to do with failing to compare "about:blank" ==
+ # u"about:blank". For the sake of consistenty, we encode the
+ # returned URL as Unicode here to ensure that the values are
+ # absolutely of the same type.
+ #
+ # (https://bugzilla.mozilla.org/show_bug.cgi?id=1322862)
+ return self.marionette.execute_script("return window.location.href").encode("utf-8")
+
+ def test_set_location_through_execute_script(self):
+ self.marionette.execute_script(
+ "window.location.href = '%s'" % self.test_doc)
+ Wait(self.marionette).until(
+ lambda _: self.test_doc == self.location_href)
+ self.assertEqual("Marionette Test", self.marionette.title)
+
+ def test_navigate_chrome_error(self):
+ with self.marionette.using_context("chrome"):
+ self.assertRaises(errors.UnsupportedOperationException,
+ self.marionette.navigate, "about:blank")
+ self.assertRaises(errors.UnsupportedOperationException, self.marionette.go_back)
+ self.assertRaises(errors.UnsupportedOperationException, self.marionette.go_forward)
+ self.assertRaises(errors.UnsupportedOperationException, self.marionette.refresh)
+
+ def test_get_current_url_returns_top_level_browsing_context_url(self):
+ self.marionette.navigate(self.iframe_doc)
+ self.assertEqual(self.iframe_doc, self.location_href)
+ frame = self.marionette.find_element(By.CSS_SELECTOR, "#test_iframe")
+ self.marionette.switch_to_frame(frame)
+ self.assertEqual(self.iframe_doc, self.marionette.get_url())
+
+ def test_get_current_url(self):
+ self.marionette.navigate(self.test_doc)
+ self.assertEqual(self.test_doc, self.marionette.get_url())
+ self.marionette.navigate("about:blank")
+ self.assertEqual("about:blank", self.marionette.get_url())
+
+ def test_refresh(self):
+ self.marionette.navigate(self.test_doc)
+ self.assertEqual("Marionette Test", self.marionette.title)
+ self.assertTrue(self.marionette.execute_script(
+ """var elem = window.document.createElement('div'); elem.id = 'someDiv';
+ window.document.body.appendChild(elem); return true;"""))
+ self.assertFalse(self.marionette.execute_script(
+ "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"))
+
+ 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_find_element_state_complete(self):
+ self.marionette.navigate(self.test_doc)
+ state = self.marionette.execute_script(
+ "return window.document.readyState")
+ self.assertEqual("complete", state)
+ self.assertTrue(self.marionette.find_element(By.ID, "mozLink"))
+
+ def test_error_when_exceeding_page_load_timeout(self):
+ self.marionette.timeout.page_load = 0.1
+ with self.assertRaises(errors.TimeoutException):
+ self.marionette.navigate(self.marionette.absolute_url("slow"))
+
+ def test_navigate_to_same_image_document_twice(self):
+ self.marionette.navigate(self.fixtures.where_is("black.png"))
+ self.assertIn("black.png", self.marionette.title)
+ self.marionette.navigate(self.fixtures.where_is("black.png"))
+ self.assertIn("black.png", self.marionette.title)
+
+ def test_navigate_hash_change(self):
+ doc = inline("<p id=foo>")
+ self.marionette.navigate(doc)
+ self.marionette.execute_script("window.visited = true", sandbox=None)
+ self.marionette.navigate("{}#foo".format(doc))
+ self.assertTrue(self.marionette.execute_script(
+ "return window.visited", sandbox=None))
+
+ @skip_if_mobile("Bug 1334095 - Timeout: No new tab has been opened")
+ def test_about_blank_for_new_docshell(self):
+ """ Bug 1312674 - Hang when loading about:blank for a new docshell."""
+ def open_with_link():
+ link = self.marionette.find_element(By.ID, "new-blank-tab")
+ link.click()
+
+ # Open a new tab to get a new docshell created
+ self.marionette.navigate(self.marionette.absolute_url("windowHandles.html"))
+ new_tab = self.open_tab(trigger=open_with_link)
+ self.marionette.switch_to_window(new_tab)
+ self.assertEqual(self.marionette.get_url(), "about:blank")
+
+ self.marionette.navigate('about:blank')
+ self.marionette.close()
+ self.marionette.switch_to_window(self.start_window)
+
+ @skip("Bug 1332064 - NoSuchElementException: Unable to locate element: :focus")
+ @run_if_manage_instance("Only runnable if Marionette manages the instance")
+ @skip_if_mobile("Bug 1322993 - Missing temporary folder")
+ def test_focus_after_navigation(self):
+ self.marionette.quit()
+ self.marionette.start_session()
+
+ self.marionette.navigate(inline("<input autofocus>"))
+ active_el = self.marionette.execute_script("return document.activeElement")
+ focus_el = self.marionette.find_element(By.CSS_SELECTOR, ":focus")
+ self.assertEqual(active_el, focus_el)
+
+
+class TestTLSNavigation(MarionetteTestCase):
+ insecure_tls = {"acceptInsecureCerts": True}
+ secure_tls = {"acceptInsecureCerts": False}
+
+ def setUp(self):
+ MarionetteTestCase.setUp(self)
+ self.marionette.delete_session()
+ self.capabilities = self.marionette.start_session(
+ {"requiredCapabilities": self.insecure_tls})
+
+ def tearDown(self):
+ try:
+ self.marionette.delete_session()
+ except:
+ pass
+ MarionetteTestCase.tearDown(self)
+
+ @contextlib.contextmanager
+ def safe_session(self):
+ try:
+ self.capabilities = self.marionette.start_session(
+ {"requiredCapabilities": self.secure_tls})
+ self.assertFalse(self.capabilities["acceptInsecureCerts"])
+ yield self.marionette
+ finally:
+ self.marionette.delete_session()
+
+ @contextlib.contextmanager
+ def unsafe_session(self):
+ try:
+ self.capabilities = self.marionette.start_session(
+ {"requiredCapabilities": self.insecure_tls})
+ self.assertTrue(self.capabilities["acceptInsecureCerts"])
+ yield self.marionette
+ finally:
+ self.marionette.delete_session()
+
+ def test_navigate_by_command(self):
+ self.marionette.navigate(
+ self.fixtures.where_is("/test.html", on="https"))
+ self.assertIn("https", self.marionette.get_url())
+
+ def test_navigate_by_click(self):
+ link_url = self.fixtures.where_is("/test.html", on="https")
+ self.marionette.navigate(
+ inline("<a href=%s>https is the future</a>" % link_url))
+ self.marionette.find_element(By.TAG_NAME, "a").click()
+ self.assertIn("https", self.marionette.get_url())
+
+ def test_deactivation(self):
+ invalid_cert_url = self.fixtures.where_is("/test.html", on="https")
+
+ print "with safe session"
+ with self.safe_session() as session:
+ with self.assertRaises(errors.InsecureCertificateException):
+ session.navigate(invalid_cert_url)
+
+ print "with unsafe session"
+ with self.unsafe_session() as session:
+ session.navigate(invalid_cert_url)
+
+ print "with safe session again"
+ with self.safe_session() as session:
+ with self.assertRaises(errors.InsecureCertificateException):
+ session.navigate(invalid_cert_url)