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

Add ability to use image snapshots to addon-storyshots #2413

Merged

Conversation

thomasbertet
Copy link
Contributor

@thomasbertet thomasbertet commented Dec 1, 2017

Issue: #1781

What I did

  • Ability to generate image snapshots from stories using addon-storyshots.

How to test

  • Start fresh & bootstrap everything
  • Go to cra-kitchen-sink
  • Run yarn run test-image-snapshots

Is this testable with jest or storyshots?

  • Not sure

Does this need a new example in the kitchen sink apps?

  • Yep done.

Does this need an update to the documentation?

  • Maybe we should say something about it in the doc as it may persuade people to use storybook ? But I don't think there is a word about storyshots in the doc yet.

@tobilen
Copy link
Contributor

tobilen commented Dec 1, 2017

just an fyi, since we added image-snapshot testing to our suites a couple of days ago: puppeteer will render text slightly different depending on the enviroment you run it on (especially mac vs linux based containers).

This means you either need to provide a big enough margin of error, or you need to record your snapshots locally from inside the container.

Either way, this change will mean that users who use container for their CI will need to modify those to include chrome. Definitely a breaking change here.

@Hypnosphi Hypnosphi changed the base branch from master to release/3.3 December 1, 2017 21:31
@thomasbertet
Copy link
Contributor Author

thomasbertet commented Dec 4, 2017

@tobilen I do not understand why this is a breaking change as it just adds an option to generate image snapshots. If one is using the addon-storyshots, he must use this option to generate images and thus the concern about linux/mac is up to him to handle while doing this, isn't it ?

@thomasbertet thomasbertet force-pushed the storyshots-add-image-snapshots branch 2 times, most recently from e4c45dc to a742d00 Compare December 4, 2017 14:02
@thomasbertet
Copy link
Contributor Author

@Hypnosphi could you give me a hint on what to do next to go on with this ?

@thomasbertet
Copy link
Contributor Author

@Hypnosphi in the meantime, can you elaborate on why this is a breaking change ? 🤔

@Hypnosphi
Copy link
Member

what to do next to go on with this

I'd like to hear from @ndelangen, he has set up visual tests for kitchen sink apps

@tobilen
Copy link
Contributor

tobilen commented Dec 6, 2017

hey @thomasbertet i mistakenly assumed you'd want storyshots to do image snapshotting as a default. i now see that you're just providing a helper method. Sorry about that.

I would include something about that in the readme though.

</span>
);

storiesOf('Button - for-image-snapshot', module)
Copy link
Member

@danielduan danielduan Dec 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please follow the current naming convention we have?

storiesOf('Addon Storyshots.Image Snapshot Button...')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need a pattern to match to avoid generating all images.

WDYT about Addon Storyshots.Button.ImageSnapshot where ImageSnapshot is the pattern I'm matching ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's wrong with matching that entire string? is it because the entire kind name isn't available to you because of the hierarchy tree?

import path from 'path';

initStoryshots({
suite: 'Image snapshots',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you document all of these options and the possible inputs for these in README.md?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact I already documented inside the README the three params for the imageSnapshot function. (the function that you assign to the test param of initStoryshots.)

The "suite" option & all other initStoryshots params are already documented, nothing new from this PR.

)
);

storiesOf('Some really long story kind description - for-image-snapshot', module)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please nest this under the previous Addon Storyshots section

@danielduan
Copy link
Member

Thanks for the contribution, I'm pretty excited for this new feature!

Copy link
Member

@igor-dv igor-dv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest. I feel a bit uncomfortable with adding this feature to StoryShots. Looks like it should be a separate plugin even from the dependencies' point of view, but I am not 100% sure about it (And I was not a part of the discussion at the beginning), so I don't want to be strict and picky.

