This is a practical guide to Tailwind, shadcn-ui Visual Regression Testing with Storybook. It will walk you through the basics of integrating Tailwind & shadcn-ui, managing components with Storybook, and ensuring visual consistency using Lost Pixel's open-source visual regression testing. Perfect for developers at any level, this guide offers a straightforward approach to enhancing your Next.js or any other projects using different frameworks. Let's dive in!
Clone the next.js template from shadcn-ui-next-js template and download it on your machine. We start with
npm install to get all of the dependencies running.
npm run dev starts the next project and sets us up for the next steps.
What are we going to do:
- Add couple of components using shadcn-ui
- Add storybook to manage the components we created
- Add lost-pixel open-source visual regression testing flow to make sure our components are always looking as expected
Extending our component base
We will create the
patterns folder where we will put our new components that we will want to test. Don't forget to addon all of the primitives like label,switch and other trough amazing
Our first component will be
Second component will be
Adding those to the page should look similar to this:
Now let's add Storybook to our project and add our patterns & primitives to our storybook so we could develop them in isolation, document & most importantly test them.
Storybook is indespensable tool for modern frontend development as it allows to document the components, develop them in isolation & finally easily test them for visual regression testing.
Let's run this command to automatically enable the storybook in our project
npx sb init --builder webpack5. Next we need to make sure that storybook works well with the tailwind which is used under the hood of shadcn.ui.
npx storybook@latest add @storybook/addon-styling-webpack
We will override our font in
globals.css so that our fonts in both storybook and application are the same, so this tutorial is simpler to follow.
Let's add 3 stories of the tailwind component that we have. One primitive component -
<Button/> and two pattern components -
stories folder that we have automatically created let's delete all of the generated files & add our own.
Note that our primitive component is used in both of the pattern components, this is important for the visual regression testing, as with growth of your component library the biggest risk lies in changing the primitives & affecting your patterns where those primitives are used.
Our end result should look like this:
Let's add a simple visual regression testing for our tailwind & shadcn-ui.
Adding Lost Pixel
Let's add Lost Pixel package to our repo:
npm add lost-pixel &&
npx lost-pixel init-ts
lostpixel.config.ts should me slightly modified to ensure we target storybook at the correct place.
Believe it or not - this is the basic working visual testing setup with Lost Pixel, the only thing that we need to do is to build our storybook & run lost-pixel!
npm run build-storybook &&
npx lost-pixel update
This will build our storybook & then run lost-pixel tests over it & place the current component visual snapshots into
Now let's try to change the
<Button/> primitive and rerun our tests, let's change default background from primary to destructive
default: "bg-destructive text-primary-foreground hover:bg-primary/90"
npm run build-storybook &&
Comparing 3 screenshots using 'pixelmatch' as compare engine [1/3] Comparing 'button--primary' (button--primary) [2/3] Comparing 'cookies--primary' (cookies--primary) [3/3] Comparing 'createaccount--primary' (create-account--primary) [1/3] Difference of 4726 pixels (0.51%) found. Difference image saved to: .lostpixel/difference/button--primary.png (button--primary) [2/3] No difference found. (cookies--primary) [3/3] Difference of 47364 pixels (5.14%) found. Difference image saved to: .lostpixel/difference/create-account--primary.png (create-account--primary) Comparison done!
We can see that in both of the pattern components that were using the
<Button/> with primary variant we have the spotted regressions. All the relevant to the run images are saved in
This is a very basic setup that allows you to run visual regression tests locally. Let's add a simple GitHub actions integration to make sure we can catch the visual regressions of our tailwind components continuously & effortlessly.
Running visual regression testing on GitHub Actions
To start running Lost Pixel on CI we need to create an action workflow file. Let's create
.github folder, and place
workflows folder inside. Inside
workflows let's create
vrt.yml file with the following contents:
This code checks out repository, installs dependencies, builds storybook & finally runs Lost Pixel. If there will be visual regressions the check will fail.
Whenever you make a change to your stories that should update the baselines - just run
npx lost-pixel docker update. This will run lost-pixel in docker to make sure we eliminate inconsistencies in operating systems between your machine & CI, it will also update all of the visual snapshots in the
baseline folder of
.lost-pixel making your next CI run successful.
That's the result we are aiming for here for when you are pushing some code that changes your primitive components and influences other patterns down the dependency graph:
If you want to extend your storybook visual tests & add your Next.js pages - it's super trivial with Lost Pixel as well, you can follow this tutorial that focuses on holistic tests
About Dima Ivashchuk
Dima is the co-founder of Lost Pixel. He likes modern frontends, building stuff on the internet and educating others.