-
Notifications
You must be signed in to change notification settings - Fork 220
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
[storybook-a11y-test] Set best practices for dealing with failing rules #2045
Conversation
c0268e3
to
08233a0
Compare
08233a0
to
710d318
Compare
I would love to learn more about why teams are not fixing:
Feels like we are solving the wrong problem and enabling teams to disable tests whenever they like. |
I am curious about this too. I have also seen one false positive or a flakey test cause many teams to disable these tests entirely though. Looking at web we have at least 90 different stories completely disabling accessibility tests, which is a major red flag. Still, I see this as a step forward. More similar to how we allow the disabling of a single eslint rule. Yes, this should always be an exception, but it is also necessary sometimes (and better than people opting out entirely). I would really like to either have clear guidelines to make the comment explaining why required, or even better, a lint rule to enforce that. |
@@ -66,20 +68,21 @@ export const getCurrentStoryIds = async ({ | |||
return stories.reduce(removeSkippedStories(skippedStoryIds), []); | |||
}; | |||
|
|||
const formatFailureNodes = (nodes) => { | |||
const formatFailureNodes = (nodes: axeCore.NodeResult[]) => { |
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 appreciate adding types. Any chance we could write these as regular function declarations rather than assigning to variables while you're in here?
const formatFailureNodes = (nodes: axeCore.NodeResult[]) => { | |
function formatFailureNodes(nodes: axeCore.NodeResult[]) { |
etc
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.
Fixed in 84cb409
This feels like something that should be linted against, as our styleguide doesn't clearly state that functions are the way to go https://github.com/Shopify/javascript#functions
const axeElement: axeCore.ElementContext | undefined = | ||
story.parameters.a11y && story.parameters.a11y.element; |
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.
These assignments might be a good excuse for optional chaining / nullish coalescing:
const axeElement: axeCore.ElementContext | undefined = | |
story.parameters.a11y && story.parameters.a11y.element; | |
const axeElement: axeCore.ElementContext | undefined = story.parameters.a11y?.element ?? {} |
If you provide a type to the const story
declaration above you wouldn't need to specify the types down here, something like:
interface Story {
parameters: {
a11y?: {
element?: axeCore.ElementContext;
config?: axeCore.spec;
options?: axeCore.RunOptions;
}
}
}
const story: Story = ....
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 part of the code is definitely a good one to refactor, thanks for the pointers.
What I ended up doing is aligning with what addon-a11y's runner does:
Let me know what you think!
You'll see this:
import type {A11yParameters} from '@storybook/addon-a11y/dist/ts3.9/params';
Ideally this type would be easier to import, so I opened a PR in Storybook, seeking a more elegant solution: storybookjs/storybook#16128
} | ||
})(); | ||
``` | ||
|
||
### Ignoring specific violations in a Story |
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.
Could we add something here about only doing this if there are false positives, not to get around an existing accessibility problem being flagged?
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.
Good nudge, yeah! And I think it's also useful during prototyping / early build GSD phases so I'll mention that.
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 just pushed 82eae5b and went for a mix of guidelines + examples, feedback appreciated!
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 looks good to me now other than Ben's comment about converting those arrow functions / variables into regular functions.
Do we have a plan for getting teams to re-enable these in web after this change goes in?
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.
No ran but logic seems good to me
The first step is to replace PrototypeComponent.parameters = {
a11y: {
options: {
rules: [
{
// Page-level semantics cause a violation and need to be reworked.
// Currently discussing solutions with the accessibility team.
//
// @link https://github.com/Shopify/shopify/issues/123
// @link https://dequeuniversity.com/rules/axe/4.3/landmark-complementary-is-top-level
id: 'landmark-complementary-is-top-level',
reviewOnFail: true,
},
],
},
},
}; Once I'm done, we'll have a better idea of the scale of the problem and we can look into next steps (as in: how to nudge team toward fixing these issues). |
Description
At the moment, folks have no other choice but to entirely disable accessibility tests in a story whenever it has a single violation. This is detrimental to accessibility testing as it could hide many issues.
The best practice is to either:
reviewOnFail
so that teams can get back to it laterThis PR allows for very granular axe configuration settings that work both in Storybook and in this automated testing suite.
Before
After
🎩 instructions
In your project (your mileage may vary regarding
yarn
scripts:Type of change
Checklist
Tested in both Shopify/web and Shopify/polaris-react.
Polaris didn't have any errors.
In Shopify/web, these errors popped up, probably due to the version of axe-core being used: