Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #20508 from yzen/bug-1018214
Browse files Browse the repository at this point in the history
Bug 1018214, Bug 1021710 - utility tray gaia-ui tests with some tweaks to hopefully avoid intermittents.
  • Loading branch information
bebef1987 committed Jun 25, 2014
2 parents 0517465 + 60b0fb8 commit 002c73b
Show file tree
Hide file tree
Showing 17 changed files with 205 additions and 39 deletions.
80 changes: 54 additions & 26 deletions tests/atoms/accessibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,28 @@
'use strict';

var Accessibility = {
_getAccessible: function Accessibility__getAccessible(element, callback) {
let gAccRetrieval = SpecialPowers.Cc[
"@mozilla.org/accessibleRetrieval;1"].getService(
SpecialPowers.Ci.nsIAccessibleRetrieval);
let attempts = 0;
let intervalId = setInterval(function() {
let acc = gAccRetrieval.getAccessibleFor(element);
if (acc || ++attempts > 10) {
clearInterval(intervalId);

_accRetrieval: SpecialPowers.Cc[
"@mozilla.org/accessibleRetrieval;1"].getService(
SpecialPowers.Ci.nsIAccessibleRetrieval),

_getAccessible:
function Accessibility__getAccessible(element, callback, once) {
let acc = this._accRetrieval.getAccessibleFor(element);
if (acc || once) {
callback(acc);
} else {
setTimeout(this._getAccessible.bind(this), 10, element, callback);
}
}, 10);
},
},

_matchState: function Accessibility__matchState(acc, stateName) {
let stateToMatch = SpecialPowers.wrap(
SpecialPowers.Components).interfaces.nsIAccessibleStates[stateName];
let state = {};
let extState = {};
acc.getState(state, extState);
marionetteScriptFinished(!!(state.value & stateToMatch));
return !!(state.value & stateToMatch);
},

click: function Accessibility_click(element) {
Expand All @@ -35,29 +36,59 @@ var Accessibility = {
});
},

wheel: function Accessibility_wheel(element, direction) {
let horizontal = direction === "left" || direction === "right";
let page = (direction === "left" || direction === "up") ? 1 : -1;
let event = new window.wrappedJSObject.WheelEvent('wheel', {
bubbles: true,
cancelable: true,
deltaX: horizontal ? page : 0,
deltaY: horizontal ? 0 : page,
deltaMode: window.wrappedJSObject.WheelEvent.DOM_DELTA_PAGE,
});
element.wrappedJSObject.dispatchEvent(event);
},

isDisabled: function Accessibility_isDisabled(element) {
this._getAccessible(element.wrappedJSObject, (acc) => {
this._matchState(acc, 'STATE_UNAVAILABLE');
marionetteScriptFinished(this._matchState(acc, 'STATE_UNAVAILABLE'));
});
},

isHidden: function Accessibility_isHidden(element) {
let elem = element.wrappedJSObject;
_isAriaHidden: function Accessibility__isAriaHidden(element) {
do {
if (JSON.parse(elem.getAttribute('aria-hidden'))) {
marionetteScriptFinished(true);
return;
if (JSON.parse(element.getAttribute('aria-hidden'))) {
return true;
}
element = element.parentNode;
} while (element && element.getAttribute);
},

elem = elem.parentNode;
} while (elem && elem.getAttribute);
isHidden: function Accessibility_isHidden(element) {
let elem = element.wrappedJSObject;
if (this._isAriaHidden(elem)) {
marionetteScriptFinished(true);
return;
}

this._getAccessible(element.wrappedJSObject, (acc) => {
this._getAccessible(elem, (acc) => {
if (!acc) {
marionetteScriptFinished(true);
return;
}
this._matchState(acc, 'STATE_INVISIBLE');
marionetteScriptFinished(this._matchState(acc, 'STATE_INVISIBLE'));
}, true);
},

isVisible: function Accessibility_isVisible(element) {
let elem = element.wrappedJSObject;
if (this._isAriaHidden(elem)) {
marionetteScriptFinished(false);
return;
}

this._getAccessible(elem, (acc) => {
marionetteScriptFinished(!this._matchState(acc, 'STATE_INVISIBLE'));
});
},

Expand All @@ -69,10 +100,7 @@ var Accessibility = {

getRole: function Accessibility_getRole(element) {
this._getAccessible(element.wrappedJSObject, (acc) => {
let gAccRetrieval = SpecialPowers.Cc[
"@mozilla.org/accessibleRetrieval;1"].getService(
SpecialPowers.Ci.nsIAccessibleRetrieval);
marionetteScriptFinished(gAccRetrieval.getStringRole(acc.role));
marionetteScriptFinished(this._accRetrieval.getStringRole(acc.role));
});
},
};
1 change: 1 addition & 0 deletions tests/python/gaia-ui-tests/gaiatest/apps/system/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class System(Base):
_status_bar_notification_locator = (By.ID, 'statusbar-notification')
_geoloc_statusbar_locator = (By.ID, 'statusbar-geolocation')
_airplane_mode_statusbar_locator = (By.ID, 'statusbar-flight-mode')
_utility_tray_locator = (By.ID, 'utility-tray')

_notification_toaster_locator = (By.ID, 'notification-toaster')
_update_manager_toaster_locator = (By.ID, 'update-manager-toaster')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +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.by import By
from gaiatest.apps.base import Base


class StatusBar(Base):
_status_bar_time_locator = (By.ID, 'statusbar-time')

def a11y_wheel_status_bar_time(self):
self.accessibility.wheel(self.marionette.find_element(
*self._status_bar_time_locator), 'down')
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
from marionette.by import By
from gaiatest.apps.base import Base
from gaiatest.apps.base import PageRegion
from gaiatest.apps.settings.app import Settings
from gaiatest.apps.system.app import System


class UtilityTray(Base):
_notification_container_locator = (By.ID, 'notifications-container')
_desktop_notifications_locator = (By.CSS_SELECTOR, '#desktop-notifications-container .notification')
_notification_clear_locator = (By.ID, 'notification-clear')
_quicksettings_app_locator = (By.ID, 'quick-settings-full-app')
_grippy_locator = (By.ID, 'utility-tray-grippy')
_quick_settings_full_app_locator = (By.ID, 'quick-settings-full-app')

def wait_for_notification_container_displayed(self):
# Marionette cannot read the displayed state of the notification container so we wait for its location
Expand All @@ -25,9 +29,23 @@ def notifications(self):
def clear_all_notifications(self):
self.marionette.find_element(*self._notification_clear_locator).tap()

def a11y_clear_all_notifications(self):
self.accessibility.click(self.marionette.find_element(*self._notification_clear_locator))

def tap_settings_button(self):
self.marionette.find_element(*self._quicksettings_app_locator).tap()

def a11y_wheel_utility_tray_grippy(self):
self.accessibility.wheel(self.marionette.find_element(
*self._grippy_locator), 'up')
self.wait_for_element_not_displayed(*System(self.marionette)._utility_tray_locator)

def a11y_click_quick_settings_full_app(self):
self.accessibility.click(self.marionette.find_element(
*self._quick_settings_full_app_locator))
return Settings(self.marionette)


class Notification(PageRegion):
_body_locator = (By.CSS_SELECTOR, 'div.detail')
_title_locator = (By.CSS_SELECTOR, 'div.title')
Expand Down
9 changes: 9 additions & 0 deletions tests/python/gaia-ui-tests/gaiatest/gaia_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ def is_hidden(self, element):
'return Accessibility.isHidden.apply(Accessibility, arguments)',
[element], special_powers=True)

def is_visible(self, element):
return self.marionette.execute_async_script(
'return Accessibility.isVisible.apply(Accessibility, arguments)',
[element], special_powers=True)

def is_disabled(self, element):
return self.marionette.execute_async_script(
'return Accessibility.isDisabled.apply(Accessibility, arguments)',
Expand All @@ -399,6 +404,10 @@ def click(self, element):
'Accessibility.click.apply(Accessibility, arguments)',
[element], special_powers=True)

def wheel(self, element, direction):
self.marionette.execute_script('Accessibility.wheel.apply(Accessibility, arguments)', [
element, direction])

def get_name(self, element):
return self.marionette.execute_async_script(
'return Accessibility.getName.apply(Accessibility, arguments)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ def test_a11y_unlock_to_camera(self):
lockScreen_window = self.marionette.find_element(*lock_screen._lockscreen_window_locator)
camera_locator = (By.CSS_SELECTOR, '[data-manifest-name="Camera"]')

self.assertFalse(self.accessibility.is_hidden(lockScreen_window))
self.assertTrue(self.accessibility.is_visible(lockScreen_window))
self.assertFalse(self.is_element_present(*camera_locator))

camera = lock_screen.a11y_click_camera_button()
lock_screen.wait_for_lockscreen_not_visible()
self.assertEquals(self.apps.displayed_app.name, camera.name)

self.assertTrue(self.accessibility.is_hidden(lockScreen_window))
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*camera_locator)))

self.apps.switch_to_displayed_app()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ def test_a11y_unlock_to_homescreen(self):
lockScreen_window = self.marionette.find_element(*lock_screen._lockscreen_window_locator)
homescreen_container = self.marionette.find_element(By.ID, 'homescreen')

self.wait_for_condition(lambda m: not self.accessibility.is_hidden(lockScreen_window))
self.wait_for_condition(lambda m: self.accessibility.is_visible(lockScreen_window))
self.wait_for_condition(lambda m: self.accessibility.is_hidden(homescreen_container))

homescreen = lock_screen.a11y_click_unlock_button()
lock_screen.wait_for_lockscreen_not_visible()
self.assertEquals(self.apps.displayed_app.name, homescreen.name)

self.assertTrue(self.accessibility.is_hidden(lockScreen_window))
self.assertFalse(self.accessibility.is_hidden(homescreen_container))
self.assertTrue(self.accessibility.is_visible(homescreen_container))
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_phone_call_log(self):
# self.accessibility.click(call_log_first_item)

# # Add contact action menu should be visible to the screen reader.
# self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
# self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
# *self.phone._add_contact_action_menu_locator)))

# # Close the add contact action menu with the screen reader.
Expand All @@ -74,7 +74,7 @@ def test_phone_call_log(self):
select = self.marionette.find_element(*call_log._call_log_edit_select_all_button_locator)

# Edit mode is visible to the screen reader.
self.assertFalse(self.accessibility.is_hidden(call_log_edit_element))
self.assertTrue(self.accessibility.is_visible(call_log_edit_element))
# Delete button is disabled for the screen reader.
self.assertTrue(self.accessibility.is_disabled(delete))
# Deselect all button is disabled for the screen reader.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_phone_keypad(self):
# Check that the number was entered correctly.
self.assertEqual(self.phone.keypad.phone_number, number_to_verify)
# Delete is visible to the screen reader.
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*self.phone.keypad._keypad_delete_locator)))
# Call button is enabled for the screen reader.
self.assertFalse(self.accessibility.is_disabled(self.marionette.find_element(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_phone_select_toolbars(self):
self.assertTrue(self.accessibility.is_hidden(self.marionette.find_element(
*self.phone._contacts_toolbar_locator)))
# Call log is visible to the screen reader.
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*self.phone._call_log_toolbar_locator)))

