Skip to content

Include axe checks in user_views_branches_spec.rb feature test

What does this MR do and why?

  1. Adding accessibility checks to feature specs for Branches view
  2. Fixing listed errors
    1. A missing toggle text declared for "More action" menu trigger
    2. Switched ID to a class for multiple "Download" buttons
  3. Unifying the toggles for "More actions" menu triggers. There were present for most of the triggers, but missing in the main nav controls.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After
Failures:

  1) User views branches all branches default branch passes axe automated accessibility testing
     Got 1 failure and 1 other error:

     1.1) Failure/Error: expect(page).to be_axe_clean.within('#content-body')
          
            Found 1 accessibility violation:
          
            1) button-name: Buttons must have discernible text (critical)
                https://dequeuniversity.com/rules/axe/4.6/button-name?application=axeAPI
                The following 1 node violate this rule:
                
                    Selector: #dropdown-toggle-btn-40
                    HTML: <button id="dropdown-toggle-btn-40" data-testid="base-dropdown-toggle"
                           aria-controls="base-dropdown-43" aria-labelledby="dropdown-toggle-btn-40" type="button"
                           class="btn btn-default btn-md gl-button btn-default-tertiary gl-new-dropdown-toggle
                           gl-new-dropdown-icon-only gl-new-dropdown-toggle-no-caret">
                    Fix any of the following:
                    - Element does not have inner text that is visible to screen readers
                    - aria-label attribute does not exist or is empty
                    - aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
                    - Element has no title attribute
                    - Element's default semantics were not overridden with role="none" or role="presentation"
                    
            Invocation: axe.run({"include"=>[["#content-body"]]}, {}, callback);
          # ./spec/features/projects/branches/user_views_branches_spec.rb:34:in `block (4 levels) in <top (required)>'
          # ./spec/spec_helper.rb:448:in `block (3 levels) in <top (required)>'
          # ./spec/support/sidekiq_middleware.rb:18:in `with_sidekiq_server_middleware'
          # ./spec/spec_helper.rb:439:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:435:in `block (3 levels) in <top (required)>'
          # ./lib/gitlab/application_context.rb:66:in `with_raw_context'
          # ./spec/spec_helper.rb:435:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:271:in `block (2 levels) in <top (required)>'
          # ./spec/support/system_exit_detected.rb:7:in `block (2 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (3 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:60:in `with_cross_joins_prevented'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (2 levels) in <main>'

     1.2) Failure/Error: raise JSConsoleError, message
          
          JSConsoleError:
            Unexpected browser console output:
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///a+C/ 5:517 Uncaught TypeError: Invalid date
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///a+C/ 5:517 Uncaught TypeError: Invalid date
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///a+C/ 5:517 Uncaught TypeError: Invalid date
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
          # ./spec/support/capybara.rb:217:in `block (2 levels) in <main>'
          # ./spec/spec_helper.rb:448:in `block (3 levels) in <top (required)>'
          # ./spec/support/sidekiq_middleware.rb:18:in `with_sidekiq_server_middleware'
          # ./spec/spec_helper.rb:439:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:435:in `block (3 levels) in <top (required)>'
          # ./lib/gitlab/application_context.rb:66:in `with_raw_context'
          # ./spec/spec_helper.rb:435:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:271:in `block (2 levels) in <top (required)>'
          # ./spec/support/system_exit_detected.rb:7:in `block (2 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (3 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:60:in `with_cross_joins_prevented'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (2 levels) in <main>'

  2) User views branches all branches non-default branch passes axe automated accessibility testing
     Got 1 failure and 1 other error:

     2.1) Failure/Error: expect(page).to be_axe_clean.within('#content-body')
          
            Found 2 accessibility violations:
          
            1) button-name: Buttons must have discernible text (critical)
                https://dequeuniversity.com/rules/axe/4.6/button-name?application=axeAPI
                The following 1 node violate this rule:
                
                    Selector: #dropdown-toggle-btn-40
                    HTML: <button id="dropdown-toggle-btn-40" data-testid="base-dropdown-toggle"
                           aria-controls="base-dropdown-43" aria-labelledby="dropdown-toggle-btn-40" type="button"
                           class="btn btn-default btn-md gl-button btn-default-tertiary gl-new-dropdown-toggle
                           gl-new-dropdown-icon-only gl-new-dropdown-toggle-no-caret">
                    Fix any of the following:
                    - Element does not have inner text that is visible to screen readers
                    - aria-label attribute does not exist or is empty
                    - aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
                    - Element has no title attribute
                    - Element's default semantics were not overridden with role="none" or role="presentation"
                    
            2) duplicate-id: id attribute value must be unique (minor)
                https://dequeuniversity.com/rules/axe/4.6/duplicate-id?application=axeAPI
                The following 1 node violate this rule:
                
                    Selector: .js-branch-feature > .right-block.gl-justify-content-end.gl-align-items-center
                               > .project-action-button.dropdown.gl-dropdown >
                               .dropdown-menu.dropdown-menu-right[role="menu"] > div
                    HTML: <div data-links="[{&quot;text&quot;:&quot;zip&quot;,&quot;path&quot;:&quot;
                          /namespace1/project-1/-/archive/feature/project-1-feature.zip&quot;},
                          {&quot;text&quot;:&quot;tar.gz&quot;,&quot;path&quot;:&quot;/namespace1
                          /project-1/-/archive/feature/project-1-feature.tar.gz&quot;},
                          {&quot;text&quot;:&quot;tar.bz2&quot;,&quot;path&quot;:&quot;
                          /namespace1/project-1/-/archive/feature/project-1-feature.tar.bz2&quot;},
                          {&quot;text&quot;:&quot;tar&quot;,&quot;path&quot;:&quot;/namespace1
                          /project-1/-/archive/feature/project-1-feature.tar&quot;}]" 
                          id="js-directory-downloads">
                    Fix any of the following:
                    - Document has multiple static elements with the same id attribute: js-directory-downloads
                    
            Invocation: axe.run({"include"=>[["#content-body"]]}, {}, callback);
          # ./spec/features/projects/branches/user_views_branches_spec.rb:54:in `block (4 levels) in <top (required)>'
          # ./spec/spec_helper.rb:448:in `block (3 levels) in <top (required)>'
          # ./spec/support/sidekiq_middleware.rb:18:in `with_sidekiq_server_middleware'
          # ./spec/spec_helper.rb:439:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:435:in `block (3 levels) in <top (required)>'
          # ./lib/gitlab/application_context.rb:66:in `with_raw_context'
          # ./spec/spec_helper.rb:435:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:271:in `block (2 levels) in <top (required)>'
          # ./spec/support/system_exit_detected.rb:7:in `block (2 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (3 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:60:in `with_cross_joins_prevented'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (2 levels) in <main>'

     2.2) Failure/Error: raise JSConsoleError, message
          
          JSConsoleError:
            Unexpected browser console output:
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///a+C/ 5:517 Uncaught TypeError: Invalid date
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///a+C/ 5:517 Uncaught TypeError: Invalid date
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
            webpack-internal:///a+C/ 5:517 Uncaught TypeError: Invalid date
            webpack-internal:///Qog8 163:12 "[gl-modal]: Accessible name for modal missing. Please add title prop or aria-label." #comment
          # ./spec/support/capybara.rb:217:in `block (2 levels) in <main>'
          # ./spec/spec_helper.rb:448:in `block (3 levels) in <top (required)>'
          # ./spec/support/sidekiq_middleware.rb:18:in `with_sidekiq_server_middleware'
          # ./spec/spec_helper.rb:439:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:435:in `block (3 levels) in <top (required)>'
          # ./lib/gitlab/application_context.rb:66:in `with_raw_context'
          # ./spec/spec_helper.rb:435:in `block (2 levels) in <top (required)>'
          # ./spec/spec_helper.rb:271:in `block (2 levels) in <top (required)>'
          # ./spec/support/system_exit_detected.rb:7:in `block (2 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (3 levels) in <main>'
          # ./spec/support/database/prevent_cross_joins.rb:60:in `with_cross_joins_prevented'
          # ./spec/support/database/prevent_cross_joins.rb:106:in `block (2 levels) in <main>'

Finished in 49.44 seconds (files took 13.47 seconds to load)
7 examples, 2 failures

Failed examples:

rspec ./spec/features/projects/branches/user_views_branches_spec.rb:33
# User views branches all branches default branch passes axe automated accessibility testing
rspec ./spec/features/projects/branches/user_views_branches_spec.rb:53
# User views branches all branches non-default branch passes axe automated accessibility testing

All errors fixed 👍🏻

  1. A missing toggle text declared for "More action" menu trigger
  2. Switched ID to a class for multiple "Download" buttons

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

The pipeline should pass successfully.

To validate muanually:

  1. Download buttons that had ID, but now have a class, are preset on two views
    1. Go to Code > Repository and click Download button above the file list. Verify that you can download a selected format.
    2. Go to Code > Branches and click Download button for any branch on the list. Verify that you can download a selected format.
  2. Go to Code > Branches and turn on a. screen reader. Tab through the nav controls (filter search bar, View branch rules, New Branch, More actions trigger) and make sure that More actions is announced, when you reach the trigger. The tooltip with More actions should also show on hover.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #426232 (closed)

Edited by Paulina Sedlak-Jakubowska

Merge request reports