diff --git a/Gemfile.lock b/Gemfile.lock
index d0258b2095f..8feb71e0c4c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -199,10 +199,10 @@ GEM
aws-sigv4 (~> 1.1)
aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2)
- axe-core-api (4.7.0)
+ axe-core-api (4.9.0)
dumb_delegator
virtus
- axe-core-rspec (4.7.0)
+ axe-core-rspec (4.9.0)
axe-core-api
dumb_delegator
virtus
@@ -448,7 +448,7 @@ GEM
net-ssh (6.1.0)
newrelic_rpm (9.7.0)
nio4r (2.7.0)
- nokogiri (1.16.2)
+ nokogiri (1.16.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
openssl (3.0.2)
diff --git a/app/views/idv/how_to_verify/show.html.erb b/app/views/idv/how_to_verify/show.html.erb
index 2955d67dbce..7a2b5c96e9a 100644
--- a/app/views/idv/how_to_verify/show.html.erb
+++ b/app/views/idv/how_to_verify/show.html.erb
@@ -16,8 +16,11 @@
<%= simple_form_for(
@idv_how_to_verify_form,
- html: { autocomplete: 'off',
- 'aria-label': t('forms.buttons.continue_remote') },
+ html: {
+ autocomplete: 'off',
+ id: nil,
+ aria: { label: t('forms.buttons.continue_remote') },
+ },
method: :put,
url: idv_how_to_verify_url,
) do |f|
@@ -53,8 +56,11 @@
<%= simple_form_for(
@idv_how_to_verify_form,
- html: { autocomplete: 'off',
- 'aria-label': t('forms.buttons.continue_ipp') },
+ html: {
+ autocomplete: 'off',
+ id: nil,
+ aria: { label: t('forms.buttons.continue_ipp') },
+ },
method: :put,
url: idv_how_to_verify_url,
) do |f|
diff --git a/spec/support/matchers/accessibility.rb b/spec/support/matchers/accessibility.rb
index b9e295ecc66..f32e7e75dd6 100644
--- a/spec/support/matchers/accessibility.rb
+++ b/spec/support/matchers/accessibility.rb
@@ -170,6 +170,23 @@ def landmarks(page)
end
end
+RSpec::Matchers.define :have_unique_ids do
+ def ids(page)
+ page.all(:css, '[id]').map { |element| element[:id] }
+ end
+
+ match do |page|
+ page_ids = ids(page)
+ page_ids.uniq.count == page_ids.count
+ end
+
+ failure_message do |page|
+ page_ids = ids(page)
+ duplicate = page_ids.detect { |id| page_ids.count(id) > 1 }
+ "Expected no duplicate element IDs. Found duplicate: #{duplicate}"
+ end
+end
+
RSpec::Matchers.define :tag_decorative_svgs_with_role do
def decorative_svgs(page)
page.all(:css, 'img[alt=""][src$=".svg" i]')
@@ -310,13 +327,11 @@ def fieldset_legend_name(element)
end
def expect_page_to_have_no_accessibility_violations(page, validate_markup: true)
- expect(page).to be_axe_clean.according_to(
- :section508, :"best-practice",
- :wcag21aa
- ).
+ expect(page).to be_axe_clean.according_to(:wcag22aa, :"best-practice").
# Axe flags redundant img role on img elements, but is necessary for a Safari bug
# See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#identifying_svg_as_an_image
excluding('img[alt=""][src$=".svg" i]')
+ expect(page).to have_unique_ids
expect(page).to have_valid_idrefs
expect(page).to label_required_fields
expect(page).to have_valid_markup if validate_markup