Bug 1333014 - Introduce new exceptions to Python client; r?whimboo draft
authorAndreas Tolfsen <ato@mozilla.com>
Fri, 03 Feb 2017 19:40:56 +0000
changeset 503048 10c5ca8a49e796597bf2aed71b41b20288663678
parent 503047 8e3854a81b28608e27187896c0132d388ad94f48
child 503049 bb2e786b8ae434d23d07888c6ee56dca7dec9a89
push id50471
push userbmo:ato@mozilla.com
push dateWed, 22 Mar 2017 19:18:41 +0000
reviewerswhimboo
bugs1333014
milestone55.0a1
Bug 1333014 - Introduce new exceptions to Python client; r?whimboo This adds the new errors ElementNotInteractableException and ElementClickInterceptedException to the Marionette Python client. It marks the ElementNotVisibleException as a deprecated, but does not remove it for to backwards compatibility concerns with the Firefox upgrade tests. MozReview-Commit-ID: GPSwMo0fHnk
testing/marionette/client/marionette_driver/errors.py
testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
testing/marionette/harness/marionette_harness/tests/unit/test_click.py
testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
testing/marionette/harness/marionette_harness/tests/unit/test_typing.py
--- a/testing/marionette/client/marionette_driver/errors.py
+++ b/testing/marionette/client/marionette_driver/errors.py
@@ -50,16 +50,20 @@ class MarionetteException(Exception):
 
         return msg
 
 
 class ElementNotSelectableException(MarionetteException):
     status = "element not selectable"
 
 
+class ElementClickInterceptedException(MarionetteException):
+    status = "element click intercepted"
+
+
 class InsecureCertificateException(MarionetteException):
     status = "insecure certificate"
 
 
 class InvalidArgumentException(MarionetteException):
     status = "invalid argument"
 
 
