diff --git a/Gemfile.lock b/Gemfile.lock index b130c77..1754b8d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - erblint-github (0.2.1) + erblint-github (0.3.0) GEM remote: https://rubygems.org/ @@ -43,14 +43,14 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.5.9) mini_portile2 (2.8.1) - minitest (5.17.0) + minitest (5.18.0) mocha (2.0.2) ruby2_keywords (>= 0.0.5) nokogiri (1.14.0) mini_portile2 (~> 2.8.0) racc (~> 1.4) parallel (1.22.1) - parser (3.2.0.0) + parser (3.2.2.0) ast (~> 2.4.1) racc (1.6.2) rack (3.0.4.1) @@ -61,32 +61,32 @@ GEM loofah (~> 2.19, >= 2.19.1) rainbow (3.1.1) rake (13.0.6) - regexp_parser (2.6.2) + regexp_parser (2.7.0) rexml (3.2.5) - rubocop (1.44.1) + rubocop (1.49.0) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.24.1, < 2.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.24.1) - parser (>= 3.1.1.0) + rubocop-ast (1.28.0) + parser (>= 3.2.1.0) rubocop-github (0.20.0) rubocop (>= 1.37) rubocop-performance (>= 1.15) rubocop-rails (>= 2.17) - rubocop-performance (1.15.2) + rubocop-performance (1.16.0) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) rubocop-rails (2.17.4) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) - ruby-progressbar (1.11.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) smart_properties (1.17.0) tzinfo (2.0.5) @@ -99,10 +99,10 @@ PLATFORMS DEPENDENCIES erb_lint (~> 0.3.0) erblint-github! - minitest (~> 5.17.0) + minitest (~> 5.18.0) mocha (~> 2.0.2) rake (~> 13.0.6) - rubocop (= 1.44.1) + rubocop (= 1.49.0) rubocop-github (~> 0.20.0) BUNDLED WITH diff --git a/README.md b/README.md index af7e20a..597f023 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ require "erblint-github/linters" ```yaml --- linters: + GitHub::Accessibility::AriaLabelIsWellFormatted: + enabled: true GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled: enabled: true GitHub::Accessibility::AvoidGenericLinkText: @@ -33,7 +35,7 @@ linters: enabled: true GitHub::Accessibility::ImageHasAlt: enabled: true - GitHub::Accessibility::LandmarkHasLabel: + GitHub::Accessibility::NavigationHasLabel: enabled: true GitHub::Accessibility::LinkHasHref: enabled: true @@ -55,10 +57,11 @@ linters: ## Rules +- [GitHub::Accessibility::AriaLabelIsWellFormatted](./docs/rules/accessibility/aria-label-is-well-formatted.md) - [GitHub::Accessibility::AvoidBothDisabledAndAriaDisabled](./docs/rules/accessibility/avoid-both-disabled-and-aria-disabled.md) - [GitHub::Accessibility::AvoidGenericLinkText](./docs/rules/accessibility/avoid-generic-link-text.md) - [GitHub::Accessibility::DisabledAttribute](./docs/rules/accessibility/disabled-attribute.md) -- [GitHub::Accessibility::LandmarkHasLabel](./docs/rules/accessibility/landmark-has-label.md) +- [GitHub::Accessibility::NavigationHasLabel](./docs/rules/accessibility/navigation-has-label.md) - [GitHub::Accessibility::LinkHasHref](./docs/rules/accessibility/link-has-href.md) - [GitHub::Accessibility::NestedInteractiveElements](./docs/rules/accessibility/nested-interactive-elements.md) - [GitHub::Accessibility::IframeHasTitle](./docs/rules/accessibility/iframe-has-title.md) diff --git a/docs/rules/accessibility/aria-label-is-well-formatted.md b/docs/rules/accessibility/aria-label-is-well-formatted.md new file mode 100644 index 0000000..e8fc344 --- /dev/null +++ b/docs/rules/accessibility/aria-label-is-well-formatted.md @@ -0,0 +1,46 @@ +# aria-label is well formatted + +## Rule Details + +`[aria-label]` content should be formatted in the same way you would visual text. Please use sentence case. + +Do not kebab case the words like you would an HTML ID. An `aria-label` is different from `aria-labelledby`. +An `aria-label` is not an ID, and should be formatted as human-friendly text. + +## Config + +If you determine that there are valid scenarios for `aria-label` to start with lowercase, you may exempt it in your `.erb-lint.yml` config like so: + +```yml + GitHub::Accessibility::AriaLabelIsWellFormatted: + enabled: true + exceptions: + - allowed for some reason + - also allowed for some reason +``` + +## Examples + +### **Incorrect** code for this rule 👎 + +```erb + + + + + HTML + @linter.run(processed_source) + + assert_equal 4, @linter.offenses.count + end + + def test_does_not_warn_when_aria_labelledby_starts_with_downcase + @file = " + + + HTML + @linter.run(processed_source) + + assert_empty @linter.offenses + end + + def test_does_not_warn_when_aria_label_is_excepted_in_config + @file = <<~HTML + + + + HTML + @linter.run(processed_source) + + assert_empty @linter.offenses + end + + + def test_does_not_warn_if_aria_label_is_in_excepted_list + @file = <<~HTML + + + HTML + @linter.config.exceptions = ["hello"] + @linter.run(processed_source) + + assert_equal 1, @linter.offenses.count + end +end diff --git a/test/linters/accessibility/landmark_has_label_test.rb b/test/linters/accessibility/landmark_has_label_test.rb deleted file mode 100644 index 7fa64be..0000000 --- a/test/linters/accessibility/landmark_has_label_test.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -require "test_helper" - -class LandmarkHasLabelTest < LinterTestCase - def linter_class - ERBLint::Linters::GitHub::Accessibility::LandmarkHasLabel - end - - def test_warns_if_landmark_has_no_label - @file = <<~ERB -
-

