-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Storybook: Add StoryShots integration to generate unit tests #18031
Conversation
ac08f2e
to
0d56672
Compare
What makes it break? Is there anyway we can mock it?
We can also just add an explicit list of |
8249379
to
cceee54
Compare
This is the full error: ● @wordpress/components › ClipboardButton › Default
TypeError: Cannot read property 'firstChild' of null
27 | componentDidMount() {
28 | const { container, getText, onCopy } = this;
> 29 | const button = container.firstChild;
| ^
30 |
31 | this.clipboard = new Clipboard( button, {
32 | text: getText,
at ClipboardButton.firstChild [as componentDidMount] (packages/components/src/clipboard-button/index.js:29:28)
at commitLifeCycles (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10930:22)
at commitLayoutEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13583:7)
at HTMLUnknownElement.callCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10487:14)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10537:16)
at invokeGuardedCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:10590:31)
at commitRootImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13355:9)
at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:643:12)
at runWithPriority (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1887:10)
at commitRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13184:3)
at runRootCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12420:20)
at node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1935:24
at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:643:12)
at runWithPriority (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1887:10)
at flushSyncCallbackQueueImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1931:7)
at flushSyncCallbackQueue (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1920:3)
at scheduleUpdateOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12297:9)
at scheduleRootUpdate (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15087:3)
at updateContainerAtExpirationTime (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15115:10)
at updateContainer (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15134:10)
at create (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15824:5)
at getRenderedTree (node_modules/@storybook/addon-storyshots/dist/frameworks/react/renderTree.js:24:16)
at node_modules/@storybook/addon-storyshots/dist/test-bodies.js:21:18
at Object.<anonymous> (node_modules/@storybook/addon-storyshots/dist/api/snapshotsTestsTemplate.js:44:33)
I guess there is something going on with how it gets mounted. I don't think it's so much important and we can skip it but feel free to investigate further.
We can start with the blacklist at first. Good idea 👍 |
0d56672
to
3684187
Compare
Sounds good, let's do it. |
cceee54
to
34a2aa2
Compare
3684187
to
7c6e7b3
Compare
With 7c6e7b3 we have a list of skipped components in the Storyshots configuration. It should be ready to go. This branch is based on the #18030 so we can merge it there once approved. |
9e4bcb8
to
fdaed2e
Compare
From my experience, snapshot testing (in general) is definitely better than nothing, but I prefer having and writing unit/integration tests. I also think writing unit tests should also be easier, which can be achieved by having testing utils (if we're staying with Enzyme) or leveraging another testing solution. Personally, I haven't used this particular addon for Storybook. I'm okay with keeping this in to see where it goes/how it feels :) Maybe it can automate a portion of manually writing basic render tests, freeing up time/focus to write unit/integration tests for more complex scenarios. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to run the tests with success by using "npm run test-unit storybook/test/index.js".
I'm not sure if these tests will be useful in catching regressions or not but I think the best way is to merge them and check if they helped us or they added developer overhead to update the snapshots.
We also have some interesting potential follow-ups pending like the a11y tests, so I guess we should merge this PR and see where these type of tests leaves us.
fdaed2e
to
ccc705b
Compare
I invested more time into this issue and I managed to mock those nodes which use refs with the following commits: This means, we no longer skip any stories from snapshot testing. However, the side effect is that if there is some special use case for refs, it might require custom logic in the mocking helper. The following seem to work for now: createNodeMock: ( element ) => {
if ( story.kind === 'Components|ClipboardButton' ) {
return {
firstChild: document.createElement( 'button' ),
};
}
return element.type && document.createElement( element.type );
}, I followed links shared by @epiqueras:
It looks like it's a general issue with snapshot testing in React apps. |
One thing I noticed is that storyshot tests will still fail if a console warning is emitted. On #17875, I created a story for a deprecated thing so I could see the UI worked and the warning was shown. On normal tests I can check if the warning was shown. Can I do that with Storyshots? |
This raises the question of whether we should keep the legacy version of Toolbar in Storybook 🤔 I could make the point that it should be removed from there as it should be discouraged from using in new code. Having it included in the docs might create the temptation for folks to copy the example and use it in their projects when they find that it fits their needs. I'm aware that it isn't probably the type of answers you expected but this is something we should discuss more broadly before we jump into finding a technical solution on how to mitigate it. Maybe we don't have to do it. The only downside is that this story is very useful in the process of developing the migration path for the |
ccc705b
to
7abdc2e
Compare
f5d6912
to
85c7ac2
Compare
09f32e2
to
83fd01e
Compare
83fd01e
to
92f46dd
Compare
I included documentation in 92f46dd. |
628b459
to
a2d5a2c
Compare
Description
Part of #17973.
Depends on #18030.
I followed the docs at this page:
https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core
Testing
Run
npm run test-unit packages/components/storybook/
Known issue
There is a known issue with using React hooks with components in stories:storybookjs/storybook#8177
I'm seeing the following:This issue was resolved by refactoring #18030. This PR was rebased with
update/storybook-enhancements
to solve it here as well.