Commit 99929eae by Tim Krones

Add tests for keyboard a11y.

parent 238bbe21
...@@ -14,8 +14,9 @@ TOP_ZONE_DESCRIPTION = _("Use this zone to associate an item with the top layer ...@@ -14,8 +14,9 @@ TOP_ZONE_DESCRIPTION = _("Use this zone to associate an item with the top layer
MIDDLE_ZONE_DESCRIPTION = _("Use this zone to associate an item with the middle layer of the triangle.") MIDDLE_ZONE_DESCRIPTION = _("Use this zone to associate an item with the middle layer of the triangle.")
BOTTOM_ZONE_DESCRIPTION = _("Use this zone to associate an item with the bottom layer of the triangle.") BOTTOM_ZONE_DESCRIPTION = _("Use this zone to associate an item with the bottom layer of the triangle.")
ITEM_INCORRECT_FEEDBACK = _("No, this item does not belong here. Try again.")
ITEM_CORRECT_FEEDBACK = _("Correct! This one belongs to {zone}.") ITEM_CORRECT_FEEDBACK = _("Correct! This one belongs to {zone}.")
ITEM_INCORRECT_FEEDBACK = _("No, this item does not belong here. Try again.")
ITEM_NO_ZONE_FEEDBACK = _("You silly, there are no zones for this one.")
START_FEEDBACK = _("Drag the items onto the image above.") START_FEEDBACK = _("Drag the items onto the image above.")
FINISH_FEEDBACK = _("Good work! You have completed this drag and drop exercise.") FINISH_FEEDBACK = _("Good work! You have completed this drag and drop exercise.")
...@@ -88,7 +89,7 @@ DEFAULT_DATA = { ...@@ -88,7 +89,7 @@ DEFAULT_DATA = {
{ {
"displayName": _("I don't belong anywhere"), "displayName": _("I don't belong anywhere"),
"feedback": { "feedback": {
"incorrect": _("You silly, there are no zones for this one."), "incorrect": ITEM_NO_ZONE_FEEDBACK,
"correct": "" "correct": ""
}, },
"zone": "none", "zone": "none",
......
...@@ -91,7 +91,7 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -91,7 +91,7 @@ function DragAndDropBlock(runtime, element, configuration) {
}; };
var focusModalButton = function() { var focusModalButton = function() {
$root.find('.keyboard-help-dialog .dismiss-modal-button ').focus(); $root.find('.keyboard-help-dialog .modal-dismiss-button ').focus();
}; };
var showKeyboardHelp = function(evt) { var showKeyboardHelp = function(evt) {
...@@ -108,7 +108,7 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -108,7 +108,7 @@ function DragAndDropBlock(runtime, element, configuration) {
// Set up event handlers // Set up event handlers
$(document).on('keydown', keyboardEventDispatcher); $(document).on('keydown', keyboardEventDispatcher);
$keyboardHelpDialog.find('.dismiss-modal-button').on('click', hideKeyboardHelp); $keyboardHelpDialog.find('.modal-dismiss-button').on('click', hideKeyboardHelp);
}; };
var hideKeyboardHelp = function(evt) { var hideKeyboardHelp = function(evt) {
...@@ -124,7 +124,7 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -124,7 +124,7 @@ function DragAndDropBlock(runtime, element, configuration) {
// Remove event handlers // Remove event handlers
$(document).off('keydown', keyboardEventDispatcher); $(document).off('keydown', keyboardEventDispatcher);
$keyboardHelpDialog.find('.dismiss-modal-button').off(); $keyboardHelpDialog.find('.modal-dismiss-button').off();
}; };
/** Asynchronously load the main background image used for this block. */ /** Asynchronously load the main background image used for this block. */
......
...@@ -164,25 +164,27 @@ ...@@ -164,25 +164,27 @@
var dialog_attributes = { role: 'dialog', 'aria-labelledby': 'modal-window-title' }; var dialog_attributes = { role: 'dialog', 'aria-labelledby': 'modal-window-title' };
var dialog_style = {}; var dialog_style = {};
return ( return (
h('div.keyboard-help-dialog', [ h('section.keyboard-help', [
h('div.modal-window-overlay'), h('a.keyboard-help-button', { attributes: { tabindex: 0 } }, gettext('Keyboard Help')),
h('div.modal-window', { attributes: dialog_attributes, style: dialog_style }, [ h('div.keyboard-help-dialog', [
h('div.modal-header', [ h('div.modal-window-overlay'),
h('h2.modal-window-title', gettext('Keyboard Help')) h('div.modal-window', { attributes: dialog_attributes, style: dialog_style }, [
]), h('div.modal-header', [
h('div.modal-content', [ h('h2.modal-window-title', gettext('Keyboard Help'))
h('p', gettext('You can complete this exercise using only your keyboard.')), ]),
h('ul', [ h('div.modal-content', [
h('li', gettext('Use "Tab" and "Shift-Tab" to navigate between items and zones.')), h('p', gettext('You can complete this exercise using only your keyboard.')),
h('li', gettext('Press "Enter" or "Space" on an item to select it for dropping, then navigate to the zone you want to drop it on.')), h('ul', [
h('li', gettext('Press "Enter" or "Space" to drop the item on the current zone.')), h('li', gettext('Use "Tab" and "Shift-Tab" to navigate between items and zones.')),
h('li', gettext('Press "Escape" if you want to cancel the drop operation (e.g. because you would like to select a different item).')), h('li', gettext('Press "Enter" or "Space" on an item to select it for dropping, then navigate to the zone you want to drop it on.')),
h('li', gettext('Press "?" at any time to bring up this dialog.')), h('li', gettext('Press "Enter" or "Space" to drop the item on the current zone.')),
h('li', gettext('Press "Escape" if you want to cancel the drop operation (e.g. because you would like to select a different item).')),
h('li', gettext('Press "?" at any time to bring up this dialog.')),
])
]),
h('div.modal-actions', [
h('button.modal-dismiss-button', gettext("OK"))
]) ])
]),
h('div.modal-actions', [
h('h3.sr', gettext('Actions')),
h('button.dismiss-modal-button', gettext("OK"))
]) ])
]) ])
]) ])
...@@ -223,9 +225,6 @@ ...@@ -223,9 +225,6 @@
renderCollection(itemTemplate, items_placed, ctx), renderCollection(itemTemplate, items_placed, ctx),
]), ]),
]), ]),
h('section.keyboard-help', [
h('a.keyboard-help-button', { attributes: { tabindex: 0 } }, gettext('Keyboard Help'))
]),
keyboardHelpTemplate(ctx), keyboardHelpTemplate(ctx),
feedbackTemplate(ctx), feedbackTemplate(ctx),
]) ])
......
...@@ -57,6 +57,21 @@ class BaseIntegrationTest(SeleniumBaseTest): ...@@ -57,6 +57,21 @@ class BaseIntegrationTest(SeleniumBaseTest):
def _get_zones(self): def _get_zones(self):
return self._page.find_elements_by_css_selector(".drag-container .zone") return self._page.find_elements_by_css_selector(".drag-container .zone")
def _get_popup(self):
return self._page.find_element_by_css_selector(".popup")
def _get_popup_content(self):
return self._page.find_element_by_css_selector(".popup .popup-content")
def _get_keyboard_help(self):
return self._page.find_element_by_css_selector(".keyboard-help")
def _get_keyboard_help_button(self):
return self._page.find_element_by_css_selector(".keyboard-help .keyboard-help-button")
def _get_keyboard_help_dialog(self):
return self._page.find_element_by_css_selector(".keyboard-help .keyboard-help-dialog")
def _get_feedback(self): def _get_feedback(self):
return self._page.find_element_by_css_selector(".feedback") return self._page.find_element_by_css_selector(".feedback")
......
...@@ -179,6 +179,30 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -179,6 +179,30 @@ class TestDragAndDropRender(BaseIntegrationTest):
# Zone description should only be visible to screen readers: # Zone description should only be visible to screen readers:
self.assertEqual(zone_description.get_attribute('class'), 'zone-description sr') self.assertEqual(zone_description.get_attribute('class'), 'zone-description sr')
def test_popup(self):
self.load_scenario()
popup = self._get_popup()
popup_content = self._get_popup_content()
self.assertFalse(popup.is_displayed())
self.assertEqual(popup.get_attribute('aria-live'), 'polite')
self.assertEqual(popup_content.text, "")
def test_keyboard_help(self):
self.load_scenario()
self._get_keyboard_help()
keyboard_help_button = self._get_keyboard_help_button()
keyboard_help_dialog = self._get_keyboard_help_dialog()
dialog_modal_overlay = keyboard_help_dialog.find_element_by_css_selector('.modal-window-overlay')
dialog_modal = keyboard_help_dialog.find_element_by_css_selector('.modal-window')
self.assertEqual(keyboard_help_button.get_attribute('tabindex'), '0')
self.assertFalse(dialog_modal_overlay.is_displayed())
self.assertFalse(dialog_modal.is_displayed())
self.assertEqual(dialog_modal.get_attribute('role'), 'dialog')
self.assertEqual(dialog_modal.get_attribute('aria-labelledby'), 'modal-window-title')
def test_feedback(self): def test_feedback(self):
self.load_scenario() self.load_scenario()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment