Storybook: Storyshots browser and image snapshots

Created on 31 Aug 2017  ·  6Comments  ·  Source: storybookjs/storybook

It would be great if storyshots could diff screenshots of stories as they are rendered in a browser. The idea comes from this blog post: https://voice.kadira.io/snapshot-testing-in-react-storybook-43b3b71cec4f

Jest’s snapshot testing is just one solution for snapshot testing. We will have two more solutions shipped as drivers. They are:
Browser snapshots — This will get snapshots by rendering your UI on a real browser.
Image snapshots — This will get snapshots as images so we can test CSS and style changes as well

Possible API:

import { browserSnapshot } from '@storybook/addon-storyshots';
initStoryshots({
  configPath: 'path/to/config',
  test: browserSnapshot
});
storyshots feature request

Most helpful comment

@smith-kyle @sideroad I would like to discuss about some possibilities around this if you have time. You can join Slack https://storybooks.slack.com to chat, otherwise I will write here my thoughts:

As pointed out by @shilman , there is an alternative here: https://loki.js.org/ but I don't quite understand how to compare images on CI, it seems everything is generated locally, so the CI will fail only if an image is missing, not if it has changed and you did not update the reference image.

Anyway for the addon-storyshots:

  • You have to run the storybook before generating image snapshots (may not be trivial on CI)
  • You should just be able to run your tests and it should generate the images & compare them with references using jest-image-snapshots

To generate images, I'm thinking of using puppeteer. I was thinking about generating images each time you run your tests like so:

/* eslint-env jest */

import puppeteer from 'puppeteer';
import { toMatchImageSnapshot } from 'jest-image-snapshot';

expect.extend({ toMatchImageSnapshot });

describe('Imagediff - Button', () => {
    let browser, page;

    beforeEach(() => {
        browser = await puppeteer.launch();
        page = await browser.newPage();
    });

    afterEach(() => {
        return browser.close();
    });

    test('button-basic', () => {
        expect.assertions(1);
        // Call the storybook in "iframe" mode to get only relevant content.
        await page.goto('http://localhost:6006/iframe.html?selectedKind=components.buttons.Button&selectedStory=basic');
        // Generate screenshot
        const image = await page.screenshot();
        // Check againt snapshot
        expect(image).toMatchImageSnapshot();
    });
)}

That said, do you see anything that may not work for your use-case ?

All 6 comments

+1

Same, puppeteer + jest-image-snapshot should cover these cases

I may start working on this real soon.

@smith-kyle @sideroad I would like to discuss about some possibilities around this if you have time. You can join Slack https://storybooks.slack.com to chat, otherwise I will write here my thoughts:

As pointed out by @shilman , there is an alternative here: https://loki.js.org/ but I don't quite understand how to compare images on CI, it seems everything is generated locally, so the CI will fail only if an image is missing, not if it has changed and you did not update the reference image.

Anyway for the addon-storyshots:

  • You have to run the storybook before generating image snapshots (may not be trivial on CI)
  • You should just be able to run your tests and it should generate the images & compare them with references using jest-image-snapshots

To generate images, I'm thinking of using puppeteer. I was thinking about generating images each time you run your tests like so:

/* eslint-env jest */

import puppeteer from 'puppeteer';
import { toMatchImageSnapshot } from 'jest-image-snapshot';

expect.extend({ toMatchImageSnapshot });

describe('Imagediff - Button', () => {
    let browser, page;

    beforeEach(() => {
        browser = await puppeteer.launch();
        page = await browser.newPage();
    });

    afterEach(() => {
        return browser.close();
    });

    test('button-basic', () => {
        expect.assertions(1);
        // Call the storybook in "iframe" mode to get only relevant content.
        await page.goto('http://localhost:6006/iframe.html?selectedKind=components.buttons.Button&selectedStory=basic');
        // Generate screenshot
        const image = await page.screenshot();
        // Check againt snapshot
        expect(image).toMatchImageSnapshot();
    });
)}

That said, do you see anything that may not work for your use-case ?

I'm gonna ask for this to be delayed until v3.4.0 since we should be releasing 3.3 soonish. Feel free to keep working on it as we'll get 3.4-alpha published when new features are ready to be tested.

Released as 3.4.0-alpha.4

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arunoda picture arunoda  ·  3Comments

tlrobinson picture tlrobinson  ·  3Comments

xogeny picture xogeny  ·  3Comments

tirli picture tirli  ·  3Comments

purplecones picture purplecones  ·  3Comments