Back to UI Testing Handbook
  • Introduction
  • Visual
  • Composition
  • Interaction
  • Accessibility
  • User flow
  • Automate
  • Workflow
  • Conclusion

UI Testing Playbook

A testing workflow that doesn’t slow you down

It's easy to find tools that test different parts of the UI. But knowing how to combine them into a productive workflow is tricky. If you get it wrong, it spirals into a maintenance nightmare.

Our workflow reduces the maintenance burden by reusing stories as test cases. Plus, we can spot bugs faster by testing at the component level.

This chapter demonstrates the entire UI testing workflow by adding in the ability to delete a task.


The Task component already allows users to edit, pin and archive a task. We'll add a delete button and wire that up to the application state to add the delete functionality.

For this demo, let's jump straight to the point where you're ready to test. Download the updated files and place them in the /src directory:

Visual & Composition tests

First, we're going to ensure that the updated UI styles match the spec. The Task component now requires the onDeleteTask prop to handle deletions. Let's mock that out as an action in the Task stories.

import Task from './Task';

export default {
  component: Task,
  title: 'Task',
  argTypes: {
    onArchiveTask: { action: 'onArchiveTask' },
    onTogglePinTask: { action: 'onTogglePinTask' },
    onEditTitle: { action: 'onEditTitle' },
+   onDeleteTask: { action: 'onDeleteTask' },

During development

Instead of booting up the entire application, you can use Storybook to focus on just the Task component. Then cycle through all its stories to manually verify their appearance.

PR check

Tweaks to the Task UI can lead to unintended changes in other components where it's used: TaskList and InboxScreen. Running visual tests with Chromatic will catch those. It'll also ensure that everything is still wired up correctly.

Chromatic will be triggered automatically when you create a pull request. On completion, you'll be presented with a diff to review. In this case, the changes are intentional. Press the accept button to update the baselines.

Accessibility tests

During development

Run accessibility checks inside Storybook during development. The A11y addon uses Axe to audit the active story and displays the report in the addon panel. A quick glance confirms that none of our stories have any violations.

PR check

To catch regressions you need to run on all your components. You can do that by importing stories into a test file and then running an accessibility audit using jest-axe. All violations will be reported back to the PR page.

Interaction tests

The user can delete a task by clicking on the trash can button, we’ll need to add in a test to verify that behaviour.

During development

During development, manually verify the interaction using the InboxScreen stories. If it’s working as expected, you can add in an interaction test using a play function.

// ... code omitted for brevity ...

export const DeleteTask = {
  parameters: {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const getTask = (id) => canvas.findByRole('listitem', { name: id });

    const itemToDelete = await getTask('task-1');
    const deleteButton = await findByRole(itemToDelete, 'button', {
      name: 'delete',

    // Click the delete button
    await expect(canvas.getAllByRole('listitem').length).toBe(5);

Run yarn run test-storybook to confirm that all tests are passing. Notice how Jest runs in watch mode and only executes tests related to files that changed.

PR check

Github Actions will run the test runner when the pull request is created and report status via PR checks.

User flow tests

Lastly, you'll need to run E2E tests to ensure that all your critical user flows are working as expected.

During development

This new functionality doesn't impact the auth flow. Therefore, you can wait to run Cypress on the CI server. You only need to run targeted E2E tests during development if you add or update a test.

PR check

Just like all your other tests, Github actions will also run E2E tests using Cypress.

Your journey begins

UI Testing handbook highlights testing strategies used by professional front-end teams. These tests act as health checks for your app, verify everything from visual appearance to UI logic, and even detect integration issues. What's more, you can reduce bugs by using continuous integration to test each commit automatically.

The final chapter concludes with the complete sample code, helpful resources, and frequently asked questions from developers.

Keep your code in sync with this chapter. View f330642 on GitHub.
Is this free guide helping you? Tweet to give kudos and help other devs find it.
Next Chapter
Get more done by doing less
✍️ Edit on GitHub – PRs welcome!
Join the community
6,623 developers and counting
WhyWhy StorybookComponent-driven UI
Open source software

Maintained by
Special thanks to Netlify and CircleCI