This is a text

-
- ERB - @linter.run(processed_source) - - assert_equal(1, @linter.offenses.count) - error_messages = @linter.offenses.map(&:message).sort - assert_match(/Landmark elements should have an aria-label attribute, or aria-labelledby if a heading elements exists in the landmark./, error_messages.last) - end - - def test_does_not_warn_if_landmark_has_label - @file = <<~ERB -
-

This is a text

-
- ERB - @linter.run(processed_source) - - assert_empty @linter.offenses - end -end diff --git a/test/linters/accessibility/navigation_has_label_test.rb b/test/linters/accessibility/navigation_has_label_test.rb new file mode 100644 index 0000000..6e4445e --- /dev/null +++ b/test/linters/accessibility/navigation_has_label_test.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "test_helper" + +class NavigationHasLabelTest < LinterTestCase + def linter_class + ERBLint::Linters::GitHub::Accessibility::NavigationHasLabel + end + + def test_warns_if_navigation_landmark_has_no_label + @file = <<~ERB + + ERB + @linter.run(processed_source) + + assert_equal(1, @linter.offenses.count) + assert_match(/The navigation landmark should have a unique accessible name via `aria-label` or `aria-labelledby`./, @linter.offenses.first.message) + end + + def test_warns_if_navigation_role_landmark_has_no_label + @file = <<~ERB +
+
+ ERB + @linter.run(processed_source) + + assert_equal(1, @linter.offenses.count) + assert_match(/The navigation landmark should have a unique accessible name via `aria-label` or `aria-labelledby`./, @linter.offenses.first.message) + end + + def test_does_not_warn_if_navigation_landmark_has_aria_labelled_by + @file = <<~ERB + + ERB + @linter.run(processed_source) + + assert_empty @linter.offenses + end + + def test_does_not_warn_if_navigation_landmark_has_aria_label + @file = <<~ERB + + ERB + @linter.run(processed_source) + + assert_empty @linter.offenses + end +end