I Tweeted this out last week that we moved to Preact X and Testing Library.
Let’s dig in to all the improvements we’ve been making in the frontend.
Preact X
DEV is now running Preact X (currently 10.4.4 at the time of writing this post). I followed the official Preact X upgrade guide to move us from 8.5.2 to 10.4.4. So, what does the new version of Preact give us as developers? You can read about all the new things in the What’s new in Preact X
post on the Preact site. In a nutshell, a lot of the functionality that was previously only available in React is now available in Preact as well—hooks, fragments, context, componentDidCatch
to name a few.
Testing Library
DEV has moved away from preact-render-spy and preact-render-to-json for a couple of reasons. The main one was that neither of these tools were working with the Preact upgrade. The second is that the official React documentation recommends react-testing-library and Jest as the tools of choice when working with React components. For those reasons, we moved to preact-testing-library, a project that is also a part of the Testing Library family.
As part of the move, we deprecated the usage of snapshot testing except for in design system components. I am still fairly new to Testing Library, but have found it to be fairly intuitive and it encourages building accessible applications. I’m also a big fan of the debug()
function.
Accessibility (a11y) Testing
Testing Library encourages building accessible applications, but we can do more. Nick Colley has taken the wonderful aXe tool from Deque Systems and integrated it with Jest as a custom Jest matcher called jest-axe for testing accessibility.
When jest-axe is used in conjunction with preact-testing-library, we get notified of a11y errors allowing us to fix them. All the tests in the DEV code base related to Preact components test for a11y errors.
A typical a11y test in a component test file looks like this.
it('should have no a11y violations', async () => {
const { container } = render(
<MyComponent />,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
And when this test fails, you are presented with readable errors to fix the a11y issues.
expect(received).toHaveNoViolations(expected)
Expected the HTML found at $('.crayons-btn--icon') to have no violations:
<button class="crayons-btn crayons-btn--outlined crayons-btn--icon" type="button" data-testid="subscription-settings">
Received:
"Buttons must have discernible text (button-name)"
Fix any of the following:
Element does not have inner text that is visible to screen readers
aria-label attribute does not exist or is empty
aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
Element's default semantics were not overridden with role="presentation"
Element's default semantics were not overridden with role="none"
Element has no title attribute or the title attribute is empty
You can find more information on this issue here:
https://dequeuniversity.com/rules/axe/3.5/button-name?application=axeAPI
More Frontend Updates!
Storybook Updates
In May, I wrote an update about our usage of Storybook.
Changelog: DEV has Some Stories for You
Nick Taylor for The DEV Team ・ May 22 '20
Since then, we’ve continued to use Storybook to build out design system components and some critical application components. Moving to Preact X has allowed us to finally start using some more powerful Storybook addons. I mentioned a11y testing above, so to complement this, we added the Storybook a11y addon.
In addition to that, we have a custom Storybook decorator that allows you to change DEV themes so you can ensure you are building out things correctly for each theme we support.
You can view DEV's work in progress Storybook here. Every merge to our main branch related to Storybook stories will deploy an updated Storybook, so what you see is always the latest and greatest. Thanks to Netlify deploy previews, you can see the Storybook related to every PR! 🔥
Improvements to Jest
There are no big changes to our Jest setup, just a few tweaks. First off, as we have been testing more in the frontend, our code coverage has been increasing. So as coverage goes up, we want to avoid any drop in coverage, so we added coverage thresholds to our Jest configuration.
module.exports = {
...
coverageThreshold: {
global: {
statements: 40,
branches: 35,
functions: 39,
lines: 41,
},
},
...
Another super handy addition is in jest watch mode. You can now filter by a test’s name or filename.
Is that all? Yes it is. Surely you jest. 😆
Updated Linting Rules
Previously, we were using the AirBnB Style Guide as the base for all our linting on the frontend. Although a great project, we found the rules to be somewhat rigid. We opted to go with the ESLint recommended rule set paired with the Preact recommended rule set.
Just a reminder, we use Prettier in the project, so that handles all formatting of frontend files.
A big shoutout to my co-worker @ridhwana for helping me migrate all the tests to preact-testing-library. 👏 I'm really excited about all the changes we have been making on the frontend, and look forward to continue to improve it. If you feel like contributing to the project in regards to the frontend, don’t be shy to DM me on DEV, Twitter or wherever. I’m pretty much @nickytonline everywhere. If email is your jam, hit me up at nick@dev.to.
That’s all for now folks!
Top comments (11)
So far I'm a big fan of Testing Library!
The dashboard looks a bit unfinished lately XD
We’ve made some recent changes there. Product design is aware, but thanks for mentioning it.
Thanks.
I wasn't sure if this was unfinished or simply broken.
PR to fix this should be getting merged today. 🚢
Awesome! Great to see lots of great a11y boosts ✨🌠
Awesome work!
I wonder - why A11y test for the whole app but individually for components? (is it because of the running speed or other factors?), Thanks!
We are fixing/testing for a11y in the application as a whole as we come across things (we're mainly a Rails app), but since the Preact components are part of the application, typically for the logged on user experience, if they have issues we need to fix those as well.