@@ -16,6 +16,8 @@ export {
snapshotWithOptions,
shallowSnapshot,
renderOnly,
imageSnapshot,
imageSnapshotWithOptions,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, since this is a new feature, you can provide just the imageSnapshot method with the relevant defaults, instead of extending the API with two methods. (IMO it's already confusing enough, and we need to start thinking of some refactoring here for the breaking version)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, did it

@@ -39,3 +43,63 @@ export function renderOnly({ story, context }) {
const storyElement = story.render(context);
reactTestRenderer.create(storyElement);
}

export const imageSnapshotWithOptions = ({ port = 6006, host = 'localhost', scheme = 'http' }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I see there is no cohesion between other "bodies" in this module and the imageSnapshot (and it's a big one). I think worth extracting it into a separate file. index.js can just import it from there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, did it.

const baseUrl = `${scheme}://${host}:${port}`;
const encodedKind = encodeURIComponent(context.kind);
const encodedStoryName = encodeURIComponent(context.story);
const storyUrl = `/iframe.html?selectedKind=${encodedKind}&selectedStory=${encodedStoryName}`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand imageSnapshot won't work for RN. It makes this addon a bit inconsistent. This should be documented very clearly. You can even throw some error in case someone tries to run it for RN.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a message about it inside README & the test itself.

@thomasbertet
Copy link
Contributor Author

Thanks for all your feedbacks ! I think I got every one of them dealt with. Please let me know :)

@danielduan
Copy link
Member

danielduan commented Dec 7, 2017

We're gonna need to fix the unit test as well. Let me see if I can install Chrome on our CircleCI instance.

edit: just converted CI to use the docker image with browsers. we're gonna need to fix the test to serve storybook in the background.

@codecov
Copy link

codecov bot commented Dec 7, 2017

Codecov Report

Merging #2413 into master will decrease coverage by 0.04%.
The diff coverage is 27.77%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2413      +/-   ##
==========================================
- Coverage   34.35%   34.31%   -0.05%     
==========================================
  Files         390      391       +1     
  Lines        8772     8806      +34     
  Branches      903      899       -4     
==========================================
+ Hits         3014     3022       +8     
- Misses       5145     5187      +42     
+ Partials      613      597      -16
Impacted Files Coverage Δ
addons/storyshots/src/test-body-image-snapshot.js 7.69% <7.69%> (ø)
addons/storyshots/src/index.js 79.31% <80%> (-0.69%) ⬇️
app/vue/src/server/config/babel.js 0% <0%> (-100%) ⬇️
addons/a11y/src/components/WrapStory.js 72.09% <0%> (ø) ⬆️
lib/components/src/table/cell.js 65.21% <0%> (ø) ⬆️
addons/links/src/react/components/link.js 78.78% <0%> (ø) ⬆️
addons/a11y/src/components/Report/index.js 0% <0%> (ø) ⬆️
addons/knobs/src/components/types/Array.js 34.14% <0%> (ø) ⬆️
...t-native/src/preview/components/StoryView/index.js 0% <0%> (ø) ⬆️
lib/ui/src/modules/ui/components/menu_item.js 19.14% <0%> (ø) ⬆️
... and 49 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 65a121f...797f2b7. Read the comment docs.

@thomasbertet
Copy link
Contributor Author

thomasbertet commented Dec 8, 2017

@danielduan What we did internally at my company was just to "sleep" for some time before running the test. It sounds pretty hacky but hey it works ! 🍭

Our CicleCI config is as follow:

defaults: &defaults
  docker:
    - image: circleci/node:8.9.1-browsers
[...]
     - run:
          name: Storybook
          command: yarn storybook
          background: true
      - run:
          name: Sleep while running storybook
          command: sleep 60
      - run:
          name: Tests
          command: ./node_modules/.bin/lerna run test --stream

The last command runs the test which needs the storybook to be running.

Is this something we "could" imagine ? If you know a way to know when the storybook has launched, then we could possibly hook into this "event" ?

@igor-dv
Copy link
Member

igor-dv commented Dec 8, 2017

Why running it on ci? Why not just export the static version?

@thomasbertet
Copy link
Contributor Author

@igor-dv what do you mean ? I'm not sure I get it.

@danielduan
Copy link
Member

danielduan commented Dec 8, 2017

@igor-dv the CI is for running the test to make sure this does not regress.

@thomasbertet feel free to toy with the CircleCI settings on your branch to get it working.

@Hypnosphi
Copy link
Member

I think @igor-dv meant that we can run build-storybook and then serve the output instead of running webpack dev server on CI

@igor-dv
Copy link
Member

igor-dv commented Dec 8, 2017

@Hypnosphi, exactly =)

@Hypnosphi
Copy link
Member

Hypnosphi commented Dec 11, 2017

Is there a way to exclude a story from screenshot testing, but still include in regular snapshots? This may be needed when using transitions and animations in components

@thomasbertet
Copy link
Contributor Author

thomasbertet commented Dec 11, 2017

Yes you can use the same parameters as for other storyshots config. In fact, that's what I did, I created two storyshots instances, and each instance is running their proper stories.

Note that you cannot run within a single initStoryshot() the two snapshots mode (images & HTML).
If you wish to use image snapshot side-by-side with HTML snapshots, you need to call another initStoryshots() with the proper params (including regexp for name/kind exclusion/inclusion)

@thomasbertet
Copy link
Contributor Author

@Hypnosphi any hint on how to start a node server to serve the static storybook on CircleCI ? Do you have any experience in this that can save me some time ?
Also, you would not accept this PR if I run the storybook in the CI using the webpack-dev-server, right ?
Thanks!

@igor-dv
Copy link
Member

igor-dv commented Jan 8, 2018

Is something missing here to go forward?

@Hypnosphi
Copy link
Member

— Document what is needed to separate visual and regular tests in addons/storyshots/README.md

This, at least

@thomasbertet
Copy link
Contributor Author

@Hypnosphi I'm not sure I follow. I mean there is nothing to do in particular to separate visual regressions (ie. image snapshots) from markup regressions.

The main issue I had was the integration with CRA, as it runs everything that follows the .test.js pattern,. At the time, I did not wanted them to be run automatically, because it requires you to build the static-storybook. This seemed to me a bit too long to be integrated as-is. That is why I had created a different approach in the CRA kitchen sink.

Now that everything is inside official-storybook, no need for two different approaches as we have full control over what test file is used.

I already updated the README of the storyshots addon to document everything image-snapshots related. I believe this is sufficient, WDYT ?

Please tell me in something is unclear. If you feel you need something else or not feel confident in something, please let me know.

@Hypnosphi
Copy link
Member

Hypnosphi commented Jan 9, 2018

there is nothing to do in particular to separate visual regressions (ie. image snapshots) from markup regressions.

Creating a separate jest project may seem obvious, but I wouldn't qualify it as "nothing"

integration with CRA

That's definitely worth documenting as well. There's quite a lot of CRA generated apps out there =)

@thomasbertet
Copy link
Contributor Author

Well technically it's not required to create a separate Jest project, it eases the Jest configuration & especially for our use case with the test ran by /scripts/tests.js.

That said, I tried to document this as much as I can, please forgive my english, don't hesitate to correct what does not make sense / is not english-valid sentences :)

Thanks again for your help & patience on this, really appreciate it. Please let me know if anything needs more details!

@Hypnosphi
Copy link
Member

Thanks @thomasbertet , great work!
Looks like there's only one small change left: #2413 (comment)

@danielduan Your concerns are addressed, aren't they?

@thomasbertet
Copy link
Contributor Author

@Hypnosphi see my answer : #2413 (comment).

@thomasbertet
Copy link
Contributor Author

So are we good ? Are we waiting for @danielduan check ❓

@Hypnosphi
Copy link
Member

unit-test job does an unneeded work ("Build static React kitchen-sink"). Note that unit-test doesn't contain any image tests at all
https://circleci.com/gh/storybooks/storybook/32093?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link

@Hypnosphi Hypnosphi dismissed danielduan’s stale review January 11, 2018 16:04

Concerns seem to be addressed

@thomasbertet
Copy link
Contributor Author

@Hypnosphi you were so right, sorry did not notice it before .. anyway thanks !

@Hypnosphi Hypnosphi merged commit 5dc6e8f into storybookjs:master Jan 11, 2018
@thomasbertet thomasbertet deleted the storyshots-add-image-snapshots branch January 11, 2018 16:49
@danielduan
Copy link
Member

My bad, been pretty busy recently. Looks good to me.

@igor-dv
Copy link
Member

igor-dv commented Jan 11, 2018

@thomasbertet 👏

@ndelangen
Copy link
Member

👏

@anescobar1991
Copy link
Contributor

anescobar1991 commented Jan 16, 2018

Should the css style testing portion of the docs be updated as well? By the way this is really great 👏

@ndelangen
Copy link
Member

@anescobar1991 sounds like a plan! You want to open a PR adding it?

@anescobar1991
Copy link
Contributor

anescobar1991 commented Jan 17, 2018

Sure!

Edit: opened #2767 with change

@wenzowski
Copy link

This will not work on node 9+
pngjs/pngjs#95

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

Successfully merging this pull request may close these issues.

10 participants