Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addon Storyshots Puppeteer: allow viewport per kind or story #9605

Closed
jayknott opened this issue Jan 23, 2020 · 6 comments
Closed

Addon Storyshots Puppeteer: allow viewport per kind or story #9605

jayknott opened this issue Jan 23, 2020 · 6 comments

Comments

@jayknott
Copy link

Describe the solution you'd like
Enable specifying a viewport per kind or story so that when imageSnapshot() is used you can size the images to something that makes sense for your component. For small components like a checkbox you might only want a 100x100 viewport, but for a list or a page you might want 900x900 so that way the diff comparisons are more accurate. This can be done in the story parameters like:
parameters: { storyshots: { viewport: { height: 100, width: 100, ...otherViewportSettings } } }

Describe alternatives you've considered
I have tried to do this in the customizePage function; however, that function doesn't get passed anything useful to identify the kind or story. And it would be ideal to store it in the story and not in the global test or settings.

Are you able to assist bring the feature to reality?
Possibly, I went through the code a little and not sure I understand everything that is happening.

@stale
Copy link

stale bot commented Feb 13, 2020

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Feb 13, 2020
@stale
Copy link

stale bot commented Mar 14, 2020

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@stale stale bot closed this as completed Mar 14, 2020
@lihue
Copy link

lihue commented May 1, 2020

I solved this by using the beforeScreenshot function like this:

const beforeScreenshot = async (page, { context: { parameters } }) => {
  const viewport = parameters.viewport;
  if (viewport) {
    const defaultViewport = viewport.viewports[viewport.defaultViewport];
    await page.setViewport({
      width: parseInt(defaultViewport.styles.width, 10),
      height: parseInt(defaultViewport.styles.height, 10),
    });
  }
  await page.waitFor(500);
};

@danielo515
Copy link

This will be a very handful feature to have, honestly.
@lihue how do you pass that config? What if you want to take several screenshots with different screen sizes?

@lihue
Copy link

lihue commented Jun 9, 2020

@danielo515 I have a testfile (storyshots.test.js) with following content:

import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';
import path from 'path';
import fs from 'fs';

// Store the screenshots outside the source folder to prevent jest from 'watching' them.
// Since they're outside the src directory we nav to them relatively
const ROOTDIR = path.join(__dirname, '../');
const CONFIG_PATH = path.join(ROOTDIR, '.storybook');
const OUTPUT_DIRECTORY = path.join(ROOTDIR, 'screenshots');

// Error if there is no screenshots folder
if (!fs.existsSync(OUTPUT_DIRECTORY)) {
  const errormessage = 'Screenshot directory does not exist. Please create the directory before running tests.';
  console.error(errormessage);
  throw new Error(errormessage);
}

const getMatchOptions = ({ context: { kind, story } }) => ({
  failureThreshold: 0.00001,
  failureThresholdType: 'percent',
  customSnapshotsDir: OUTPUT_DIRECTORY,
  customSnapshotIdentifier: `${kind}-${story}`
    .replace(/[ä]/gi, 'ae')
    .replace(/[ü]/gi, 'ue')
    .replace(/[ö]/gi, 'oe')
    .replace(/[📷]/gi, '')
    .replace(/[^a-z0-9]/gi, '_') // replace anything other than basic letters or numbers with '_'
    .replace(/_+/g, '_') // replace any number of sequential underscores with a single underscore
    .replace(/_$/, '')
    .toLowerCase(),
});

const beforeScreenshot = async (page, { context: { parameters } }) => {
  const viewport = parameters.viewport;
  if (viewport) {
    const defaultViewport = viewport.viewports[viewport.defaultViewport];
    await page.setViewport({
      width: parseInt(defaultViewport.styles.width, 10),
      height: parseInt(defaultViewport.styles.height, 10),
    });
  }
  await page.waitFor(500);
};

initStoryshots({
  suite: 'Standard templates storyshots',

  // Only apply image snapshots to stories with 📷 in the name or kind
  storyNameRegex: /📷/,

  // Relative path from this .js file to the storybook config directory
  configPath: CONFIG_PATH,

  test: imageSnapshot({
    storybookUrl: 'http://localhost:55550/',
    getMatchOptions,
    beforeScreenshot,
  }),
});

I defined different stories for each resolution to test.

@danielo515
Copy link

Thanks for the detailed answer @lihue, I am using a similar (but simpler) approach by providing parameters to the stories.
The good thing it's that all I need to do is re-use the same story but attach a different params, the bad thing is that I end with extra stories that add nothing to my storybook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants