diff --git a/grade/report/grader/index.php b/grade/report/grader/index.php index 8a9b32feb33bc..f4aadb93813cf 100644 --- a/grade/report/grader/index.php +++ b/grade/report/grader/index.php @@ -109,14 +109,14 @@ $reportname = get_string('pluginname', 'gradereport_grader'); +// Do this check just before printing the grade header (and only do it once). +grade_regrade_final_grades_if_required($course); + //Initialise the grader report object that produces the table //the class grade_report_grader_ajax was removed as part of MDL-21562 $report = new grade_report_grader($courseid, $gpr, $context, $page, $sortitemid); $numusers = $report->get_numusers(true, true); -// Do this check just before printing the grade header (and only do it once). -grade_regrade_final_grades_if_required($course); - $actionbar = new \gradereport_grader\output\action_bar($context, $report, $numusers); print_grade_page_head($COURSE->id, 'report', 'grader', $reportname, false, $buttons, true, null, null, null, $actionbar); diff --git a/grade/report/grader/tests/behat/ajax_grader.feature b/grade/report/grader/tests/behat/ajax_grader.feature index e90259cd5bbf6..f462e17c46891 100644 --- a/grade/report/grader/tests/behat/ajax_grader.feature +++ b/grade/report/grader/tests/behat/ajax_grader.feature @@ -1,4 +1,4 @@ -@gradereport @gradereport_grader +@gradereport @gradereport_grader @javascript Feature: Using the AJAX grading feature of Grader report to update grades and feedback In order to use AJAX grading As a teacher @@ -7,10 +7,10 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe Background: Given the following "courses" exist: | fullname | shortname | category | groupmode | - | Course 1 | C1 | 0 | 1 | + | Course 1 | C1 | 0 | 1 | And the following "custom profile fields" exist: - | datatype | shortname | name | - | text | frog | Favourite frog | + | datatype | shortname | name | + | text | frog | Favourite frog | And the following "users" exist: | username | firstname | lastname | email | idnumber | profile_field_frog | | teacher1 | Teacher | 1 | teacher1@example.com | t1 | | @@ -18,11 +18,11 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe | student2 | Student | 2 | student2@example.com | s2 | prince frog | | student3 | Student | 3 | student3@example.com | s3 | | And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - | student3 | C1 | student | + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | student3 | C1 | student | And the following "scales" exist: | name | scale | | Test Scale | Disappointing,Good,Very good,Excellent | @@ -50,7 +50,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe | grade_report_showaverages | 0 | | grade_report_enableajax | 1 | - @javascript Scenario: Use the grader report without editing, with AJAX on and quick feedback off When the following config values are set as admin: | grade_overridecat | 1 | @@ -105,7 +104,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe | Student 2 | - | 33.00 | - | 33.00 | | Student 3 | 80.00 | 50.00 | Very good | 133.00 | - @javascript Scenario: Use the grader report without editing, with AJAX and quick feedback on When the following config values are set as admin: | grade_overridecat | 1 | @@ -143,7 +141,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe And I click on student "Student 2" for grade item "Item SU" And the field "ajaxfeedback" matches value "Student 2 SU feedback" - @javascript Scenario: Use the grader report without editing, with AJAX and quick feedback on, without category override When the following config values are set as admin: | grade_overridecat | 0 | @@ -164,7 +161,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe | -1- | -7- | -16- | | Student 2 | 33.00 | 33.00 | - @javascript Scenario: Use the grader report with editing, with AJAX and quick feedback on, with category override When the following config values are set as admin: | grade_overridecat | 1 | @@ -195,7 +191,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe And I click on student "Student 2" for grade item "Item 1" And the field "ajaxfeedback" matches value "Some feedback" - @javascript Scenario: Use the grader report with editing, with AJAX and quick feedback on, without category override When the following config values are set as admin: | grade_overridecat | 0 | @@ -243,7 +238,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe And I click on student "Student 2" for grade item "Item 1" And the field "ajaxfeedback" matches value "Some feedback" - @javascript Scenario: Teacher can see an error when an incorrect grade is given using the grader report with editing and AJAX on Given I log in as "teacher1" And I am on "Course 1" course homepage @@ -258,7 +252,6 @@ Feature: Using the AJAX grading feature of Grader report to update grades and fe And I should not see "The grade entered for Item VU for Student 2 is more than the maximum allowed" And the grade for "Student 2" in grade item "Item VU" should match "66.00" - @javascript Scenario: Teacher can see user custom filed columns as additional user identity Given the following config values are set as admin: | showuseridentity | email,profile_field_frog | diff --git a/grade/report/grader/tests/behat/tertiary_name_filter.feature b/grade/report/grader/tests/behat/tertiary_name_filter.feature new file mode 100644 index 0000000000000..2ca502a2bd5e5 --- /dev/null +++ b/grade/report/grader/tests/behat/tertiary_name_filter.feature @@ -0,0 +1,165 @@ +@core @javascript @gradereport_grader +Feature: Within the grader report, test that we can open our generic filter dropdown component + In order to filter down the users on the page + As a teacher + I need to be able to see the filter and select a combination of parameters + + Background: + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "users" exist: + | username | firstname | lastname | email | idnumber | + | teacher1 | Teacher | 1 | teacher1@example.com | t1 | + | student1 | Student | 1 | student1@example.com | s1 | + | student2 | Dummy | User | student2@example.com | s2 | + | student3 | User | Example | student3@example.com | s3 | + | student4 | User | Test | student4@example.com | s4 | + | student5 | Turtle | Manatee | student5@example.com | s5 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + | student3 | C1 | student | + | student4 | C1 | student | + | student5 | C1 | student | + And the following "activities" exist: + | activity | course | idnumber | name | + | assign | C1 | a1 | Test assignment one | + And I am on the "Course 1" "Course" page logged in as "teacher1" + And I change window size to "large" + And I navigate to "View > Grader report" in the course gradebook + + Scenario: A teacher can open the filter component + Given I should see "Filter by name" + When I press "Filter by name" + Then I should see "27" node occurrences of type "input" in the "First name" "core_grades > initials bar" + And I should see "27" node occurrences of type "input" in the "Surname" "core_grades > initials bar" + And "input[data-action=cancel]" "css_element" should exist + And "input[data-action=save]" "css_element" should exist + + Scenario: A teacher can filter the grader report to limit users reported + Given I press "Filter by name" + And I wait until "input[data-action=save]" "css_element" exists + When I select "D" in the "First name" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + # We should only have one user that matches the "D" first name + Then the following should exist in the "user-grades" table: + | -1- | + | Dummy User | + And the following should not exist in the "user-grades" table: + | -1- | + | Teacher 1 | + | Student 1 | + | User Example | + | User Test | + | Turtle Manatee | + + # Test filtering on last name + # Business logic: If all is selected, we will not show it i.e. First (D) and NOT First (D) Last (All) + And I press "First (D)" + And I select "All" in the "First name" "core_grades > initials bar" + And I select "M" in the "Surname" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + # We should only have one user that matches the "T" first name + And the following should exist in the "user-grades" table: + | -1- | + | Turtle Manatee | + And the following should not exist in the "user-grades" table: + | -1- | + | Teacher 1 | + | Student 1 | + | User Example | + | User Test | + | Dummy User | + + # Test filtering on first && last name + And I press "Last (M)" + And I select "U" in the "First name" "core_grades > initials bar" + And I select "T" in the "Surname" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + # We should only have one user that matches the "T" first name + And the following should exist in the "user-grades" table: + | -1- | + | User Test | + And the following should not exist in the "user-grades" table: + | -1- | + | Teacher 1 | + | Student 1 | + | User Example | + | Dummy User | + | Turtle Manatee | + # Final cheeky check to ensure our button matches. + And I press "First (U) Last (T)" + + Scenario: A teacher can quickly tell that a filter is applied to the current table + Given I press "Filter by name" + And I wait until "input[data-action=save]" "css_element" exists + When I select "T" in the "First name" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + Then I should see "First (T)" + + # Check if removing the filter, removes the highlight and user notice of applied filters + And I press "First (T)" + And I wait until "input[data-action=save]" "css_element" exists + And I select "All" in the "First name" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + # Check if the name button indicates if a filter is active + And I should see "Filter by name" + And I should not see "First (T)" + + Scenario: A teacher can close the filter either by clicking close or clicking off the dropdown + Given I press "Filter by name" + And "input[data-action=save]" "css_element" should be visible + When I click on "input[data-action=cancel]" "css_element" + Then "input[data-action=save]" "css_element" should not be visible + + # Click off the drop down + And I press "Filter by name" + And "input[data-action=save]" "css_element" should be visible + And I click on "First name" "link" in the "gradereport-grader-table" "table" + And "input[data-action=save]" "css_element" should not be visible + + Scenario: A teacher using a language besides english can reset the initials bar + Given the following "language customisations" exist: + | component | stringid | value | + | core | all | すべて | + And I press "Filter by name" + And "input[data-action=save]" "css_element" should be visible + And I select "T" in the "First name" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + And I press "First (T)" + And I wait until "input[data-action=save]" "css_element" exists + + When I select "すべて" in the "First name" "core_grades > initials bar" + And I press "Apply" + And I wait to be redirected + Then I should not see "First (すべて) Last (すべて)" + And the following should exist in the "user-grades" table: + | -1- | + | Dummy User | + | Student 1 | + | User Example | + | User Test | + | Turtle Manatee | + + # This can be expanded for left/right/home & end keys but will have to be done in conjunction with the non mini render. + @accessibility + Scenario: A teacher can set focus and navigate the filter with the keyboard + Given 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 + And I press "Filter by name" + And "input[data-action=save]" "css_element" should be visible + And the focused element is "All" "button" in the "First name" "core_grades > initials bar" + When I press the tab key + Then the focused element is "input[value=A]" "css_element" in the "First name" "core_grades > initials bar" + And I press the tab key + And the focused element is "input[value=B]" "css_element" in the "First name" "core_grades > initials bar" diff --git a/grade/tests/behat/behat_grades.php b/grade/tests/behat/behat_grades.php new file mode 100644 index 0000000000000..6aa9dc92ea389 --- /dev/null +++ b/grade/tests/behat/behat_grades.php @@ -0,0 +1,58 @@ +. + +// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. + +require_once(__DIR__ . '/../../../lib/behat/behat_base.php'); + +/** + * Behat grade related steps definitions. + * + * @package core_grades + * @copyright 2022 Mathew May + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class behat_grades extends behat_base { + + /** + * Return the list of partial named selectors. + * + * @return array + */ + public static function get_partial_named_selectors(): array { + return [ + new behat_component_named_selector( + 'initials bar', + [".//*[contains(concat(' ', @class, ' '), ' initialbar ')]//span[contains(., %locator%)]/parent::div"] + ), + ]; + } + + /** + * Select a given element within a specific container instance. + * + * @Given /^I select "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" "(?P(?:[^"]|\\")*)"$/ + * @param string $value The Needle + * @param string $element The Haystack to select within + * @param string $selectortype What type of haystack we are looking in + */ + public function i_select_in_the($value, $element, $selectortype) { + // Getting the container where the text should be found. + $container = $this->get_selected_node($selectortype, $element); + $node = $this->find('xpath', './/input[@value="' . $value . '"]', false, $container); + $node->click(); + } +} diff --git a/grade/tests/behat/grade_aggregation.feature b/grade/tests/behat/grade_aggregation.feature index c7508f0893026..8c02e87f050fa 100644 --- a/grade/tests/behat/grade_aggregation.feature +++ b/grade/tests/behat/grade_aggregation.feature @@ -41,9 +41,8 @@ Feature: We can use calculated grade totals | grade_aggregations_visible | Mean of grades,Weighted mean of grades,Simple weighted mean of grades,Mean of grades (with extra credits),Median of grades,Lowest grade,Highest grade,Mode of grades,Natural | And I log out And I log in as "teacher1" - And I am on "Course 1" course homepage + And I am on "Course 1" course homepage with editing mode on And I navigate to "View > Grader report" in the course gradebook - And I turn editing mode on And I change window size to "large" And I give the grade "60.00" to the user "Student 1" for the grade item "Test assignment one &" And I give the grade "20.00" to the user "Student 1" for the grade item "Test assignment two" diff --git a/lib/tests/behat/alpha_chooser.feature b/lib/tests/behat/alpha_chooser.feature index 4de5a10c4941b..5cb2afde76322 100644 --- a/lib/tests/behat/alpha_chooser.feature +++ b/lib/tests/behat/alpha_chooser.feature @@ -119,6 +119,7 @@ Feature: Initials bar And I should see "Bstudent Astudent" And I should see "Cstudent Cstudent" + @javascript Scenario: Filter users on view gradebook page Given the following "activities" exist: | activity | course | idnumber | name | intro | assignsubmission_onlinetext_enabled | assignsubmission_file_enabled | @@ -126,6 +127,7 @@ Feature: Initials bar And I am on the "assign1" "Activity" page logged in as "teacher" When I follow "View all submissions" And I select "View gradebook" from the "jump" singleselect + And I press "Filter by name" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.lastinitial" "css_element" And ".page-item.active.B" "css_element" should not exist in the ".initialbar.firstinitial" "css_element" @@ -133,15 +135,19 @@ Feature: Initials bar And I should see "Astudent Astudent" And I should see "Bstudent Astudent" And I should see "Cstudent Cstudent" - And I click on "A" "link" in the ".initialbar.lastinitial .page-item.A" "css_element" + And I select "A" in the "Surname" "core_grades > initials bar" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should not exist in the ".initialbar.lastinitial" "css_element" And ".page-item.active.B" "css_element" should not exist in the ".initialbar.firstinitial" "css_element" And ".page-item.active.A" "css_element" should exist in the ".initialbar.lastinitial" "css_element" + And I press "Apply" And I should see "Astudent Astudent" And I should see "Bstudent Astudent" And I should not see "Cstudent Cstudent" - And I click on "B" "link" in the ".initialbar.firstinitial .page-item.B" "css_element" + And I press "Last (A)" + And I select "B" in the "First name" "core_grades > initials bar" + And I press "Apply" + And I wait until the page is ready And ".initialbarall.page-item.active" "css_element" should not exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should not exist in the ".initialbar.lastinitial" "css_element" And ".page-item.active.B" "css_element" should exist in the ".initialbar.firstinitial" "css_element" @@ -159,19 +165,25 @@ Feature: Initials bar And I should not see "Astudent Astudent" And I should see "Bstudent Astudent" And I should not see "Cstudent Cstudent" - And I click on "All" "link" in the ".initialbar.firstinitial" "css_element" + And I press "First (B) Last (A)" + And I select "All" in the "First name" "core_grades > initials bar" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should not exist in the ".initialbar.lastinitial" "css_element" And ".page-item.active.B" "css_element" should not exist in the ".initialbar.firstinitial" "css_element" And ".page-item.active.A" "css_element" should exist in the ".initialbar.lastinitial" "css_element" + And I press "Apply" + And I wait until the page is ready And I should see "Astudent Astudent" And I should see "Bstudent Astudent" And I should not see "Cstudent Cstudent" - And I click on "All" "link" in the ".initialbar.lastinitial" "css_element" + And I press "Last (A)" + And I select "All" in the "Surname" "core_grades > initials bar" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.firstinitial" "css_element" And ".initialbarall.page-item.active" "css_element" should exist in the ".initialbar.lastinitial" "css_element" And ".page-item.active.B" "css_element" should not exist in the ".initialbar.firstinitial" "css_element" And ".page-item.active.A" "css_element" should not exist in the ".initialbar.lastinitial" "css_element" + And I press "Apply" + And I wait until the page is ready And I should see "Astudent Astudent" And I should see "Bstudent Astudent" And I should see "Cstudent Cstudent" diff --git a/lib/tests/behat/behat_general.php b/lib/tests/behat/behat_general.php index dbce60b922d49..6852f44ffc584 100644 --- a/lib/tests/behat/behat_general.php +++ b/lib/tests/behat/behat_general.php @@ -2155,6 +2155,39 @@ public function i_should_see_occurrences_of_in_element($elementscount, $text, $e } } + /** + * Checks, that the specified element contains the specified node type a certain amount of times. + * When running Javascript tests it also considers that texts may be hidden. + * + * @Then /^I should see "(?P\d+)" node occurrences of type "(?P(?:[^"]|\\")*)" in the "(?P(?:[^"]|\\")*)" "(?P[^"]*)"$/ + * @throws ElementNotFoundException + * @throws ExpectationException + * @param int $elementscount How many occurrences of the element we look for. + * @param string $nodetype + * @param string $element Element we look in. + * @param string $selectortype The type of element where we are looking in. + */ + public function i_should_see_node_occurrences_of_type_in_element(int $elementscount, string $nodetype, string $element, string $selectortype) { + + // Getting the container where the text should be found. + $container = $this->get_selected_node($selectortype, $element); + + $xpath = "/descendant-or-self::$nodetype [count(descendant::$nodetype) = 0]"; + + $nodes = $this->find_all('xpath', $xpath, false, $container); + + if ($this->running_javascript()) { + $nodes = array_filter($nodes, function($node) { + return $node->isVisible(); + }); + } + + if ($elementscount != count($nodes)) { + throw new ExpectationException('Found '.count($nodes).' elements in column. Expected '.$elementscount, + $this->getSession()); + } + } + /** * Manually press enter key. * diff --git a/lib/tests/behat/filter_component.feature b/lib/tests/behat/filter_component.feature deleted file mode 100644 index 3fdb10b194dc8..0000000000000 --- a/lib/tests/behat/filter_component.feature +++ /dev/null @@ -1,163 +0,0 @@ -@core @javascript -Feature: Within the grader report, test that we can open our generic filter dropdown component - In order to filter down the users on the page - As a teacher - I need to be able to see the filter and select a combination of parameters - - Background: - Given the following "courses" exist: - | fullname | shortname | category | groupmode | - | Course 1 | C1 | 0 | 1 | - And the following "users" exist: - | username | firstname | lastname | email | idnumber | - | teacher1 | Teacher | 1 | teacher1@example.com | t1 | - | student1 | Student | 1 | student1@example.com | s1 | - | student2 | Dummy | User | student2@example.com | s2 | - | student3 | User | Example | student3@example.com | s3 | - | student4 | User | Test | student4@example.com | s4 | - | student5 | Turtle | Manatee | student5@example.com | s5 | - And the following "course enrolments" exist: - | user | course | role | - | teacher1 | C1 | editingteacher | - | student1 | C1 | student | - | student2 | C1 | student | - | student3 | C1 | student | - | student4 | C1 | student | - | student5 | C1 | student | - And the following "activities" exist: - | activity | course | idnumber | name | - | assign | C1 | a1 | Test assignment one | - And I am on the "Course 1" "Course" page logged in as "teacher1" - And I change window size to "large" - And I navigate to "View > Grader report" in the course gradebook - - Scenario: A teacher can open the filer component - Given I should see "Name" "button" - When I press "Name" - # Meeting outcome: We will use a placeholder pulse pattern. - # And I wait until "pulsing placholder" "css_element" exists - # And I wait until "Apply filter" "button" exists - # Meeting outcome: "All" option will still exist for the time being, with the followup of toggling active nodes to disable filter - # Meeting outcome: Deferred for later in the release after A+B testing done in-house. - And I should see "A loading spinner" - And I wait until "Apply filter" "button" exists - # https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/ - Then I should see "27" occurrences of "Filter option" in the "First name" "Tool bar" - And I should see "27" occurrences of "Filter option" in the "Last name" "Tool bar" - # Meeting outcome: Upon selection, the table should update like the participants filter - # Given the above meeting outcome, This button will likely not need to exist - And I should see "Close" "button" - And I should see "Apply filter" "button" - - # We need to decide if we want the page to reload or if the page content reloads like in the Course participants filters - Scenario: A teacher can filter the grader report to limit users reported - Given I press "Name" - And I wait until "Apply filter" "button" exists - When I select "D" in the "First name" "Toolbar" - And I press "Apply filter" - # Assuming we close the dropdown once filter is applied - And I wait until "Apply filter" "Button" does not exist - # We should only have one user that matches the "D" first name - Then the following should exist in the "user-grades" table: - | -1- | - | Dummy User | - # All other users should not be shown to the user based on filtering - And the following should not exist in the "user-grades" table: - | -1- | - | Teacher 1 | - | Student 1 | - | User Example | - | User Test | - | Turtle Manatee | - - # Test filtering on last name - # Meeting outcome: Indication will be: First(T) - # Meeting outcome: If all is selected, we will not show it i.e. First (D) and NOT First (D) Last (All) - And I press "First (D)" - And I select "All" in the "First name" "Toolbar" - And I select "M" in the "Last name" "Toolbar" - And I press "Apply filter" - # Assuming we close the dropdown once filter is applied - And I wait until "Apply filter" "Button" does not exist - And I should see "First (U) Last(T)" "button" - # We should only have one user that matches the "T" first name - And the following should exist in the "user-grades" table: - | -1- | - | Turtle Manatee | - # All other users should not be shown to the user based on filtering - And the following should not exist in the "user-grades" table: - | -1- | - | Teacher 1 | - | Student 1 | - | User Example | - | User Test | - | Dummy User | - - # Test filtering on first && last name - And I press "Name" - And I select "U" in the "First name" "Toolbar" - And I select "T" in the "Last name" "Toolbar" - And I press "Apply filter" - # Assuming we close the dropdown once filter is applied - And I wait until "Apply filter" "Button" does not exist - # We should only have one user that matches the "T" first name - And the following should exist in the "user-grades" table: - | -1- | - | User Test | - # All other users should not be shown to the user based on filtering - And the following should not exist in the "user-grades" table: - | -1- | - | Teacher 1 | - | Student 1 | - | User Example | - | Dummy User | - | Turtle Manatee | - - Scenario: A teacher can quickly tell that a filter is applied to the current table - Given I press "Name" - And I wait until "Apply filter" "button" exists - When I select "T" in the "First name" "Toolbar" - And I press "Apply filter" - # Assuming we close the dropdown once filter is applied - And I wait until "Apply filter" "Button" does not exist - # Check if the name button indicates if a filter is active - Then I should see "First (T)" - # Meeting outcome: No decision yet if we alter the colors / active state / focus state - And I should see that "Name (T)" "button" is highlighted - - # Check if removing the filter, removes the highlight and user notice of applied filters - And I press "First (T)" - And I wait until "Apply filter" "button" exists - And I select "All" in the "First name" "Toolbar" - And I press "Apply filter" - # Assuming we close the dropdown once filter is applied - And I wait until "Apply filter" "Button" does not exist - # Check if the name button indicates if a filter is active - And I should see "Name" - # Meeting outcome: We do not show First(All) Last(All) - And I should not see "First (T)" - And I should not see that "Name" "button" is highlighted - - Scenario: A teacher can close the filter either by clicking close or clicking off the dropdown - # Meeting outcome: We would like this report to act like the participants filter page with the dynamic table - # Meeting outcome: Should we save state of user input when clicking off or click close?: - Maybe not needed? based on if we were to filter instantly on the user selection like we do in the participants page. - Given I press "Name" - And I wait until "Apply filter" "button" exists - When I press "Close" - Then I should not see "Apply filter" - - # Click off the drop down - And I press "Name" - And I wait until "Apply filter" "button" exists - And I click on "First name" "link" in the "gradereport-grader-table" "table" - And I should not see "Apply filter" - - # This can be expanded for left/right/up/down/home & end keys - Scenario: A teacher can set focus and navigate the filter with the keyboard - Given I press "Name" - And I wait until "Apply filter" "button" exists - And the focused element is "All" "button" in the "First name" "Toolbar" - When I press the right key - Then the focused element is "A" "button" in the "First name" "Toolbar" - And I press the tab key - And the focused element is "All" "button" in the "Last name" "Toolbar"