Interaction testing
Let's write some interaction tests directly in Storybook!
When talking about React and testing, Testing Library is one of the most known libraries out there. Developers normally write tests in Jest using Testing Library to simulate user behavior. However, the tests run in JSDOM, which although being fast, is not a real browser.
Since Storybook 6.4, Storybook provides browser-compatible wrappers of Testing library and Jest, so you can use them directly in your stories, and they can be used in the play function, a story annotation that executes after the component has rendered. This means that you can move your test into your stories, which will execute directly in the browser. This is part of what we call interaction testing in Storybook.
Storybook also provides an addon called @storybook/addon-interactions which provides a panel to visualize the interactions as they happen, and even go back and forth to improve debugging!
Getting started#
Let's start by adding the necessary dependencies to write tests in Storybook (stop the process if you are running Storybook):
yarn add -D @storybook/testing-library @storybook/jest @storybook/addon-interactions
Now let's open the .storybook/main.ts
file and register the addon, as well as enable its debugging functionality:
// .storybook/main.ts
module.exports = {
// ...rest of the code
addons: [
// ...other Storybook addons
// register addon-interactions
'@storybook/addon-interactions',
],
// enable playback controls feature (Might be default later, but required in 6.4)
features: {
interactionsDebugger: true,
},
}
We're set!
Writing our first tests#
Let's start by writing some tests for the RestaurantCard.tsx
component. In the project, there is already a RestaurantCard.stories.tsx
file which we wrote in the Composing Components lesson, containing a few variations of a RestaurantCard, including default and closed states.
We start by defining what we want to achieve with our tests. Let's write a couple:
In its default state, the component triggers
onClick
when users interact with the cardIn its closed state, the component does not trigger
onClick
when users interact with the card
Now open the components/RestaurantCard/RestaurantCard.stories.tsx
file and add a play function to the Default
story. The play function receives a context
object with lots of information about a story, and what matters to us is canvasElement
and args
. Let's log them:
// src/components/RestaurantCard/RestaurantCard.stories.tsx
// ... rest of the code
export const Default = Template.bind({})
Default.play = async ({ canvasElement, args }) => {
console.log({ canvasElement, args })
}
You should see the information in your dev tools, and notice that canvasElement
is the DOM element that wraps our story. This will be very useful for us.
This page is a preview of Storybook for React Apps