# Screen reader activated contacts button click.
Expand All @@ -37,7 +37,7 @@ def test_phone_select_toolbars(self):
self.assertTrue(self.accessibility.is_hidden(self.marionette.find_element(
*self.phone._keypad_toolbar_locator)))
# Contacts is visible to the screen reader.
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*self.phone._contacts_toolbar_locator)))
# Call log is hidden from the screen reader.
self.assertTrue(self.accessibility.is_hidden(self.marionette.find_element(
Expand All @@ -47,7 +47,7 @@ def test_phone_select_toolbars(self):
self.phone.a11y_click_keypad_toolbar_button()

# Keypad is visible to the screen reader.
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*self.phone._keypad_toolbar_locator)))
# Contacts is hidden from the screen reader.
self.assertTrue(self.accessibility.is_hidden(self.marionette.find_element(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ def test_a11y_slider_visibility(self):
# Both rate and volume sliders should be visible
self.assertTrue(self.is_element_displayed(
*accessibility_settings._screen_reader_volume_slider_locator))
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*accessibility_settings._screen_reader_volume_slider_locator)))
self.assertTrue(self.is_element_displayed(
*accessibility_settings._screen_reader_rate_slider_locator))
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*accessibility_settings._screen_reader_rate_slider_locator)))
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
b2g = true

