Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/views/mfa_confirmation/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<% self.title = @content.heading %>

<%= image_tag asset_url('user-signup-ial1.svg'), width: 107, height: 119, alt: '', class: 'margin-bottom-4', role: 'img' %>
<%= image_tag asset_url('user-signup-ial1.svg'), width: 107, height: 119, alt: '', class: 'margin-bottom-4', aria: { hidden: true } %>

<%= render PageHeadingComponent.new.with_content(@content.heading) %>

Expand Down
2 changes: 1 addition & 1 deletion app/views/openid_connect/logout/confirm_logout.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<% self.title = t('openid_connect.logout.heading', app_name: APP_NAME) %>

<div class='text-center'>
<%= image_tag(asset_url('user-access.svg'), width: '280', height: '91', alt: '', role: 'img') %>
<%= image_tag(asset_url('user-access.svg'), width: '280', height: '91', alt: '', aria: { hidden: true }) %>
<% if @service_provider_name.present? %>
<%= render PageHeadingComponent.new.with_content(t('openid_connect.logout.heading_with_sp', app_name: APP_NAME, service_provider_name: @service_provider_name)) %>
<% else %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"two_factor_options_form_selection_#{option.type}",
class: 'usa-checkbox__label usa-checkbox__label--illustrated',
) do %>
<%= image_tag(asset_url("mfa-options/#{option.type}.svg"), alt: '', class: 'usa-checkbox__image', role: 'img') %>
<%= image_tag(asset_url("mfa-options/#{option.type}.svg"), alt: '', class: 'usa-checkbox__image', aria: { hidden: true }) %>
<div class="usa-checkbox__label--text">
<span class="margin-right-2"><%= option.label %></span>
<%= content_tag(
Expand Down
2 changes: 0 additions & 2 deletions app/views/shared/_banner.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
asset_url('icon-dot-gov.svg'),
size: 40,
alt: '',
role: 'img',
aria: { hidden: true },
class: 'usa-banner__icon usa-media-block__img',
) %>
Expand All @@ -44,7 +43,6 @@
asset_url('icon-https.svg'),
size: 40,
alt: '',
role: 'img',
aria: { hidden: true },
class: 'usa-banner__icon usa-media-block__img',
) %>
Expand Down
4 changes: 2 additions & 2 deletions app/views/shared/_footer_lite.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<footer class="footer">
<%= new_tab_link_to('https://www.gsa.gov', class: 'footer__agency-logo') do %>
<%= image_tag(asset_url('sp-logos/square-gsa.svg'), size: 20, alt: '', class: 'margin-right-05', role: 'img') %>
<%= image_tag(asset_url('sp-logos/square-gsa.svg'), size: 20, alt: '', class: 'margin-right-05', aria: { hidden: true }) %>
<%= t('shared.footer_lite.gsa') %>
<% end %>
<%= render LanguagePickerComponent.new(class: 'footer__language-picker') %>
Expand All @@ -12,7 +12,7 @@
</div>
<div class="footer__links">
<%= new_tab_link_to('https://www.gsa.gov', class: 'footer__agency-logo') do %>
<%= image_tag(asset_url('sp-logos/square-gsa-dark.svg'), size: 20, alt: '', class: 'margin-right-05', role: 'img') %>
<%= image_tag(asset_url('sp-logos/square-gsa-dark.svg'), size: 20, alt: '', class: 'margin-right-05', aria: { hidden: true }) %>
<%= t('shared.footer_lite.gsa') %>
<% end %>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="text-center">
<%= image_tag(asset_url('user-access.svg'), width: '280', height: '91', alt: '', role: 'img') %>
<%= image_tag(asset_url('user-access.svg'), width: '280', height: '91', alt: '', aria: { hidden: true }) %>
<h1 class="margin-bottom-4 text-primary text-normal">
<strong><%= decorated_sp_session.sp_name %></strong>
<%= t('headings.create_account_with_sp.sp_text', app_name: APP_NAME) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/users/backup_code_setup/reminder.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<% self.title = t('forms.backup_code.title') %>

<%= image_tag asset_url('user-signup-ial1.svg'), width: 107, height: 119, alt: '', class: 'margin-bottom-4', role: 'img' %>
<%= image_tag asset_url('user-signup-ial1.svg'), width: 107, height: 119, alt: '', class: 'margin-bottom-4', aria: { hidden: true } %>

<%= render PageHeadingComponent.new.with_content(t('forms.backup_code_reminder.heading')) %>

Expand Down
2 changes: 1 addition & 1 deletion app/views/users/webauthn_setup/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<% self.title = @presenter.page_title %>

<% if @platform_authenticator %>
<%= image_tag asset_url('platform-authenticator.svg'), alt: '', width: 84, height: 95, class: 'margin-left-1 margin-bottom-2', role: 'img' %>
<%= image_tag asset_url('platform-authenticator.svg'), alt: '', width: 84, height: 95, class: 'margin-left-1 margin-bottom-2', aria: { hidden: true } %>
<% end %>

<%= render PageHeadingComponent.new.with_content(@presenter.heading) %>
Expand Down
25 changes: 16 additions & 9 deletions spec/support/matchers/accessibility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,22 +187,32 @@ def ids(page)
end
end

RSpec::Matchers.define :tag_decorative_svgs_with_role do
RSpec::Matchers.define :tag_decorative_svgs_with_aria_hidden do
# VoiceOver on Safari will erroneously announce SVG <img> elements with a null text alternative,
# even with `role="presentation"` (see LG-12465). Assigning `aria-hidden` is equivalent to
# `role="presentation"` for image elements, and prevents the images from being announced. This
# should be removed if and when the bug is fixed in a future version of Safari.
#
# "Consequently, using role="presentation" or role="none" on an HTML img is equivalent to using
# aria-hidden="true"."
#
# See: https://www.w3.org/TR/wai-aria-1.2/#presentation

def decorative_svgs(page)
page.all(:css, 'img[alt=""][src$=".svg" i]')
end

match do |page|
expect(decorative_svgs(page)).to all satisfy { |img| img[:role] == 'img' }
expect(decorative_svgs(page)).to all satisfy { |img| !img[:'aria-hidden'].nil? }
end

failure_message do |page|
img_tags = decorative_svgs(page).reject { |img| img[:role] == 'img' }.
img_tags = decorative_svgs(page).select { |img| img[:'aria-hidden'].nil? }.
map { |img| %(<img alt="#{img[:alt]}" src="#{img[:src]}" class="#{img[:class]}">) }.
join("\n")

<<~STR
Expect all decorative SVGs to have role="img", but found ones without:
Expect all decorative SVGs to have aria-hidden, but found ones without:
#{img_tags}
STR
end
Expand Down Expand Up @@ -327,15 +337,12 @@ 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(: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 be_axe_clean.according_to(:wcag22aa, :"best-practice")
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
expect(page).to tag_decorative_svgs_with_role
expect(page).to tag_decorative_svgs_with_aria_hidden
end

def activate_skip_link
Expand Down