This commit is contained in:
Ilya Tregubov 2023-04-21 13:18:14 +08:00
commit 04bf346ca3
13 changed files with 124 additions and 30 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -217,6 +217,25 @@ export default class ColumnSearch extends GradebookSearchClass {
}
}
/**
* The handler for when a user presses a key within the component.
*
* @param {KeyboardEvent} e The triggering event that we are working with.
*/
async keyHandler(e) {
super.keyHandler(e);
// Switch the key presses to handle keyboard nav.
switch (e.key) {
case 'Tab':
if (e.target.closest(this.selectors.input)) {
e.preventDefault();
this.clearSearchButton.focus({preventScroll: true});
}
break;
}
}
/**
* Handle any keyboard inputs.
*/
@ -400,7 +419,10 @@ export default class ColumnSearch extends GradebookSearchClass {
} else if (content.classList.contains('d-none')) {
// We should always have content but some cells do not contain menus or other actions.
element.classList.remove('collapsed');
content.classList.add('d-flex');
// If there are many nodes, apply the following.
if (content.childNodes.length > 1) {
content.classList.add('d-flex');
}
nodeSet.forEach(node => {
node?.classList.remove('d-none');
node?.setAttribute('aria-hidden', 'false');
@ -454,6 +476,11 @@ export default class ColumnSearch extends GradebookSearchClass {
// Given we now have the body, we can set up more triggers.
this.registerFormEvents();
this.registerInputEvents();
// Add a small BS listener so that we can set the focus correctly on open.
this.$component.on('shown.bs.dropdown', () => {
this.searchInput.focus({preventScroll: true});
});
}
/**

View File

@ -198,6 +198,21 @@ export default class UserSearch extends GradebookSearchClass {
break;
}
break;
case 'Escape':
this.toggleDropdown();
this.searchInput.focus({preventScroll: true});
break;
case 'Tab':
// If the current focus is on clear search, then check if viewall exists then around tab to it.
if (e.target.closest(this.selectors.clearSearch)) {
if (this.currentViewAll && !e.shiftKey) {
e.preventDefault();
this.currentViewAll.focus({preventScroll: true});
} else {
this.closeSearch();
}
}
break;
}
}

View File

@ -366,6 +366,12 @@ export default class {
this.moveToNode(index + 1);
}
}
} else {
if (direction === UP) {
this.moveToLastNode();
} else {
this.moveToFirstNode();
}
}
}
@ -415,20 +421,7 @@ export default class {
e.preventDefault();
this.moveToLastNode();
break;
case 'Escape':
this.toggleDropdown();
this.searchInput.focus({preventScroll: true});
break;
case 'Tab':
// If the current focus is on clear search, then check if viewall exists then around tab to it.
if (e.target.closest(this.selectors.clearSearch)) {
if (this.currentViewAll && !e.shiftKey) {
e.preventDefault();
this.currentViewAll.focus({preventScroll: true});
} else {
this.closeSearch();
}
}
// If the current focus is on the view all link, then close the widget then set focus on the next tertiary nav item.
if (e.target.closest(this.selectors.viewall)) {
this.closeSearch();

View File

@ -42,7 +42,7 @@
{{/ core/search_input_auto }}
<form class="columnsdropdownform flex-column h-100">
<ul class="searchresultitemscontainer overflow-auto py-2 px-1 list-group mx-0 text-truncate" role="menu" data-region="search-result-items-container" tabindex="-1">
<ul class="searchresultitemscontainer overflow-auto py-2 px-1 list-group mx-0 text-truncate" role="listbox" data-region="search-result-items-container" tabindex="-1">
{{>gradereport_grader/collapse/collapseresults}}
</ul>
<div class="d-flex flex-row justify-content-end mt-2">

View File

@ -27,8 +27,8 @@
}
}}
<li class="w-100 result-row form-check mb-1" role="none">
<input class="form-check-input" data-collapse="{{name}}" type="checkbox" value="" id="check-{{name}}">
<label class="selected-option-info d-block pr-3 text-truncate form-check-label" for="check-{{name}}" role="menuitem" tabindex="-1" aria-label="{{#str}}viewresultsuser, gradereport_grader, {{displayName}}{{/str}}">
<input id="check-{{name}}-input" class="form-check-input" role="option" data-collapse="{{name}}" type="checkbox" value="" aria-labelledby="check-{{name}}">
<label id="check-{{name}}" class="selected-option-info d-block pr-3 text-truncate form-check-label" tabindex="-1" aria-label="{{#str}}viewresultsuser, gradereport_grader, {{displayName}}{{/str}}">
<span class="selected-option-text w-100 p-0">
{{displayName}}
</span>

View File

@ -112,9 +112,9 @@ Feature: Within the grader report, test that we can collapse columns
And I click on "Collapsed columns" "button"
# This is checking that the column name search dropdown exists.
When I wait until "Search collapsed columns" "field" exists
And I set the field "Test assignment one" in the "form" "gradereport_grader > collapse search" to "1"
And I set the field "Test assignment three" in the "form" "gradereport_grader > collapse search" to "1"
And I set the field "Phone" in the "form" "gradereport_grader > collapse search" to "1"
And I click on "Test assignment one" "option_role" in the "form" "gradereport_grader > collapse search"
And I click on "Test assignment three" "option_role" in the "form" "gradereport_grader > collapse search"
And I click on "Phone" "option_role" in the "form" "gradereport_grader > collapse search"
And I click on "Expand" "button" in the "form" "gradereport_grader > collapse search"
Then I should see "Test assignment one" in the "First name / Last name" "table_row"
And I should see "Test assignment three" in the "First name / Last name" "table_row"
@ -173,10 +173,68 @@ Feature: Within the grader report, test that we can collapse columns
@accessibility
Scenario: A teacher can manipulate the report display in an accessible way
# Hide a bunch of columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone1"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone2"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Basic tests for the page.
Given the page should meet accessibility standards
When the page should meet "wcag131, wcag141, wcag412" accessibility standards
Then the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
When the page should meet accessibility standards
And the page should meet "wcag131, wcag141, wcag412" accessibility standards
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
# Move onto general keyboard navigation testing.
Then I click on "Collapsed columns" "button"
And the focused element is "Search collapsed columns" "field"
And I press the down key
And the focused element is "Email address" "option_role"
And I press the end key
And the focused element is "Country" "option_role"
And I press the home key
And the focused element is "Email address" "option_role"
And I press the up key
And the focused element is "Country" "option_role"
And I press the down key
And the focused element is "Email address" "option_role"
And I press the escape key
And the focused element is "Collapsed columns" "button"
And I click on "Collapsed columns" "button"
Then I set the field "Search collapsed columns" to "Goodmeme"
And I wait until "No results for \"Goodmeme\"" "text" exists
And I press the down key
And the focused element is "Search collapsed columns" "field"
# Lets check the tabbing order.
And I set the field "Search collapsed columns" to "phone"
And I wait until "Mobile phone" "option_role" exists
And I press the tab key
And the focused element is "Clear search input" "button" in the ".dropdown-menu.show" "css_element"
And I press the tab key
And I press the tab key
And I press the tab key
And the focused element is "Close" "button" in the ".dropdown-menu.show" "css_element"
And I press the tab key
# The course grade category menu.
And the focused element is "Cell actions" "button"
# Tab over to the collapsed columns.
And I click on user profile field menu "city"
And I press the escape key
And I press the tab key
And the focused element is "Reopen country column" "button"
And I press the enter key
And I press the tab key
And the focused element is "Reopen phone1 column" "button"
And I press the enter key
And I should not see "Email" in the "First name / Last name" "table_row"
And I should see "Phone" in the "First name / Last name" "table_row"
And I should not see "Mobile phone" in the "First name / Last name" "table_row"
And I should see "Country" in the "First name / Last name" "table_row"
# Ensure that things did not start failing after we did some manipulation.
And the page should meet accessibility standards
And the page should meet "wcag131, wcag141, wcag412" accessibility standards
And the page should meet accessibility standards with "wcag131, wcag141, wcag412" extra tests
Scenario: Collapsed columns persist across paginated pages
# Hide a bunch of columns.

View File

@ -220,7 +220,8 @@ XPATH
.//*[@role='menuitem'][%titleMatch% or %ariaLabelMatch% or text()[contains(., %locator%)]]
XPATH
, 'option_role' => <<<XPATH
.//*[@role='option'][%titleMatch% or %ariaLabelMatch% or text()[contains(., %locator%)]]
.//*[@role='option'][%titleMatch% or %ariaLabelMatch% or text()[contains(., %locator%)]] |
.//*[@role='option']/following-sibling::label[contains(., %locator%)]/preceding-sibling::input
XPATH
, 'question' => <<<XPATH
.//div[contains(concat(' ', normalize-space(@class), ' '), ' que ')]