Commit 8cb4774d by Braden MacDonald Committed by GitHub

Merge pull request #110 from open-craft/ekolpakov/improve-keyboard-instructions

Improve keyboard and SR instructions
parents 34c41163 77df9f5f
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
display: inline-block; display: inline-block;
color: #5e5e5e; color: #5e5e5e;
font-size: 0.875em; font-size: 0.875em;
margin-bottom: 0.5em;
} }
.xblock--drag-and-drop .problem p { .xblock--drag-and-drop .problem p {
...@@ -444,8 +445,6 @@ ...@@ -444,8 +445,6 @@
.xblock--drag-and-drop .btn-brand { .xblock--drag-and-drop .btn-brand {
display: inline-block; display: inline-block;
font-weight: normal; font-weight: normal;
background: #0079bc;
color: #fcfcfc;
-webkit-transition: color 0.125s ease-in-out 0s, border-color 0.125s ease-in-out 0s, background 0.125s ease-in-out 0s, box-shadow 0.125s ease-in-out 0s; -webkit-transition: color 0.125s ease-in-out 0s, border-color 0.125s ease-in-out 0s, background 0.125s ease-in-out 0s, box-shadow 0.125s ease-in-out 0s;
-moz-transition: color 0.125s ease-in-out 0s, border-color 0.125s ease-in-out 0s, background 0.125s ease-in-out 0s, box-shadow 0.125s ease-in-out 0s; -moz-transition: color 0.125s ease-in-out 0s, border-color 0.125s ease-in-out 0s, background 0.125s ease-in-out 0s, box-shadow 0.125s ease-in-out 0s;
transition: color 0.125s ease-in-out 0s, border-color 0.125s ease-in-out 0s, background 0.125s ease-in-out 0s, box-shadow 0.125s ease-in-out 0s; transition: color 0.125s ease-in-out 0s, border-color 0.125s ease-in-out 0s, background 0.125s ease-in-out 0s, box-shadow 0.125s ease-in-out 0s;
...@@ -472,6 +471,12 @@ ...@@ -472,6 +471,12 @@
font-size: 0.875em; font-size: 0.875em;
} }
.xblock--drag-and-drop .btn-link {
padding: 1px;
font-size: 0.875em;
font-weight: normal;
}
.xblock--drag-and-drop .btn-default:hover, .xblock--drag-and-drop .btn-default:hover,
.xblock--drag-and-drop .btn-default.is-hovered, .xblock--drag-and-drop .btn-default.is-hovered,
.xblock--drag-and-drop .btn-default:focus, .xblock--drag-and-drop .btn-default:focus,
...@@ -625,6 +630,10 @@ ...@@ -625,6 +630,10 @@
display: block; display: block;
} }
.xblock--drag-and-drop .btn-link .btn-icon {
display: inline;
}
/*** ACTIONS TOOLBAR END ***/ /*** ACTIONS TOOLBAR END ***/
/*** KEYBOARD HELP ***/ /*** KEYBOARD HELP ***/
......
...@@ -53,6 +53,7 @@ function DragAndDropTemplates(configuration) { ...@@ -53,6 +53,7 @@ function DragAndDropTemplates(configuration) {
var itemTemplate = function(item, ctx) { var itemTemplate = function(item, ctx) {
// Define properties // Define properties
var descriptionClassName = "sr description";
var className = (item.class_name) ? item.class_name : ""; var className = (item.class_name) ? item.class_name : "";
var zone = getZone(item.zone, ctx) || {}; var zone = getZone(item.zone, ctx) || {};
if (item.has_image) { if (item.has_image) {
...@@ -69,7 +70,8 @@ function DragAndDropTemplates(configuration) { ...@@ -69,7 +70,8 @@ function DragAndDropTemplates(configuration) {
'draggable': !item.drag_disabled, 'draggable': !item.drag_disabled,
'aria-grabbed': item.grabbed, 'aria-grabbed': item.grabbed,
'data-value': item.value, 'data-value': item.value,
'tabindex': item.focusable ? 0 : undefined 'tabindex': item.focusable ? 0 : undefined,
'aria-live': 'polite'
}; };
var style = {}; var style = {};
if (item.background_color) { if (item.background_color) {
...@@ -98,13 +100,11 @@ function DragAndDropTemplates(configuration) { ...@@ -98,13 +100,11 @@ function DragAndDropTemplates(configuration) {
$.extend(style, bankItemWidthStyles(item, ctx)); $.extend(style, bankItemWidthStyles(item, ctx));
} }
// Define children // Define children
var children = [
itemSpinnerTemplate(item)
];
var item_content = itemContentTemplate(item); var item_content = itemContentTemplate(item);
var item_description = null;
// Insert information about zone in which this item has been placed // Insert information about zone in which this item has been placed
var item_description_id = configuration.url_name + '-item-' + item.value + '-description';
item_content.properties.attributes = { 'aria-describedby': item_description_id };
if (item.is_placed) { if (item.is_placed) {
var zone_title = (zone.title || "Unknown Zone"); // This "Unknown" text should never be seen, so does not need i18n var zone_title = (zone.title || "Unknown Zone"); // This "Unknown" text should never be seen, so does not need i18n
var description_content; var description_content;
...@@ -116,20 +116,23 @@ function DragAndDropTemplates(configuration) { ...@@ -116,20 +116,23 @@ function DragAndDropTemplates(configuration) {
// so all placed items are always in the correct zone. // so all placed items are always in the correct zone.
description_content = gettext('Correctly placed in: {zone_title}').replace('{zone_title}', zone_title); description_content = gettext('Correctly placed in: {zone_title}').replace('{zone_title}', zone_title);
} }
var item_description = h( var item_description_id = configuration.url_name + '-item-' + item.value + '-description';
item_content.properties.attributes = { 'aria-describedby': item_description_id };
item_description = h(
'div', 'div',
{ key: item.value + '-description', id: item_description_id, className: 'sr' }, { key: item.value + '-description', id: item_description_id, className: descriptionClassName },
description_content description_content
); );
} else {
var item_description = h(
'div',
{ id: item_description_id, className: 'sr'},
gettext('Press "Enter", "Space", "Ctrl-m", or "⌘-m" on an item to select it for dropping, then navigate to the zone you want to drop it on.')
);
} }
children.splice(1, 0, item_description); var itemSRNote = h(
children.splice(1, 0, item_content); 'span.sr.draggable',
(item.grabbed) ? gettext(", draggable, grabbed") : gettext(", draggable")
);
var children = [
itemSpinnerTemplate(item), item_content, itemSRNote, item_description
];
return ( return (
h( h(
'div.option', 'div.option',
...@@ -219,7 +222,7 @@ function DragAndDropTemplates(configuration) { ...@@ -219,7 +222,7 @@ function DragAndDropTemplates(configuration) {
}, },
[ [
h('p', { className: className }, zone.title), h('p', { className: className }, zone.title),
h('p', { className: 'zone-description sr' }, zone.description), h('p', { className: 'zone-description sr' }, zone.description || gettext("droppable")),
h(item_wrapper, renderCollection(itemTemplate, items_in_zone, ctx)), h(item_wrapper, renderCollection(itemTemplate, items_in_zone, ctx)),
zone_description zone_description
] ]
...@@ -252,54 +255,25 @@ function DragAndDropTemplates(configuration) { ...@@ -252,54 +255,25 @@ function DragAndDropTemplates(configuration) {
); );
}; };
var popupTemplate = function(ctx) {
var popupSelector = 'div.popup';
if (ctx.popup_html && !ctx.last_action_correct) {
popupSelector += '.popup-incorrect';
}
return (
h(
"div.popup-wrapper",
{
attributes: {
'aria-live': 'polite',
'aria-atomic': 'true',
'aria-relevant': 'additions',
}
},
[
h(
popupSelector,
{
style: {display: ctx.popup_html ? 'block' : 'none'},
},
[
h('div.close.icon-remove-sign.fa-times-circle'),
h('p.popup-content', {innerHTML: ctx.popup_html}),
]
)
]
)
)
};
var keyboardHelpPopupTemplate = function(ctx) { var keyboardHelpPopupTemplate = function(ctx) {
var labelledby_id = 'modal-window-title-'+configuration.url_name; var labelledby_id = 'modal-window-title-'+configuration.url_name;
return ( return (
h('div.keyboard-help-dialog', [ h('div.keyboard-help-dialog', [
h('div.modal-window-overlay'), h('div.modal-window-overlay'),
h('div.modal-window', {attributes: {role: 'dialog', 'aria-labelledby': labelledby_id}}, [ h('div.modal-window', {attributes: {role: 'dialog', 'aria-labelledby': labelledby_id, tabindex: -1}}, [
h('div.modal-header', [ h('div.modal-header', [
h('h2.modal-window-title#'+labelledby_id, gettext('Keyboard Help')) h('h2.modal-window-title#'+labelledby_id, gettext('Keyboard Help'))
]), ]),
h('div.modal-content', [ h('div.modal-content', [
h('p', gettext('You can complete this problem using only your keyboard.')), h('p.sr', gettext('This is a screen reader-friendly problem.')),
h('p.sr', gettext('Drag and Drop problems consist of draggable items and dropzones. Users should select a draggable item with their keyboard and then navigate to an appropriate dropzone to drop it.')),
h('p', gettext('You can complete this problem using only your keyboard by following the guidance below:')),
h('ul', [ h('ul', [
h('li', gettext('Use "Tab" and "Shift-Tab" to navigate between items and zones.')), h('li', gettext('Use only TAB and SHIFT+TAB to navigate between draggable items and drop zones.')),
h('li', gettext('Press "Enter", "Space", "Ctrl-m", or "⌘-m" on an item to select it for dropping, then navigate to the zone you want to drop it on.')), h('li', gettext('Press CTRL+M to select a draggable item (effectively picking it up).')),
h('li', gettext('Press "Enter", "Space", "Ctrl-m", or "⌘-m" to drop the item on the current zone.')), h('li', gettext('Navigate using TAB and SHIFT+TAB to the appropriate dropzone and press CTRL+M once more to drop it here.')),
h('li', gettext('Press "Esc" if you want to cancel the drop operation (for example, to select a different item).')), h('li', gettext('Press ESC if you want to cancel the drop operation (for example, to select a different item).')),
h('li', gettext('TAB back to the list of draggable items and repeat this process until all of the draggable items have been placed on their respective dropzones.')),
]) ])
]), ]),
h('div.modal-actions', [ h('div.modal-actions', [
...@@ -370,7 +344,6 @@ function DragAndDropTemplates(configuration) { ...@@ -370,7 +344,6 @@ function DragAndDropTemplates(configuration) {
} }
return( return(
h("section.action-toolbar-item.sidebar-buttons", {}, [ h("section.action-toolbar-item.sidebar-buttons", {}, [
sidebarButtonTemplate("keyboard-help-button", "fa-question", gettext('Keyboard Help')),
sidebarButtonTemplate("reset-button", "fa-refresh", gettext('Reset'), ctx.disable_reset_button), sidebarButtonTemplate("reset-button", "fa-refresh", gettext('Reset'), ctx.disable_reset_button),
showAnswerButton, showAnswerButton,
]) ])
...@@ -423,7 +396,7 @@ function DragAndDropTemplates(configuration) { ...@@ -423,7 +396,7 @@ function DragAndDropTemplates(configuration) {
h( h(
'span.sr', 'span.sr',
{ {
innerHTML: gettext("Close item feedback popup") innerHTML: gettext("Close")
} }
), ),
h( h(
...@@ -441,6 +414,22 @@ function DragAndDropTemplates(configuration) { ...@@ -441,6 +414,22 @@ function DragAndDropTemplates(configuration) {
) )
}; };
var forwardKeyboardHelpButtonTemplate = function(ctx) {
return h(
'button.unbutton.btn-link.keyboard-help-button',
[
h(
"span.btn-icon.fa.fa-keyboard-o",
{attributes: {"aria-hidden": true}}
),
// appending space is the simplest way to avoid sticking text to the button, but also to have
// them underlined together on hover. When margin was used there was a gap in underlining
" ",
gettext('Keyboard Help')
]
);
};
var progressTemplate = function(ctx) { var progressTemplate = function(ctx) {
// Formats a number to 4 decimals without trailing zeros // Formats a number to 4 decimals without trailing zeros
// (1.00 -> '1'; 1.50 -> '1.5'; 1.333333333 -> '1.3333'). // (1.00 -> '1'; 1.50 -> '1.5'; 1.333333333 -> '1.3333').
...@@ -504,26 +493,29 @@ function DragAndDropTemplates(configuration) { ...@@ -504,26 +493,29 @@ function DragAndDropTemplates(configuration) {
var is_item_placed = function(i) { return i.is_placed; }; var is_item_placed = function(i) { return i.is_placed; };
var items_placed = $.grep(ctx.items, is_item_placed); var items_placed = $.grep(ctx.items, is_item_placed);
var items_in_bank = $.grep(ctx.items, is_item_placed, true); var items_in_bank = $.grep(ctx.items, is_item_placed, true);
var item_bank_properties = {}; var item_bank_properties = {
if (ctx.item_bank_focusable) { attributes: {
item_bank_properties.attributes = { 'role': 'group',
'tabindex': 0, 'aria-label': gettext('Item Bank')
'dropzone': 'move', }
'aria-dropeffect': 'move',
'role': 'button'
}; };
if (ctx.item_bank_focusable) {
item_bank_properties.attributes['tabindex'] = 0;
item_bank_properties.attributes['dropzone'] = 'move';
item_bank_properties.attributes['aria-dropeffect'] = 'move';
item_bank_properties.attributes['role'] = 'button';
} }
return ( return (
h('section.themed-xblock.xblock--drag-and-drop', [ h('section.themed-xblock.xblock--drag-and-drop', [
problemTitle, problemTitle,
problemProgress, problemProgress,
h('div', [forwardKeyboardHelpButtonTemplate(ctx)]),
h('section.problem', [ h('section.problem', [
problemHeader, problemHeader,
h('p', {innerHTML: ctx.problem_html}), h('p', {innerHTML: ctx.problem_html}),
]), ]),
h('section.drag-container', {}, [ h('section.drag-container', {}, [
h('div.item-bank', item_bank_properties, [ h('div.item-bank', item_bank_properties, [
h('p', { className: 'zone-description sr' }, gettext('Item Bank')),
renderCollection(itemTemplate, items_in_bank, ctx), renderCollection(itemTemplate, items_in_bank, ctx),
renderCollection(itemPlaceholderTemplate, items_placed, ctx) renderCollection(itemPlaceholderTemplate, items_placed, ctx)
]), ]),
...@@ -688,11 +680,10 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -688,11 +680,10 @@ function DragAndDropBlock(runtime, element, configuration) {
// Show dialog // Show dialog
var $keyboardHelpDialog = $root.find('.keyboard-help-dialog'); var $keyboardHelpDialog = $root.find('.keyboard-help-dialog');
$keyboardHelpDialog.find('.modal-window-overlay').show(); $keyboardHelpDialog.find('.modal-window-overlay').show();
$keyboardHelpDialog.find('.modal-window').show(); $keyboardHelpDialog.find('.modal-window').show().focus();
// Handle focus // Handle focus
$focusedElement = $(':focus'); $focusedElement = $(':focus');
focusModalButton();
// Set up event handlers // Set up event handlers
$(document).on('keydown', keyboardEventDispatcher); $(document).on('keydown', keyboardEventDispatcher);
...@@ -851,11 +842,7 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -851,11 +842,7 @@ function DragAndDropBlock(runtime, element, configuration) {
}; };
var isActionKey = function(evt) { var isActionKey = function(evt) {
var key = evt.which; return evt.which == RET || (evt.ctrlKey && evt.which == M);
if (evt.ctrlKey || evt.metaKey) {
return key === M;
}
return key === RET || key === SPC;
}; };
var isSpaceKey = function(evt) { var isSpaceKey = function(evt) {
......
...@@ -449,6 +449,14 @@ msgstr "" ...@@ -449,6 +449,14 @@ msgstr ""
msgid "Correctly placed in: {zone_title}" msgid "Correctly placed in: {zone_title}"
msgstr "" msgstr ""
#: drag_and_drop_v2/public/js/drag_and_drop.js:137
msgid ", draggable, grabbed"
msgstr ""
#: drag_and_drop_v2/public/js/drag_and_drop.js:137
msgid ", draggable"
msgstr ""
#: public/js/drag_and_drop.js #: public/js/drag_and_drop.js
msgid "Reset" msgid "Reset"
msgstr "" msgstr ""
...@@ -473,32 +481,51 @@ msgstr "" ...@@ -473,32 +481,51 @@ msgstr ""
msgid "Keyboard Help" msgid "Keyboard Help"
msgstr "" msgstr ""
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js:305
msgid "You can complete this problem using only your keyboard." msgid "This is a screen reader-friendly problem"
msgstr "" msgstr ""
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js:306
msgid "Use \"Tab\" and \"Shift-Tab\" to navigate between items and zones." msgid ""
"You can complete this problem using only your keyboard by following the "
"guidance below:"
msgstr "" msgstr ""
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js:307
msgid "" msgid ""
"Press \"Enter\", \"Space\", \"Ctrl-m\", or \"⌘-m\" on an item to select it " "Drag and Drop problems consist of draggable items and dropzones. Users "
"for dropping, then navigate to the zone you want to drop it on." "should select a draggable item with their keyboard and then navigate to an "
"appropriate dropzone to drop it."
msgstr "" msgstr ""
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js:309
msgid "" msgid ""
"Press \"Enter\", \"Space\", \"Ctrl-m\", or \"⌘-m\" to drop the item on the " "Use only TAB and SHIFT+TAB to navigate between draggable items and drop "
"current zone." "zones."
msgstr "" msgstr ""
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js:310
msgid "Press CTRL+M to select a draggable item (effectively picking it up)."
msgstr ""
#: drag_and_drop_v2/public/js/drag_and_drop.js:311
msgid "" msgid ""
"Press \"Esc\" if you want to cancel the drop operation (for example, to " "Navigate using TAB and SHIFT+TAB to the appropriate dropzone and press CTRL"
"+M once more to drop it here."
msgstr ""
#: drag_and_drop_v2/public/js/drag_and_drop.js:312
msgid ""
"Press ESC if you want to cancel the drop operation (for example, to "
"select a different item)." "select a different item)."
msgstr "" msgstr ""
#: drag_and_drop_v2/public/js/drag_and_drop.js:313
msgid ""
"TAB back to the list of draggable items and repeat this process until all of "
"the draggable items have been placed on their respective dropzones."
msgstr ""
#: public/js/drag_and_drop.js #: public/js/drag_and_drop.js
msgid "OK" msgid "OK"
msgstr "" msgstr ""
...@@ -532,7 +559,7 @@ msgid "None" ...@@ -532,7 +559,7 @@ msgid "None"
msgstr "" msgstr ""
#: public/js/drag_and_drop_edit.js #: public/js/drag_and_drop_edit.js
msgid "Close item feedback popup" msgid "Close"
msgstr "" msgstr ""
......
...@@ -521,6 +521,14 @@ msgstr "Pläçéd ïn: {zone_title} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт ...@@ -521,6 +521,14 @@ msgstr "Pläçéd ïn: {zone_title} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт
msgid "Correctly placed in: {zone_title}" msgid "Correctly placed in: {zone_title}"
msgstr "Çörréçtlý pläçéd ïn: {zone_title} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #" msgstr "Çörréçtlý pläçéd ïn: {zone_title} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
#: drag_and_drop_v2/public/js/drag_and_drop.js
msgid ", draggable, grabbed"
msgstr ", dräggäßlé, gräßßéd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
#: drag_and_drop_v2/public/js/drag_and_drop.js
msgid ", draggable"
msgstr "dräggäßlé Ⱡ'σяєм ιρѕυм ∂σł#"
#: public/js/drag_and_drop.js #: public/js/drag_and_drop.js
msgid "Reset" msgid "Reset"
msgstr "Rését Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#" msgstr "Rését Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
...@@ -545,42 +553,79 @@ msgstr "Féédßäçk Ⱡ'σяєм ιρѕυм ∂#" ...@@ -545,42 +553,79 @@ msgstr "Féédßäçk Ⱡ'σяєм ιρѕυм ∂#"
msgid "Keyboard Help" msgid "Keyboard Help"
msgstr "Kéýßöärd Hélp Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#" msgstr "Kéýßöärd Hélp Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "You can complete this problem using only your keyboard." msgid "This is a screen reader-friendly problem."
msgstr "" msgstr ""
"Ýöü çän çömplété thïs prößlém üsïng önlý ýöür kéýßöärd. Ⱡ'σяєм ιρѕυм ∂σłσя " "Thïs ïs ä sçréén réädér-frïéndlý prößlém. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"ѕιт αмєт, ¢σηѕє¢тєтυя α#" "¢σηѕє¢тєтυя#"
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "Use \"Tab\" and \"Shift-Tab\" to navigate between items and zones." msgid ""
"You can complete this problem using only your keyboard by following the "
"guidance below:"
msgstr "" msgstr ""
"Ûsé \"Täß\" änd \"Shïft-Täß\" tö nävïgäté ßétwéén ïtéms änd zönés. Ⱡ'σяєм " "Ýöü çän çömplété thïs prößlém üsïng önlý ýöür kéýßöärd ßý föllöwïng thé "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#" "güïdänçé ßélöw: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "" msgid ""
"Press \"Enter\", \"Space\", \"Ctrl-m\", or \"⌘-m\" on an item to select it " "Drag and Drop problems consist of draggable items and dropzones. Users "
"for dropping, then navigate to the zone you want to drop it on." "should select a draggable item with their keyboard and then navigate to an "
"appropriate dropzone to drop it."
msgstr "" msgstr ""
"Préss \"Éntér\", \"Späçé\", \"Çtrl-m\", ör \"⌘-m\" ön än ïtém tö séléçt ït " "Dräg änd Dröp prößléms çönsïst öf dräggäßlé ïtéms änd dröpzönés. Ûsérs "
"för dröppïng, thén nävïgäté tö thé zöné ýöü wänt tö dröp ït ön. Ⱡ'#" "shöüld séléçt ä dräggäßlé ïtém wïth théïr kéýßöärd änd thén nävïgäté tö än "
"äppröprïäté dröpzöné tö dröp ït. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя "
"α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα"
" αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ "
"ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ ¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη "
"яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα "
"ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт ηση ρяσι∂єηт, ѕυηт ιη #"
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "" msgid ""
"Press \"Enter\", \"Space\", \"Ctrl-m\", or \"⌘-m\" to drop the item on the " "Use only TAB and SHIFT+TAB to navigate between draggable items and drop "
"current zone." "zones."
msgstr "" msgstr ""
"Préss \"Éntér\", \"Späçé\", \"Çtrl-m\", ör \"⌘-m\" tö dröp thé ïtém ön thé " "Ûsé önlý TÀB änd SHÌFT+TÀB tö nävïgäté ßétwéén dräggäßlé ïtéms änd dröp "
"çürrént zöné. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#" "zönés. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
#: public/js/drag_and_drop.js #: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "Press CTRL+M to select a draggable item (effectively picking it up)."
msgstr ""
"Préss ÇTRL+M tö séléçt ä dräggäßlé ïtém (éfféçtïvélý pïçkïng ït üp). Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
#: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "" msgid ""
"Press \"Esc\" if you want to cancel the drop operation (for example, to " "Navigate using TAB and SHIFT+TAB to the appropriate dropzone and press "
"CTRL+M once more to drop it here."
msgstr ""
"Nävïgäté üsïng TÀB änd SHÌFT+TÀB tö thé äppröprïäté dröpzöné änd préss "
"ÇTRL+M önçé möré tö dröp ït héré. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
#: drag_and_drop_v2/public/js/drag_and_drop.js
msgid ""
"Press ESC if you want to cancel the drop operation (for example, to "
"select a different item)." "select a different item)."
msgstr "" msgstr ""
"Préss \"Ésç\" ïf ýöü wänt tö çänçél thé dröp öpérätïön (för éxämplé, tö " "Préss ÉSÇ ïf ýöü wänt tö çänçél thé dröp öpérätïön (för éxämplé, tö "
"séléçt ä dïfférént ïtém). Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#" "séléçt ä dïfférént ïtém). Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
#: drag_and_drop_v2/public/js/drag_and_drop.js
msgid ""
"TAB back to the list of draggable items and repeat this process until all of"
" the draggable items have been placed on their respective dropzones."
msgstr ""
"TÀB ßäçk tö thé lïst öf dräggäßlé ïtéms änd répéät thïs pröçéss üntïl äll öf"
" thé dräggäßlé ïtéms hävé ßéén pläçéd ön théïr réspéçtïvé dröpzönés. Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ є#"
#: public/js/drag_and_drop.js #: public/js/drag_and_drop.js
msgid "OK" msgid "OK"
msgstr "ÖK Ⱡ'σя#" msgstr "ÖK Ⱡ'σя#"
...@@ -641,9 +686,9 @@ msgid_plural "{possible} points possible (ungraded)" ...@@ -641,9 +686,9 @@ msgid_plural "{possible} points possible (ungraded)"
msgstr[0] "{possible} pöïnt pössïßlé (üngrädéd) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#" msgstr[0] "{possible} pöïnt pössïßlé (üngrädéd) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
msgstr[1] "{possible} pöïnts pössïßlé (üngrädéd) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#" msgstr[1] "{possible} pöïnts pössïßlé (üngrädéd) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
#: public/js/drag_and_drop_edit.js #: drag_and_drop_v2/public/js/drag_and_drop.js
msgid "Close item feedback popup" msgid "Close"
msgstr "Çlösé ïtém féédßäçk pöpüp Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#" msgstr "Çlösé Ⱡ'σяєм ιρѕ#"
#: utils.py:44 #: utils.py:44
msgid "Your highest score is {score}" msgid "Your highest score is {score}"
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import json import json
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver import ActionChains from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
...@@ -384,7 +385,7 @@ class InteractionTestBase(object): ...@@ -384,7 +385,7 @@ class InteractionTestBase(object):
self.wait_until_ondrop_xhr_finished(item) self.wait_until_ondrop_xhr_finished(item)
item_content = item.find_element_by_css_selector('.item-content') item_content = item.find_element_by_css_selector('.item-content')
self.wait_until_visible(item_content) self.wait_until_visible(item_content)
item_description = item.find_element_by_css_selector('.sr') item_description = item.find_element_by_css_selector('.sr.description')
self.wait_until_visible(item_description) self.wait_until_visible(item_description)
item_description_id = '-item-{}-description'.format(item_value) item_description_id = '-item-{}-description'.format(item_value)
...@@ -421,12 +422,13 @@ class InteractionTestBase(object): ...@@ -421,12 +422,13 @@ class InteractionTestBase(object):
self.assertEqual(item.get_attribute('class'), 'option') self.assertEqual(item.get_attribute('class'), 'option')
self.assertEqual(item.get_attribute('tabindex'), '0') self.assertEqual(item.get_attribute('tabindex'), '0')
self.assertEqual(item.get_attribute('aria-grabbed'), 'false') self.assertEqual(item.get_attribute('aria-grabbed'), 'false')
item_description_id = '-item-{}-description'.format(item_value) self.assertEqual(item_content.get_attribute('aria-describedby'), None)
self.assertEqual(item_content.get_attribute('aria-describedby'), item_description_id)
describedby_text = (u'Press "Enter", "Space", "Ctrl-m", or "⌘-m" on an item to select it for dropping, ' try:
'then navigate to the zone you want to drop it on.') item.find_element_by_css_selector('.sr.description')
self.assertEqual(item.find_element_by_css_selector('.sr').text, describedby_text) self.fail("Description element exists")
except NoSuchElementException:
pass
def place_decoy_items(self, items_map, action_key): def place_decoy_items(self, items_map, action_key):
decoy_items = self._get_items_without_zone(items_map) decoy_items = self._get_items_without_zone(items_map)
......
...@@ -23,6 +23,8 @@ loader = ResourceLoader(__name__) ...@@ -23,6 +23,8 @@ loader = ResourceLoader(__name__)
# Classes ########################################################### # Classes ###########################################################
ITEM_DRAG_KEYBOARD_KEYS = (None, Keys.RETURN, Keys.CONTROL+'m')
class ParameterizedTestsMixin(object): class ParameterizedTestsMixin(object):
def parameterized_item_positive_feedback_on_good_move( def parameterized_item_positive_feedback_on_good_move(
...@@ -167,7 +169,7 @@ class ParameterizedTestsMixin(object): ...@@ -167,7 +169,7 @@ class ParameterizedTestsMixin(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=100, use_keyboard=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, dialog_modal = self._get_dialog_components(keyboard_help_dialog) dialog_modal_overlay, dialog_modal = self._get_dialog_components(keyboard_help_dialog)
...@@ -211,15 +213,15 @@ class StandardInteractionTest(DefaultDataTestMixin, InteractionTestBase, Paramet ...@@ -211,15 +213,15 @@ class StandardInteractionTest(DefaultDataTestMixin, InteractionTestBase, Paramet
All interactions are tested using mouse (action_key=None) and four different keyboard action keys. All interactions are tested using mouse (action_key=None) and four different keyboard action keys.
If default data changes this will break. If default data changes this will break.
""" """
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_item_positive_feedback_on_good_move(self, action_key): def test_item_positive_feedback_on_good_move(self, action_key):
self.parameterized_item_positive_feedback_on_good_move(self.items_map, action_key=action_key) self.parameterized_item_positive_feedback_on_good_move(self.items_map, action_key=action_key)
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_item_negative_feedback_on_bad_move(self, action_key): def test_item_negative_feedback_on_bad_move(self, action_key):
self.parameterized_item_negative_feedback_on_bad_move(self.items_map, self.all_zones, action_key=action_key) self.parameterized_item_negative_feedback_on_bad_move(self.items_map, self.all_zones, action_key=action_key)
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_cannot_move_items_between_zones(self, action_key): def test_cannot_move_items_between_zones(self, action_key):
self.parameterized_cannot_move_items_between_zones( self.parameterized_cannot_move_items_between_zones(
self.items_map, self.all_zones, action_key=action_key self.items_map, self.all_zones, action_key=action_key
...@@ -236,9 +238,12 @@ class StandardInteractionTest(DefaultDataTestMixin, InteractionTestBase, Paramet ...@@ -236,9 +238,12 @@ class StandardInteractionTest(DefaultDataTestMixin, InteractionTestBase, Paramet
for _, definition in self.items_map.items(): for _, definition in self.items_map.items():
item = self._get_unplaced_item_by_value(definition.item_id) item = self._get_unplaced_item_by_value(definition.item_id)
ActionChains(self.browser).move_to_element(item).perform() ActionChains(self.browser).move_to_element(item).perform()
keyboard_help_text = (u'Press "Enter", "Space", "Ctrl-m", or "⌘-m" on an item to select it for dropping, ' self.assertEqual(item.find_element_by_css_selector('.sr.draggable').text, ", draggable")
'then navigate to the zone you want to drop it on.') item.send_keys("")
self.assertEqual(item.find_element_by_css_selector('.sr').text, keyboard_help_text) item.send_keys(Keys.ENTER) # grabbed an item
self.assertEqual(item.find_element_by_css_selector('.sr.draggable').text, ", draggable, grabbed")
item.send_keys(Keys.ESCAPE)
self.assertEqual(item.find_element_by_css_selector('.sr.draggable').text, ", draggable")
def test_alt_text_for_zones(self): def test_alt_text_for_zones(self):
self._get_popup() self._get_popup()
...@@ -264,7 +269,7 @@ class StandardInteractionTest(DefaultDataTestMixin, InteractionTestBase, Paramet ...@@ -264,7 +269,7 @@ class StandardInteractionTest(DefaultDataTestMixin, InteractionTestBase, Paramet
self.wait_until_visible(item_content) self.wait_until_visible(item_content)
self.assertTrue(item_content.text in zone_description) self.assertTrue(item_content.text in zone_description)
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_final_feedback_and_reset(self, action_key): def test_final_feedback_and_reset(self, action_key):
self.parameterized_final_feedback_and_reset(self.items_map, self.feedback, action_key=action_key) self.parameterized_final_feedback_and_reset(self.items_map, self.feedback, action_key=action_key)
...@@ -442,21 +447,21 @@ class MultipleBlocksDataInteraction(ParameterizedTestsMixin, InteractionTestBase ...@@ -442,21 +447,21 @@ class MultipleBlocksDataInteraction(ParameterizedTestsMixin, InteractionTestBase
self._switch_to_block(0) self._switch_to_block(0)
self.parameterized_item_positive_feedback_on_good_move(self.item_maps['block1']) self.parameterized_item_positive_feedback_on_good_move(self.item_maps['block1'])
self._switch_to_block(1) self._switch_to_block(1)
self.parameterized_item_positive_feedback_on_good_move(self.item_maps['block2'], scroll_down=900) self.parameterized_item_positive_feedback_on_good_move(self.item_maps['block2'], scroll_down=1000)
def test_item_negative_feedback_on_bad_move(self): def test_item_negative_feedback_on_bad_move(self):
self._switch_to_block(0) self._switch_to_block(0)
self.parameterized_item_negative_feedback_on_bad_move(self.item_maps['block1'], self.all_zones['block1']) self.parameterized_item_negative_feedback_on_bad_move(self.item_maps['block1'], self.all_zones['block1'])
self._switch_to_block(1) self._switch_to_block(1)
self.parameterized_item_negative_feedback_on_bad_move( self.parameterized_item_negative_feedback_on_bad_move(
self.item_maps['block2'], self.all_zones['block2'], scroll_down=900 self.item_maps['block2'], self.all_zones['block2'], scroll_down=1000
) )
def test_final_feedback_and_reset(self): def test_final_feedback_and_reset(self):
self._switch_to_block(0) self._switch_to_block(0)
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=1000)
def test_keyboard_help(self): def test_keyboard_help(self):
self._switch_to_block(0) self._switch_to_block(0)
...@@ -466,7 +471,7 @@ class MultipleBlocksDataInteraction(ParameterizedTestsMixin, InteractionTestBase ...@@ -466,7 +471,7 @@ class MultipleBlocksDataInteraction(ParameterizedTestsMixin, InteractionTestBase
self._switch_to_block(1) self._switch_to_block(1)
# Test mouse and keyboard interaction # Test mouse and keyboard interaction
self.interact_with_keyboard_help(scroll_down=1200) self.interact_with_keyboard_help(scroll_down=1000)
self.interact_with_keyboard_help(scroll_down=0, use_keyboard=True) self.interact_with_keyboard_help(scroll_down=0, use_keyboard=True)
...@@ -477,7 +482,7 @@ class ZoneAlignInteractionTest(InteractionTestBase, BaseIntegrationTest): ...@@ -477,7 +482,7 @@ class ZoneAlignInteractionTest(InteractionTestBase, BaseIntegrationTest):
""" """
PAGE_TITLE = 'Drag and Drop v2' PAGE_TITLE = 'Drag and Drop v2'
PAGE_ID = 'drag_and_drop_v2' PAGE_ID = 'drag_and_drop_v2'
ACTION_KEYS = (None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') ACTION_KEYS = ITEM_DRAG_KEYBOARD_KEYS
def setUp(self): def setUp(self):
super(ZoneAlignInteractionTest, self).setUp() super(ZoneAlignInteractionTest, self).setUp()
......
...@@ -7,6 +7,7 @@ from mock import Mock, patch ...@@ -7,6 +7,7 @@ from mock import Mock, patch
import time import time
import re import re
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
...@@ -18,7 +19,9 @@ from drag_and_drop_v2.default_data import ( ...@@ -18,7 +19,9 @@ from drag_and_drop_v2.default_data import (
) )
from drag_and_drop_v2.utils import FeedbackMessages, Constants from drag_and_drop_v2.utils import FeedbackMessages, Constants
from .test_base import BaseIntegrationTest from .test_base import BaseIntegrationTest
from .test_interaction import InteractionTestBase, DefaultDataTestMixin, ParameterizedTestsMixin, TestMaxItemsPerZone from .test_interaction import (
InteractionTestBase, DefaultDataTestMixin, ParameterizedTestsMixin, TestMaxItemsPerZone, ITEM_DRAG_KEYBOARD_KEYS
)
# Globals ########################################################### # Globals ###########################################################
...@@ -76,25 +79,25 @@ class AssessmentInteractionTest( ...@@ -76,25 +79,25 @@ class AssessmentInteractionTest(
All interactions are tested using mouse (action_key=None) and four different keyboard action keys. All interactions are tested using mouse (action_key=None) and four different keyboard action keys.
If default data changes this will break. If default data changes this will break.
""" """
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_item_no_feedback_on_good_move(self, action_key): def test_item_no_feedback_on_good_move(self, action_key):
self.parameterized_item_positive_feedback_on_good_move( self.parameterized_item_positive_feedback_on_good_move(
self.items_map, action_key=action_key, assessment_mode=True self.items_map, action_key=action_key, assessment_mode=True
) )
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_item_no_feedback_on_bad_move(self, action_key): def test_item_no_feedback_on_bad_move(self, action_key):
self.parameterized_item_negative_feedback_on_bad_move( self.parameterized_item_negative_feedback_on_bad_move(
self.items_map, self.all_zones, action_key=action_key, assessment_mode=True self.items_map, self.all_zones, action_key=action_key, assessment_mode=True
) )
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_move_items_between_zones(self, action_key): def test_move_items_between_zones(self, action_key):
self.parameterized_move_items_between_zones( self.parameterized_move_items_between_zones(
self.items_map, self.all_zones, action_key=action_key self.items_map, self.all_zones, action_key=action_key
) )
@data(None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m') @data(*ITEM_DRAG_KEYBOARD_KEYS)
def test_final_feedback_and_reset(self, action_key): def test_final_feedback_and_reset(self, action_key):
self.parameterized_final_feedback_and_reset( self.parameterized_final_feedback_and_reset(
self.items_map, self.feedback, action_key=action_key, assessment_mode=True self.items_map, self.feedback, action_key=action_key, assessment_mode=True
...@@ -159,7 +162,7 @@ class AssessmentInteractionTest( ...@@ -159,7 +162,7 @@ class AssessmentInteractionTest(
# Incorrect item remains placed # Incorrect item remains placed
def _assert_placed(item_id, zone_title): def _assert_placed(item_id, zone_title):
item = self._get_placed_item_by_value(item_id) item = self._get_placed_item_by_value(item_id)
item_description = item.find_element_by_css_selector('.sr') item_description = item.find_element_by_css_selector('.sr.description')
self.assertEqual(item_description.text, 'Placed in: {}'.format(zone_title)) self.assertEqual(item_description.text, 'Placed in: {}'.format(zone_title))
_assert_placed(1, TOP_ZONE_TITLE) _assert_placed(1, TOP_ZONE_TITLE)
...@@ -204,12 +207,13 @@ class AssessmentInteractionTest( ...@@ -204,12 +207,13 @@ class AssessmentInteractionTest(
self.assertEqual(item.get_attribute('class'), 'option fade') self.assertEqual(item.get_attribute('class'), 'option fade')
item_content = item.find_element_by_css_selector('.item-content') item_content = item.find_element_by_css_selector('.item-content')
item_description_id = '-item-{}-description'.format(item_definition.item_id) self.assertEqual(item_content.get_attribute('aria-describedby'), None)
self.assertEqual(item_content.get_attribute('aria-describedby'), item_description_id)
describedby_text = (u'Press "Enter", "Space", "Ctrl-m", or "⌘-m" on an item to select it for dropping, ' try:
'then navigate to the zone you want to drop it on.') item.find_element_by_css_selector('.sr.description')
self.assertEqual(item.find_element_by_css_selector('.sr').text, describedby_text) self.fail("Description element should not be present")
except NoSuchElementException:
pass
def test_show_answer(self): def test_show_answer(self):
""" """
......
...@@ -166,10 +166,7 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -166,10 +166,7 @@ class TestDragAndDropRender(BaseIntegrationTest):
def test_item_bank(self): def test_item_bank(self):
self.load_scenario() self.load_scenario()
item_bank = self._page.find_element_by_css_selector('.item-bank') item_bank = self._page.find_element_by_css_selector('.item-bank')
description = item_bank.find_element_by_css_selector('p.zone-description') self.assertEqual(item_bank.get_attribute("aria-label"), 'Item Bank')
self.assertEqual(description.text, 'Item Bank')
# Description should only be visible to screen readers:
self.assertEqual(description.get_attribute('class'), 'zone-description sr')
def test_zones(self): def test_zones(self):
self.load_scenario() self.load_scenario()
...@@ -216,12 +213,10 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -216,12 +213,10 @@ class TestDragAndDropRender(BaseIntegrationTest):
def test_keyboard_help(self): def test_keyboard_help(self):
self.load_scenario() self.load_scenario()
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 = keyboard_help_dialog.find_element_by_css_selector('.modal-window-overlay')
dialog_modal = keyboard_help_dialog.find_element_by_css_selector('.modal-window') 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_overlay.is_displayed())
self.assertFalse(dialog_modal.is_displayed()) self.assertFalse(dialog_modal.is_displayed())
self.assertEqual(dialog_modal.get_attribute('role'), 'dialog') self.assertEqual(dialog_modal.get_attribute('role'), 'dialog')
......
...@@ -14,7 +14,8 @@ disable= ...@@ -14,7 +14,8 @@ disable=
too-few-public-methods, too-few-public-methods,
too-many-public-methods, too-many-public-methods,
invalid-name, invalid-name,
no-member no-member,
star-args
[SIMILARITIES] [SIMILARITIES]
min-similarity-lines=4 min-similarity-lines=4
......
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