Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

# 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 sys
import unittest
from marionette_driver.by import By
from marionette_driver.errors import (
ElementNotAccessibleException,
ElementNotInteractableException,
ElementClickInterceptedException,
)
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 accessible 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", "button4", "button5", "button6"]
displayed_but_have_no_accessible_elementIDs = [
# Button3 does not have an accessible object
"button3",
# Button 7 is hidden with aria-hidden set to true
"button7",
# Button 8 is inside an element with aria-hidden set to true
"button8",
"no_accessible_but_displayed",
]
disabled_elementIDs = ["button11", "no_accessible_but_disabled"]
# Elements that are enabled but otherwise disabled or not explorable
# via the accessibility API
aria_disabled_elementIDs = ["button12"]
# pointer-events: "none", which will return
# ElementClickInterceptedException if clicked
# when Marionette switches
# to using WebDriver conforming interaction
pointer_events_none_elementIDs = ["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({"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_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_have_no_accessible_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.aria_disabled_elementIDs,
lambda element: self.assertRaises(
ElementNotAccessibleException, element.is_enabled
),
)
self.run_element_test(
self.pointer_events_none_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.aria_disabled_elementIDs,
lambda element: self.assertRaises(
ElementNotAccessibleException, element.click
),
)
# To be removed with bug 1405967
if not self.marionette.session_capabilities["moz:webdriverClick"]:
self.run_element_test(
self.pointer_events_none_elementIDs,
lambda element: self.assertRaises(
ElementNotAccessibleException, element.click
),
)
self.setup_accessibility(False, False)
self.run_element_test(
self.aria_disabled_elementIDs, lambda element: element.is_enabled()
)
self.run_element_test(
self.pointer_events_none_elementIDs, lambda element: element.is_enabled()
)
self.run_element_test(
self.aria_disabled_elementIDs, lambda element: element.click()
)
# To be removed with bug 1405967
if not self.marionette.session_capabilities["moz:webdriverClick"]:
self.run_element_test(
self.pointer_events_none_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"))
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()
)