-
-
Notifications
You must be signed in to change notification settings - Fork 612
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
Fix a11y CI workflow #2503
Fix a11y CI workflow #2503
Conversation
🦋 Changeset detectedLatest commit: 5f5eaeb The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for astro-starlight ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@@ -47,6 +47,7 @@ | |||
"peerDependencyRules": { | |||
"ignoreMissing": [ | |||
"@algolia/client-search", | |||
"playwright", |
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.
This is needed as axe-playwright
has a peer dependency of playwright
which we explicitly don't use in favor of @playwright/test
. Both official packages are different in the sense that playwright
automatically installs browser binaries while @playwright/test
does not. Running pnpm test:a11y
in the packages/starlight/
directory will take care of installing the necessary dependencies in our case only when needed.
Amazing work @HiDeoo! Great to get these running again, and with the latest versions of stuff. I took a quick look at the errors and suspect the error raised is technically correct, but a bit tricky to solve for. It’s raising issues with both our aside and tab components. AsidesAside markup looks like this (simplified): <aside aria-label="Note">
<!-- ... -->
</aside>
Fixing this is tricky. Some of the options might be:
Probably needs some more research to understand the impact. TabsTab markup looks like this (simplified): <starlight-tabs>
<div class="tablist-wrapper">
<ul role="tablist">
<li role="presentation">
<a role="tab" href="#tab-panel-378" id="tab-378">npm</a>
</li>
<!-- more tabs -->
</ul>
</div>
<section id="tab-panel-378" aria-labelledby="tab-378" role="tabpanel">
<!-- panel content -->
</section>
<!-- more panels -->
</starlight-tabs>
So basically the same question for us to answer I guess: how important is it for these to be landmark regions, given that enforcing unique labelling may be impractical (in the aside case) or even impossible (in the tabs case, where the whole point is that they share a title). |
Thanks for the great write-up. After investigating the errors myself I came to the same conclusions and also the same questions and after some research, here are my current thoughts: AsidesI think before jumping to the reported
At the moment, this rule is not reported in our case, as even if it's not documented, an exception was added for allowing As the initial rule was supposed to be based on the ARIA standards, I decided to dig a bit further and indeed the ARIA Authoring Practices Guide state for landmark regions the following:
Altho, it's quite confusing considering the next sentence is:
We can also easily find a lot of discussions like this one, or this one where the confusion is obvious even between members:
Even tho some statement are contradictory, the rule was edited to make it more obvious that
There are also stories about the W3C having this exact same issue themselves, e.g. when implementing the "Editor's note" note on this document: ![]() The Proposed changeNote that this proposal would require more testing. Considering the existing confusion regarding this rule and as it was mentioned quite a bit of times in the links I shared for this kind of use case, we could move to the
This would remove the extra landmark and the original error while still providing a hint that is designed to help screen reader users understand the context and purpose. It should be noted that this role is not reported in NVDA altho, this would be 1 specific reader issue, which could be solved at some point, instead of making navigation for screen reader users relying on landmarks navigation more difficult by having identical labels for multiple landmarks. TabsI think this one is a bit more easy at first glance. Most tabs pattern example, even the one from the ARIA Authoring Practices Guide (APG) don't create an extra landmark. Proposed changeNote that this proposal would require more testing. We just replace the |
Haha, the history around the I think I’m in favour of both your proposed changes. Additional motivation when I consider it a bit more is also that the usual usage of Starlight’s notes etc. is for that content to be locally complementary. It’s not really complementing I’ll leave it up to you how you prefer to tackle this, whether to do the work directly in this PR or if you prefer to disable those audits in this PR, and we open an issue for these problems to PR the fixes & re-enabling the audits separately. Both would be fine approaches I think. |
Implemented some slug filtering to reduce the number of page tested that I mentioned in the PR description (open to discuss/ditch the idea if we decide it's not worth it or if we want to test all pages). Here is a benchmark on my machine before the change (this include building the docs site): ❯ hyperfine --runs 5 -i 'pnpm test:a11y'
Benchmark 1: pnpm test:a11y
Time (mean ± σ): 126.005 s ± 10.246 s [User: 117.604 s, System: 7.940 s]
Range (min … max): 113.814 s … 135.125 s 5 runs And after the change: ❯ hyperfine --runs 5 -i 'pnpm test:a11y'
Benchmark 1: pnpm test:a11y
Time (mean ± σ): 88.082 s ± 1.699 s [User: 91.069 s, System: 6.393 s]
Range (min … max): 86.485 s … 90.196 s 5 runs For comparison, on CI, this change reduced the time from 3m 44s to 3m 2s. Here is the pages I decided to keep and the reason why (these are tested for the default locale and
All other pages are skipped as they don't really contain any unique content that is not already tested in the other pages. The skipped pages are explicitly defined which means that adding new pages will automatically be tested until we decide to opt-out of them. |
const extractTabPanels = (html: string) => { | ||
const tree = fromHtml(html, { fragment: true }); | ||
const tabPanels = selectAll('div[role="tabpanel"]', tree); | ||
return tabPanels.map((tabPanel) => processor.stringify({ type: 'root', children: [tabPanel] })); | ||
}; |
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.
Considering we're now using a <div>
element and the tests contain nested <div>
elements, I didn't want to rely and maintain a regular expression to extract the panel HTML 😅
@@ -202,7 +203,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> { | |||
), | |||
...titleNode, | |||
]), | |||
h('section', { class: 'starlight-aside__content' }, node.children), | |||
h('div', { class: 'starlight-aside__content' }, node.children), |
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 also removed the inner region landmark too as it doesn't bring any value imo. I think this landmark definition sums it up well:
Landmarks are meant to identify key areas of a page a user would most likely be interested in and would want to navigate to.
Implemented the changes discussed above. For the asides, here is the accessibility tree and a VoiceOver recording of the asides before and after the changes: For the tabs, the changes don't affect the screen readers output. |
As we discussed, I moved the a11y tests to the I also tested the new changes on Windows using NVDA and JAWS. For tabs, everything is working as expected for both screen readers. For the asides, unfortunately, JAWS is working fine, but NVDA does not only not announce the new Back to the drawing board for asides 😢 |
Following on my previous message, I continued research for the asides. One interesting thing I found is this proposal by Lea Verou for a new This comment from Matthew Tylee Atkinson, an accessibility consultant, pinged by Lea Verou in the issue as an a11y expert, also confirms some previous points:
I also found this interesting comparison between various callouts, e.g. AsciiDoc vs reStructuredText vs Obsidian vs MDN vs Docusaurus vs W3C. It basically highlights the same issues and conclusions that we have been discussing. Then I decided to take a look at some implementations of asides. I used The Component Gallery altho it's a bit tricky as asides don't have a dedicated category and usually bundled with alerts. From my research, I think there are mostly 3 types of implementations:
So here are the various possibilities I see so far:
So far, in the current state of things, I'm leaning towards the last option. It's not the best but maybe the "more accessible" version across all screen readers. As we also tend to avoid asides, I think this goes in the same direction, but of course we have no control over the user's content. When nvaccess/nvda#10439 is fixed (I'm subscribed to it), we can revisit the first option which would be the best until, if ever, a The second best option would be the option 3 I guess, which is widely used. Open to any feedback or suggestions. |
* main: (82 commits) i18n(ja): Update site-search.mdx (withastro#2577) i18n(ja): Update pages.mdx (withastro#2576) i18n(fr): Update `reference/plugins.mdx` from withastro#2549 (withastro#2574) [ci] format docs: update showcase-sites.astro (withastro#2562) Throw an error if a showcase image does not have the required dimensions (withastro#2573) i18n(ja): Update frontmatter.md (withastro#2566) Fixes import name typo in Customize icons example (withastro#2572) [ci] release (withastro#2570) Prettier ignore a malformed YAML test file (withastro#2571) Add YAML support to the FS translation system (withastro#2565) i18n(ja): Update reference/icons.mdx (withastro#2564) i18n(ja): Update overrides.md (withastro#2567) i18n(zh-cn): Update `plugins.mdx` (withastro#2568) i18n(ja): Update customization.mdx (withastro#2560) i18n(ja): Update css-and-tailwind.mdx (withastro#2559) i18n(ru): update `icons.mdx` and `overrides.md` (withastro#2558) i18n(ru): update `i18n.mdx` and `overriding-components.mdx` (withastro#2557) i18n(ko-KR): update `plugins.mdx` (withastro#2556) i18n(ru): update `plugins.mdx` (withastro#2555) ...
Just noting here before I forget that we chatted on Monday and agreed that probably the best (if still imperfect) approach is to maintain use of the Basically the trade-off is:
On balance, we agreed the first option is probably the best compromise for now and we can always revisit this base on future user feedback. |
Updated the PR with the following changes:
|
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.
Looks good to me! Ready to merge when we release the next minor.
Thanks again for the careful work researching this behaviour with different screenreaders to help us arrive at the best approach we can for now 💖
* main: (27 commits) i18n(ko-KR): update `site-search.mdx` [ci] release (withastro#2590) Support passing more options to the DocSearch component (withastro#2589) [ci] release (withastro#2587) Add changeset for withastro#2252 (withastro#2588) [ci] format Update dev dependencies (withastro#2582) Build performance optimizations for projects with large sidebars (withastro#2252) Fix a11y CI workflow (withastro#2503) Update `astro-expressive-code` to v0.38 (withastro#2551) Added social icon for Nostr (withastro#2579) [ci] format docs(showcase): add docs.reactbricks.com to showcase (withastro#2586) i18n(ja): Update site-search.mdx (withastro#2577) i18n(ja): Update pages.mdx (withastro#2576) i18n(fr): Update `reference/plugins.mdx` from withastro#2549 (withastro#2574) [ci] format docs: update showcase-sites.astro (withastro#2562) Throw an error if a showcase image does not have the required dimensions (withastro#2573) i18n(ja): Update frontmatter.md (withastro#2566) ...
This PR fixes the a11y CI workflow that has been silently failing on us for longer than we can even check 😓
After various fixes in the past to accommodate with
pa11y-ci
, this PR removes it in favour of directly running Axe through Playwright (which we're already using for our E2E tests). As we discussed the other day, my initial plan was to write yet again another Axe reporter but after researching for prior art, I found in the React Aria testing suite which uses Storybook, a package doing exactly what we need:axe-playwright
with a built-in CLI reporter.At the moment, the current test suite is running against the same rules that
pa11y-ci
was using plus the newwcag22aa
(WCAG 2.2 Level AA).With this kind of setup, we have way more control over the tests and even if at the moment, we are mostly mirroring the previous setup, we can easily extend it in the future with more tests, e.g. testing light/dark mode, testing after user interactions, etc.
Currently, the tests are failing due to a single error (
landmark-unique
) but I did not yet investigate it further to see if it's something we need to fix or if it's a rule to disable for w/e reason (that's why the PR is still a draft).I'm also planning on experimenting with reducing the number of page tested: I don't think testing some pages provide much value (e.g.
manual-setup
&environmental-impact
don't really provide much a11y value after having already tested thegetting-started
page).