@@ -87,29 +91,35 @@ class StaleElementException(MarionetteEx
     status = "stale element reference"
 
 
 class ScriptTimeoutException(MarionetteException):
     status = "script timeout"
 
 
 class ElementNotVisibleException(MarionetteException):
+    """Deprecated.  Will be removed with the release of Firefox 54."""
+
     status = "element not visible"
 
     def __init__(self,
                  message="Element is not currently visible and may not be manipulated",
                  stacktrace=None, cause=None):
         super(ElementNotVisibleException, self).__init__(
             message, cause=cause, stacktrace=stacktrace)
 
 
 class ElementNotAccessibleException(MarionetteException):
     status = "element not accessible"
 
 
+class ElementNotInteractableException(MarionetteException):
+    status = "element not interactable"
+
+
 class NoSuchFrameException(MarionetteException):
     status = "no such frame"
 
 
 class InvalidElementStateException(MarionetteException):
     status = "invalid element state"
 
 
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
@@ -1,16 +1,16 @@
 # 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/.
 
 from marionette_driver.by import By
 from marionette_driver.errors import (
     ElementNotAccessibleException,
-    ElementNotVisibleException
+    ElementNotInteractableException
 )
 
 from marionette_harness import MarionetteTestCase
 
 
 
 class TestAccessibility(MarionetteTestCase):
     def setUp(self):
@@ -109,49 +109,49 @@ class TestAccessibility(MarionetteTestCa
         self.run_element_test(self.valid_elementIDs, lambda button: button.tap())
 
     def test_single_tap_raises_element_not_accessible(self):
         self.setup_accessibility()
         self.run_element_test(self.invalid_elementIDs,
                               lambda button: self.assertRaises(ElementNotAccessibleException,
                                                                button.tap))
         self.run_element_test(self.falsy_elements,
-                              lambda button: self.assertRaises(ElementNotVisibleException,
+                              lambda button: self.assertRaises(ElementNotInteractableException,
                                                                button.tap))
 
     def test_single_tap_raises_no_exceptions(self):
         self.setup_accessibility(False, True)
         # No exception should be raised
         self.run_element_test(self.invalid_elementIDs, lambda button: button.tap())
         # Elements are invisible
         self.run_element_test(self.falsy_elements,
-                              lambda button: self.assertRaises(ElementNotVisibleException,
+                              lambda button: self.assertRaises(ElementNotInteractableException,
                                                                button.tap))
 
     def test_valid_click(self):
         self.setup_accessibility()
         # No exception should be raised
         self.run_element_test(self.valid_elementIDs, lambda button: button.click())
 
     def test_click_raises_element_not_accessible(self):
         self.setup_accessibility()
         self.run_element_test(self.invalid_elementIDs,
                               lambda button: self.assertRaises(ElementNotAccessibleException,
                                                                button.click))
         self.run_element_test(self.falsy_elements,
-                              lambda button: self.assertRaises(ElementNotVisibleException,
+                              lambda button: self.assertRaises(ElementNotInteractableException,
                                                                button.click))
 
     def test_click_raises_no_exceptions(self):
         self.setup_accessibility(False, True)
         # No exception should be raised
         self.run_element_test(self.invalid_elementIDs, lambda button: button.click())
         # Elements are invisible
         self.run_element_test(self.falsy_elements,
-                              lambda button: self.assertRaises(ElementNotVisibleException,
+                              lambda button: self.assertRaises(ElementNotInteractableException,
                                                                button.click))
 
     def test_element_visible_but_not_visible_to_accessbility(self):
         self.setup_accessibility()
         # Elements are displayed but hidden from accessibility API
         self.run_element_test(self.displayed_but_a11y_hidden_elementIDs,
                               lambda element: self.assertRaises(ElementNotAccessibleException,
                                                                 element.is_displayed))
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_click.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_click.py
@@ -1,16 +1,16 @@
 # 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 urllib
 
 from marionette_driver.by import By
-from marionette_driver.errors import NoSuchElementException, ElementNotVisibleException
+from marionette_driver import errors
 from marionette_driver.wait import Wait
 
 from marionette_harness import MarionetteTestCase
 
 
 def inline(doc):
     return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
 
@@ -62,25 +62,25 @@ class TestLegacyClick(MarionetteTestCase
         link = self.marionette.find_element(By.ID, "mozLink")
         link.click()
         self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
 
     def test_clicking_a_link_made_up_of_numbers_is_handled_correctly(self):
         test_html = self.marionette.absolute_url("clicks.html")
         self.marionette.navigate(test_html)
         self.marionette.find_element(By.LINK_TEXT, "333333").click()
-        Wait(self.marionette, timeout=30, ignored_exceptions=NoSuchElementException).until(
+        Wait(self.marionette, timeout=30, ignored_exceptions=errors.NoSuchElementException).until(
             lambda m: m.find_element(By.ID, 'username'))
         self.assertEqual(self.marionette.title, "XHTML Test Page")
 
     def test_clicking_an_element_that_is_not_displayed_raises(self):
         test_html = self.marionette.absolute_url('hidden.html')
         self.marionette.navigate(test_html)
 
-        with self.assertRaises(ElementNotVisibleException):
+        with self.assertRaises(errors.ElementNotInteractableException):
             self.marionette.find_element(By.ID, 'child').click()
 
     def test_clicking_on_a_multiline_link(self):
         test_html = self.marionette.absolute_url("clicks.html")
         self.marionette.navigate(test_html)
         self.marionette.find_element(By.ID, "overflowLink").click()
         self.wait_for_condition(lambda mn: self.marionette.title == "XHTML Test Page")
 
@@ -113,17 +113,17 @@ class TestClick(TestLegacyClick):
 
             <div id=obscured></div>
             <div id=overlay></div>"""))
 
         overlay = self.marionette.find_element(By.ID, "overlay")
         obscured = self.marionette.find_element(By.ID, "obscured")
 
         overlay.click()
-        with self.assertRaises(ElementNotVisibleException):
+        with self.assertRaises(errors.ElementClickInterceptedException):
             obscured.click()
 
     def test_centre_outside_viewport_vertically(self):
         self.marionette.navigate(inline("""
             <style>
             * { margin: 0; padding: 0; }
             div {
              display: block;
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py
@@ -1,14 +1,14 @@
 # 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/.
 
 from marionette_driver.by import By
-from marionette_driver.errors import NoAlertPresentException, ElementNotVisibleException
+from marionette_driver.errors import NoAlertPresentException, ElementNotInteractableException
 from marionette_driver.marionette import Alert
 from marionette_driver.wait import Wait
 
 from marionette_harness import MarionetteTestCase, skip_if_e10s
 
 
 class TestTabModals(MarionetteTestCase):
 
@@ -108,17 +108,17 @@ class TestTabModals(MarionetteTestCase):
         self.assertEqual(alert.text, 'Marionette confirm')
         alert.accept()
 
     def test_set_text_throws(self):
         self.assertRaises(NoAlertPresentException, Alert(self.marionette).send_keys, "Foo")
         self.marionette.find_element(By.ID, 'modal-alert').click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
-        self.assertRaises(ElementNotVisibleException, alert.send_keys, "Foo")
+        self.assertRaises(ElementNotInteractableException, alert.send_keys, "Foo")
         alert.accept()
 
     def test_set_text_accept(self):
         self.marionette.find_element(By.ID, 'modal-prompt').click()
         self.wait_for_alert()
         alert = self.marionette.switch_to_alert()
         alert.send_keys("Some text!");
         alert.accept()
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_typing.py
@@ -1,16 +1,16 @@
 # 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 urllib
 
 from marionette_driver.by import By
-from marionette_driver.errors import ElementNotVisibleException
+from marionette_driver.errors import ElementNotInteractableException
 from marionette_driver.keys import Keys
 
 from marionette_harness import MarionetteTestCase, skip, skip_if_mobile
 
 
 def inline(doc):
     return "data:text/html;charset=utf-8,{}".format(urllib.quote(doc))
 
@@ -306,21 +306,21 @@ class TestTypingContent(TypingTestCase):
 
     def testShouldSendKeysToElementsWithoutTheValueAttribute(self):
         test_html = self.marionette.absolute_url("javascriptPage.html")
         self.marionette.navigate(test_html)
 
         # If we don't get an error below we are good
         self.marionette.find_element(By.TAG_NAME, "body").send_keys("foo")
 
-    def testShouldThrowElementNotVisibleWhenInputHidden(self):
+    def test_not_interactable_if_hidden(self):
         test_html = self.marionette.absolute_url("javascriptPage.html")
         self.marionette.navigate(test_html)
         not_displayed = self.marionette.find_element(By.ID, "notDisplayed")
-        self.assertRaises(ElementNotVisibleException, not_displayed.send_keys, "foo")
+        self.assertRaises(ElementNotInteractableException, not_displayed.send_keys, "foo")
 
     def test_appends_to_input_text(self):
         self.marionette.navigate(inline("<input>"))
         el = self.marionette.find_element(By.TAG_NAME, "input")
         el.send_keys("foo")
         el.send_keys("bar")
         self.assertEqual("foobar", el.get_property("value"))