Commit 47d67d93 by Tim Krones

Fix: Make sure pressing "?" only brings up a single "Keyboard Help"

dialog, even if page/unit contains multiple DnDv2 exercises.
parent 1a119b6e
...@@ -47,9 +47,12 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -47,9 +47,12 @@ function DragAndDropBlock(runtime, element, configuration) {
initDroppable(); initDroppable();
$(document).on('keydown mousedown touchstart', closePopup); $(document).on('keydown mousedown touchstart', closePopup);
$(document).on('keypress', function(evt) { if (isFirstExercise()) { // Set up handler for "?" key only once,
runOnKey(evt, QUESTION_MARK, showKeyboardHelp); // even if unit contains multiple DnDv2 exercises
}); $(document).on('keypress', function(evt) {
runOnKey(evt, QUESTION_MARK, showKeyboardHelp);
});
}
$element.on('click', '.keyboard-help-button', showKeyboardHelp); $element.on('click', '.keyboard-help-button', showKeyboardHelp);
$element.on('keydown', '.keyboard-help-button', function(evt) { $element.on('keydown', '.keyboard-help-button', function(evt) {
runOnKey(evt, RET, showKeyboardHelp); runOnKey(evt, RET, showKeyboardHelp);
...@@ -67,6 +70,26 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -67,6 +70,26 @@ function DragAndDropBlock(runtime, element, configuration) {
}); });
}; };
var isFirstExercise = function() {
var klass = $element.attr('class');
var $block;
var siblingSelector;
if (klass.startsWith('xblock ')) { // We are in the LMS
$block = $element.parent();
siblingSelector = '.vert[data-id*="drag-and-drop-v2"]';
} else if (klass.startsWith('xblock-v1 ')) { // We are in the workbench
$block = $element;
siblingSelector = '.xblock-v1[data-block-type="drag-and-drop-v2"]';
}
var $previousBlocks = $block.prevAll(siblingSelector);
if ($previousBlocks.length === 0) {
return true;
}
return false;
};
var runOnKey = function(evt, key, handler) { var runOnKey = function(evt, key, handler) {
if (evt.which === key) { if (evt.which === key) {
handler(evt); handler(evt);
......
...@@ -79,6 +79,9 @@ class BaseIntegrationTest(SeleniumBaseTest): ...@@ -79,6 +79,9 @@ class BaseIntegrationTest(SeleniumBaseTest):
def _get_keyboard_help_dialog(self): def _get_keyboard_help_dialog(self):
return self._page.find_element_by_css_selector(".keyboard-help .keyboard-help-dialog") return self._page.find_element_by_css_selector(".keyboard-help .keyboard-help-dialog")
def _get_keyboard_help_dialogs(self):
return self.browser.find_elements_by_css_selector(".keyboard-help .keyboard-help-dialog")
def _get_reset_button(self): def _get_reset_button(self):
return self._page.find_element_by_css_selector('.reset-button') return self._page.find_element_by_css_selector('.reset-button')
......
...@@ -80,6 +80,14 @@ class InteractionTestBase(object): ...@@ -80,6 +80,14 @@ class InteractionTestBase(object):
element = self._get_item_by_value(item_value) element = self._get_item_by_value(item_value)
return element.find_element_by_class_name('numerical-input') return element.find_element_by_class_name('numerical-input')
def _get_dialog_components(self, dialog):
dialog_modal_overlay = dialog.find_element_by_css_selector('.modal-window-overlay')
dialog_modal = dialog.find_element_by_css_selector('.modal-window')
return dialog_modal_overlay, dialog_modal
def _get_dialog_dismiss_button(self, dialog_modal):
return dialog_modal.find_element_by_css_selector('.modal-dismiss-button')
def _get_zone_position(self, zone_id): def _get_zone_position(self, zone_id):
return self.browser.execute_script( return self.browser.execute_script(
'return $("div[data-zone=\'{zone_id}\']").prevAll(".zone").length'.format(zone_id=zone_id) 'return $("div[data-zone=\'{zone_id}\']").prevAll(".zone").length'.format(zone_id=zone_id)
...@@ -265,12 +273,11 @@ class InteractionTestBase(object): ...@@ -265,12 +273,11 @@ class InteractionTestBase(object):
self.assertDictEqual(locations_after_reset[item_key], initial_locations[item_key]) self.assertDictEqual(locations_after_reset[item_key], initial_locations[item_key])
self.assert_reverted_item(item_key) self.assert_reverted_item(item_key)
def interact_with_keyboard_help(self, scroll_down=250, use_keyboard=False): def interact_with_keyboard_help(self, scroll_down=250, use_keyboard=False, multiple_blocks=False):
keyboard_help_button = self._get_keyboard_help_button() keyboard_help_button = self._get_keyboard_help_button()
keyboard_help_dialog = self._get_keyboard_help_dialog() keyboard_help_dialog = self._get_keyboard_help_dialog()
dialog_modal_overlay = keyboard_help_dialog.find_element_by_css_selector('.modal-window-overlay') dialog_modal_overlay, dialog_modal = self._get_dialog_components(keyboard_help_dialog)
dialog_modal = keyboard_help_dialog.find_element_by_css_selector('.modal-window') dialog_dismiss_button = self._get_dialog_dismiss_button(dialog_modal)
dialog_dismiss_button = dialog_modal.find_element_by_css_selector('.modal-dismiss-button')
# Scroll "Keyboard help" button into view to make sure Selenium can successfully click it # Scroll "Keyboard help" button into view to make sure Selenium can successfully click it
self.scroll_down(pixels=scroll_down) self.scroll_down(pixels=scroll_down)
...@@ -291,12 +298,18 @@ class InteractionTestBase(object): ...@@ -291,12 +298,18 @@ class InteractionTestBase(object):
self.assertFalse(dialog_modal_overlay.is_displayed()) self.assertFalse(dialog_modal_overlay.is_displayed())
self.assertFalse(dialog_modal.is_displayed()) self.assertFalse(dialog_modal.is_displayed())
if use_keyboard: # Try again with "?" key if use_keyboard and not multiple_blocks: # Try again with "?" key
# (behavior for multiple blocks has dedicated test below)
self._page.send_keys("?") self._page.send_keys("?")
self.assertTrue(dialog_modal_overlay.is_displayed()) self.assertTrue(dialog_modal_overlay.is_displayed())
self.assertTrue(dialog_modal.is_displayed()) self.assertTrue(dialog_modal.is_displayed())
self._page.send_keys(Keys.ESCAPE)
self.assertFalse(dialog_modal_overlay.is_displayed())
self.assertFalse(dialog_modal.is_displayed())
class BasicInteractionTest(InteractionTestBase): class BasicInteractionTest(InteractionTestBase):
""" """
...@@ -482,3 +495,37 @@ class MultipleBlocksDataInteraction(InteractionTestBase, BaseIntegrationTest): ...@@ -482,3 +495,37 @@ class MultipleBlocksDataInteraction(InteractionTestBase, BaseIntegrationTest):
self.parameterized_final_feedback_and_reset(self.item_maps['block1'], self.feedback['block1']) self.parameterized_final_feedback_and_reset(self.item_maps['block1'], self.feedback['block1'])
self._switch_to_block(1) self._switch_to_block(1)
self.parameterized_final_feedback_and_reset(self.item_maps['block2'], self.feedback['block2'], scroll_down=900) self.parameterized_final_feedback_and_reset(self.item_maps['block2'], self.feedback['block2'], scroll_down=900)
def test_keyboard_help(self):
self._switch_to_block(0)
# Test mouse and keyboard interaction
self.interact_with_keyboard_help()
self.interact_with_keyboard_help(use_keyboard=True)
self._switch_to_block(1)
# Test mouse and keyboard interaction
self.interact_with_keyboard_help(scroll_down=900)
self.interact_with_keyboard_help(scroll_down=0, use_keyboard=True, multiple_blocks=True)
# When pressing "?" on a page with multiple DnDv2 exercises,
# only a single "Keyboard Help" dialog should be shown:
first_keyboard_help_dialog, second_keyboard_help_dialog = self._get_keyboard_help_dialogs()
first_dialog_modal_overlay, first_dialog_modal = self._get_dialog_components(first_keyboard_help_dialog)
first_dialog_dismiss_button = self._get_dialog_dismiss_button(first_dialog_modal)
second_dialog_modal_overlay, second_dialog_modal = self._get_dialog_components(second_keyboard_help_dialog)
self._switch_to_block(0)
self._page.send_keys("?")
self.assertTrue(first_dialog_modal_overlay.is_displayed())
self.assertTrue(first_dialog_modal.is_displayed())
self.assertFalse(second_dialog_modal_overlay.is_displayed())
self.assertFalse(second_dialog_modal.is_displayed())
first_dialog_dismiss_button.click()
self._switch_to_block(1)
self._page.send_keys("?")
self.assertTrue(first_dialog_modal_overlay.is_displayed())
self.assertTrue(first_dialog_modal.is_displayed())
self.assertFalse(second_dialog_modal_overlay.is_displayed())
self.assertFalse(second_dialog_modal.is_displayed())
first_dialog_dismiss_button.click()
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