-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LG-12465 VPAT 1.1.1 Safari VoiceOver svg with null alt #10200
Conversation
Is there a way we can catch these with a regression spec? Like augmenting the aXe checks or adding a new check for https://github.com/18F/identity-idp/blob/main/spec/support/matchers/accessibility.rb#L291 |
Would that correct for the failing tests? |
I think so? Here's the gist of what I was thinking, we could probably update the error description a bit diff --git a/spec/support/matchers/accessibility.rb b/spec/support/matchers/accessibility.rb
index 19659c2b5..fc9798125 100644
--- a/spec/support/matchers/accessibility.rb
+++ b/spec/support/matchers/accessibility.rb
@@ -170,6 +170,27 @@ RSpec::Matchers.define :have_unique_form_landmark_labels do
end
end
+RSpec::Matchers.define :tag_decorative_svgs_with_role do
+ 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' }
+ end
+
+ failure_message do |page|
+ img_tags = decorative_svgs(page).reject { |img| img[:role] == 'img' }
+ .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:
+ #{img_tags}
+ STR
+ end
+end
+
class AccessibleName
attr_reader :page
@@ -293,6 +314,7 @@ def expect_page_to_have_no_accessibility_violations(page, validate_markup: true)
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
end
def activate_skip_link that gives us a failure message like this:
|
Thank you, @zachmargolis that snippet works great. Is there something more that needs to be done to ./spec/support/matchers/accessibility because it still doesn't like the use of the img role. It seems to be caught under :"best-practice"
|
Originally I thought Axe might be flagging it since it'd be redundant with But I'm curious if that'd conflict with the fix being effective in Safari. Can you link to a resource about why we'd want to add |
I should have tested locally before going right to pushing change to 'presentation'. The bug manifests with the 'presentation' role also. |
expect(page).to be_axe_clean.according_to( | ||
:section508, :"best-practice", | ||
:wcag21aa | ||
).skipping('aria-allowed-role') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if skipping all role attributes is a good solution here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I modify tag_decorative_svgs_with_role
to compensate, I wonder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a feeling that if we need to bypass typical best practices for img
role
that we might have to do something like this, so it's not totally unexpected to me. I'd wonder if we could at least limit it to the very specific case we're trying to exempt, i.e. img
role
and not anything else that Axe might be looking for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't done any research to validate the idea, but I'd also wonder if we could mark the image as aria-hidden="true"
if it's decorative anyways. My understanding is that the expected behavior for a screen reader with a decorative image (alt=""
) is to skip it entirely and omit it from the page structure, which is the same as what happens with aria-hidden="true"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed that you'd revised this to target the image specifically, so my previous comment may not be necessary. I'll review shortly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, Zach's selector up above for the decorative svg function worked great there. 🙂
8e31585
to
0a6a2f1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, and tested locally 👍
One suggestion about adding a code comment to explain the solution.
expect(page).to be_axe_clean.according_to( | ||
:section508, :"best-practice", | ||
:wcag21aa | ||
).excluding('img[alt=""][src$=".svg" i]') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an inline code comment to help explain why this is here?
).excluding('img[alt=""][src$=".svg" i]') | |
). | |
# 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]') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the i
portion of this selector doing? I've not seen that before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's there to flag case-insensitive. The test passes without it though so I'm not sure if it's needed here.
https://caniuse.com/css-case-insensitive
🎫 Ticket
Link to the relevant ticket:
LG-12465
🛠 Summary of changes
Instead of skipping over SVG images with alt="" attribute, VoiceOver in Safari is reading them as 'image'. Multi-part SVG would read 'image, image, image, etc.' Adding role='img' to the SVG eliminates the bug.
https://a11y-101.com/development/svg
📜 Testing Plan
Using MacOS with Safari and VoiceOver capability
Before fix
https://github.com/18F/identity-idp/assets/135744319/6ae9386e-7ef5-4690-b8b1-f74e7b04b24b
After fix
https://github.com/18F/identity-idp/assets/135744319/9891c134-1aa4-4363-8c55-71ad0dc5e808