LG-12465 VPAT 1.1.1 Safari VoiceOver svg with null alt#10200
LG-12465 VPAT 1.1.1 Safari VoiceOver svg with null alt#10200kevinsmaster5 merged 9 commits intomainfrom
Conversation
|
Is there a way we can catch these with a regression spec? Like augmenting the aXe checks or adding a new check for |
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_linkthat 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. |
There was a problem hiding this comment.
Not sure if skipping all role attributes is a good solution here.
There was a problem hiding this comment.
Can I modify tag_decorative_svgs_with_role to compensate, I wonder.
There was a problem hiding this comment.
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.
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.
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.
Yeah, Zach's selector up above for the decorative svg function worked great there. 🙂
8e31585 to
0a6a2f1
Compare
aduth
left a comment
There was a problem hiding this comment.
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.
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.
What is the i portion of this selector doing? I've not seen that before.
There was a problem hiding this comment.
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