summaryrefslogtreecommitdiffstats
path: root/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py')
-rw-r--r--testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py210
1 files changed, 210 insertions, 0 deletions
diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py b/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
new file mode 100644
index 000000000..0d8d9dca5
--- /dev/null
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py
@@ -0,0 +1,210 @@
+# 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,
+ ElementNotInteractableException
+)
+
+from marionette_harness import MarionetteTestCase
+
+
+
+class TestAccessibility(MarionetteTestCase):
+ def setUp(self):
+ super(TestAccessibility, self).setUp()
+ with self.marionette.using_context("chrome"):
+ self.marionette.set_pref("dom.ipc.processCount", 1)
+
+ def tearDown(self):
+ with self.marionette.using_context("chrome"):
+ self.marionette.clear_pref("dom.ipc.processCount")
+
+ # Elements that are accessible with and without the accessibliity API
+ valid_elementIDs = [
+ # Button1 is an accessible button with a valid accessible name
+ # computed from subtree
+ "button1",
+ # Button2 is an accessible button with a valid accessible name
+ # computed from aria-label
+ "button2",
+ # Button13 is an accessible button that is implemented via role="button"
+ # and is explorable using tabindex="0"
+ "button13",
+ # button17 is an accessible button that overrides parent's
+ # pointer-events:none; property with its own pointer-events:all;
+ "button17"
+ ]
+
+ # Elements that are not accessible with the accessibility API
+ invalid_elementIDs = [
+ # Button3 does not have an accessible object
+ "button3",
+ # Button4 does not support any accessible actions
+ "button4",
+ # Button5 does not have a correct accessibility role and may not be
+ # manipulated via the accessibility API
+ "button5",
+ # Button6 is missing an accesible name
+ "button6",
+ # Button7 is not currently visible via the accessibility API and may
+ # not be manipulated by it
+ "button7",
+ # Button8 is not currently visible via the accessibility API and may
+ # not be manipulated by it (in hidden subtree)
+ "button8",
+ # Button14 is accessible button but is not explorable because of lack
+ # of tabindex that would make it focusable.
+ "button14"
+ ]
+
+ # Elements that are either accessible to accessibility API or not accessible
+ # at all
+ falsy_elements = [
+ # Element is only visible to the accessibility API and may be
+ # manipulated by it
+ "button9",
+ # Element is not currently visible
+ "button10"
+ ]
+
+ displayed_elementIDs = [
+ "button1", "button2", "button3", "button4", "button5", "button6",
+ "button9", "no_accessible_but_displayed"
+ ]
+
+ displayed_but_a11y_hidden_elementIDs = ["button7", "button8"]
+
+ disabled_elementIDs = ["button11", "no_accessible_but_disabled"]
+
+ # Elements that are enabled but otherwise disabled or not explorable via the accessibility API
+ disabled_accessibility_elementIDs = ["button12", "button15", "button16"]
+
+ # Elements that are reporting selected state
+ valid_option_elementIDs = ["option1", "option2"]
+
+ def run_element_test(self, ids, testFn):
+ for id in ids:
+ element = self.marionette.find_element(By.ID, id)
+ testFn(element)
+
+ def setup_accessibility(self, enable_a11y_checks=True, navigate=True):
+ self.marionette.delete_session()
+ self.marionette.start_session(
+ {"requiredCapabilities": {"moz:accessibilityChecks": enable_a11y_checks}})
+ self.assertEqual(
+ self.marionette.session_capabilities["moz:accessibilityChecks"],
+ enable_a11y_checks)
+
+ # Navigate to test_accessibility.html
+ if navigate:
+ test_accessibility = self.marionette.absolute_url("test_accessibility.html")
+ self.marionette.navigate(test_accessibility)
+
+ def test_valid_single_tap(self):
+ self.setup_accessibility()
+ # No exception should be raised
+ 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(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(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(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(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))
+
+ def test_element_is_visible_to_accessibility(self):
+ self.setup_accessibility()
+ # No exception should be raised
+ self.run_element_test(self.displayed_elementIDs, lambda element: element.is_displayed())
+
+ def test_element_is_not_enabled_to_accessbility(self):
+ self.setup_accessibility()
+ # Buttons are enabled but disabled/not-explorable via the accessibility API
+ self.run_element_test(self.disabled_accessibility_elementIDs,
+ lambda element: self.assertRaises(ElementNotAccessibleException,
+ element.is_enabled))
+
+ # Buttons are enabled but disabled/not-explorable via the accessibility API and thus are not
+ # clickable via the accessibility API
+ self.run_element_test(self.disabled_accessibility_elementIDs,
+ lambda element: self.assertRaises(ElementNotAccessibleException,
+ element.click))
+
+ self.setup_accessibility(False, False)
+ self.run_element_test(self.disabled_accessibility_elementIDs,
+ lambda element: element.is_enabled())
+ self.run_element_test(self.disabled_accessibility_elementIDs,
+ lambda element: element.click())
+
+ def test_element_is_enabled_to_accessibility(self):
+ self.setup_accessibility()
+ # No exception should be raised
+ self.run_element_test(self.disabled_elementIDs, lambda element: element.is_enabled())
+
+ def test_send_keys_raises_no_exception(self):
+ self.setup_accessibility()
+ # Sending keys to valid input should not raise any exceptions
+ self.run_element_test(['input1'], lambda element: element.send_keys("a"))
+
+ self.setup_accessibility(False, False)
+ # Sending keys to invalid element should not raise any exceptions when raising accessibility
+ # exceptions is disabled
+ self.run_element_test(['button5'], lambda element: element.send_keys("abc"))
+
+ def test_send_keys_raises_element_not_accessible(self):
+ self.setup_accessibility()
+ # Sending keys to invalid element should raise an exception
+ self.run_element_test(['button5'],
+ lambda element: self.assertRaises(ElementNotAccessibleException,
+ element.send_keys))
+
+ def test_is_selected_raises_no_exception(self):
+ self.setup_accessibility()
+ # No exception should be raised for valid options
+ self.run_element_test(self.valid_option_elementIDs, lambda element: element.is_selected())
+ # No exception should be raised for non-selectable elements
+ self.run_element_test(self.valid_elementIDs, lambda element: element.is_selected())