Storyshots doesn't work on local storybook-static folder

1.4k Views Asked by At

Problem Summary

Storybook snapshot test on static storybook returning blank screenshots even though they look fine on localhost:8080 when I ran npx http-server storybook-static

Tech stack and relevant code

  • Vue 3
  • Vite
  • Storybook
  • Jest
  • Storyshots
  • Puppeteer

I have components and their respective stories. npm run storybook works perfectly fine. My storybook.spec.js is as follows:

import { imageSnapshot } from "@storybook/addon-storyshots-puppeteer"

import initStoryshots from "@storybook/addon-storyshots"


initStoryshots({
    suite: "Image storyshots", 
    test: imageSnapshot(
        storybookUrl: 'file://absolute/path/to/my/storybook-static'
    )
})

I ran the following. fyi, I did not modify any file in storybook-static after running npm run build-storybook.

npm run build-storybook
npm run test

npm run test constitutes jest --config=jest.config.js test

Problem

Unfortunately, the screenshots I get are all blank and fail the snapshot test.

I suspect it might be due to a CORS error just like other Storybook users when they click <project-root>/storybook-static/index.html after running npm run build-storybook, to which I want to ask for a solution as well, because I wanna run test remotely on a headless server.

Note

I used absolute path because relative path caused a resource not found error during the testing process.

2

There are 2 best solutions below

0
On

None of the images were loading within my pipeline but worked fine locally, ended up being because the components were fetching images using a relative path <img src="/my-image" /> which apparently is not allowed using the file protocol.

I ended up doing 2 things:

  1. Updating the static dirs directory to use the root by updating the main.js file in storybook
module.exports = {
 staticDirs: [{ from: '../static', to: '/' }],
}
  1. Added a script to remove the leading slash of images in the preview-head.html file from storybook
<script>
  document.addEventListener('DOMContentLoaded', () => {
      Array.from(document.querySelectorAll('img')).forEach((img) => {
        const original = img.getAttribute('src');
        img.setAttribute('src', original.replace('/', ''));
      });
  });
</script>

Another (arguably better) approach would be to run the tests through a server where you can access the images

0
On

The problem is that you're running the tests from file:// instead of http://. So the URI is file:// and the img url ends up like this after applying some url logic: path.resolve(window.location, '/your-image.png') file:///your-image.png. If this is the case you could change to http://. You can start a express server and serve the storybook-static folder from setupGlobal and then shut it down in teardownGlobal. Then you will need to change your storybookUrl to http://localhost:<some-port>.