[test_a11y_notification_visibility.py]
[test_a11y_utility_tray_notifications.py]
[test_a11y_utility_tray_settings.py]
[test_a11y_utility_tray_visibility.py]
[test_a11y_volume_buttons.py]
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_a11y_notification_visibility(self):
self.system.wait_for_notification_toaster_displayed()

# Now the notification toaster should be visible to the screen reader.
self.assertFalse(self.accessibility.is_hidden(self.marionette.find_element(
self.assertTrue(self.accessibility.is_visible(self.marionette.find_element(
*self.system._notification_toaster_locator)))

self.system.wait_for_notification_toaster_not_displayed()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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.by import By
from gaiatest import GaiaTestCase
from gaiatest.apps.system.app import System


class TestUtilityTrayNotificationsAccessibility(GaiaTestCase):

def setUp(self):
GaiaTestCase.setUp(self)
self.system = System(self.marionette)

def test_a11y_utility_tray_notifications(self):
self.system.wait_for_status_bar_displayed()

utility_tray = self.system.open_utility_tray()
utility_tray.wait_for_notification_container_displayed()

self.marionette.execute_script('new Notification("Title", {body: "Body"});')
# Assert there is one notification is listed in notifications-container
notifications = utility_tray.notifications
self.assertEqual(1, len(notifications), 'Expected one notification.')

# Clear the notification by "Clear all"
utility_tray.a11y_clear_all_notifications()

# wait for the notifications to be cleared
self.wait_for_condition(lambda m: len(utility_tray.notifications) == 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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 gaiatest import GaiaTestCase
from gaiatest.apps.system.app import System


class TestUtilityTraySettingsAccessibility(GaiaTestCase):

def setUp(self):
GaiaTestCase.setUp(self)
self.system = System(self.marionette)

def test_a11y_utility_tray_settings(self):
self.system.wait_for_status_bar_displayed()

utility_tray = self.system.open_utility_tray()
utility_tray.wait_for_notification_container_displayed()

settings = utility_tray.a11y_click_quick_settings_full_app()

# Make sure that Settings is the currently displayed app.
self.assertEquals(self.apps.displayed_app.name, settings.name)

0 comments on commit 002c73b

Please sign in to comment.