Changelog: Frontend Edition

Nick Taylor - Jun 24 '20 - - Dev Community

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();
  });
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

More Frontend Updates!

Storybook Updates

In May, I wrote an update about our usage of Storybook.

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.

Screenshot of DEV's Storybook

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.

Screenshot of DEV's Storybook theme switcher

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,
    },
  },
...
Enter fullscreen mode Exit fullscreen mode

Another super handy addition is in jest watch mode. You can now filter by a test’s name or filename.

Screenshot of jest test runner options in watch mode

Screenshot of jest test runner options in watch mode for filtering test files based on 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!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .