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

Need Help - Unable to run some custom tests with initStoryshots. #3526

Closed
aircraft721 opened this issue May 3, 2018 · 14 comments
Closed

Need Help - Unable to run some custom tests with initStoryshots. #3526

aircraft721 opened this issue May 3, 2018 · 14 comments

Comments

@aircraft721
Copy link

aircraft721 commented May 3, 2018

If you are reporting a bug or requesting support, start here:

Bug or support request

I want to use enzyme and jest-axe to do some accessibility tests. I was wondering if I can accomplish this by using the test method from initStoryshots.

Something like this :

import initStoryshots from '@storybook/addon-storyshots';
import { mount } from 'enzyme';
import { axe, toHaveNoViolations } from 'jest-axe';

initStoryshots({
    storyKindRegex: /^component$/,
    framework: 'react',
    test: ({ story, context, renderTree }) => {
        const component = story.render(context);
        const wrapper = mount(component);
        const results = axe(html);
        expect(results).toHaveNoViolations();
    }
});

After I run it I get this error

    Invariant Violation: WrapStory(...): Nothing was returned from render. This usually means a return stat
ement is missing. Or, to render nothing, return null.

Is there any way I could extract the component and use enzyme mount like this ?

Or should I use the renderTree function ?

Any ideas on how I could make this work ?

Please specify which version of Storybook and optionally any affected addons that you're running

  • storybook/react 3.2.14
  • storybook/addon-storyshots 3.4.2
@Hypnosphi
Copy link
Member

Cc @igor-dv

@igor-dv
Copy link
Member

igor-dv commented May 5, 2018

From the first glance, everything looks ok. Can you try to reproduce this with the latest storybook and addon-storyshots versions?

@aircraft721
Copy link
Author

I updated all my storybook related packages to version 3.4.3 but I still get that error.

 Invariant Violation: WrapStory(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing
, return null.
      at invariant (node_modules/fbjs/lib/invariant.js:42:15)
      at reconcileChildFibers (node_modules/react-dom/cjs/react-dom.development.js:7688:13)
      at reconcileChildrenAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:7756:30)
      at reconcileChildren (node_modules/react-dom/cjs/react-dom.development.js:7747:5)
      at finishClassComponent (node_modules/react-dom/cjs/react-dom.development.js:7881:5)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:7850:12)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:8225:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:10224:16)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:10288:26)
      at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:542: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-dom/cjs/react-dom.development.js:581:16)
      at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:438:27)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:10366:7)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:11014:24)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:10967:7)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:10878:7)
      at scheduleWorkImpl (node_modules/react-dom/cjs/react-dom.development.js:10732:11)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:10689:12)
      at scheduleTopLevelUpdate (node_modules/react-dom/cjs/react-dom.development.js:11193:5)
      at Object.updateContainer (node_modules/react-dom/cjs/react-dom.development.js:11231:7)
      at node_modules/react-dom/cjs/react-dom.development.js:15226:19
      at Object.unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:11102:12)
      at renderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:15225:17)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:15290:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:98:16)
      at Object.mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (screenshots/StoryAxe.tsx:28:34)
      at screenshots/StoryAxe.tsx:7:71
      at Object.<anonymous>.__awaiter (screenshots/StoryAxe.tsx:3:12)
      at test (screenshots/StoryAxe.tsx:26:35)
      at Object.<anonymous> (node_modules/@storybook/addon-storyshots/dist/index.js:125:20)
console.error node_modules\react-dom\cjs\react-dom.development.js:9747
    The above error occurred in the <WrapStory> component:
        in WrapStory (created by WrapperComponent)
        in WrapperComponent

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

@igor-dv
Copy link
Member

igor-dv commented May 8, 2018

Looks like it happens from the mount, maybe you return a wrong result from one of your stories. Can you please share your code from the stories?

@aircraft721
Copy link
Author

Yes, of course.

import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import * as React from 'react';
import { AlertUnavailable } from '../views/AlertUnavailable';
import { AlertError } from '../views/AlertError';
import { checkA11y } from '@storybook/addon-a11y';
import { withReadme } from 'storybook-readme';

// tslint:disable-next-line:no-var-requires
const README = require('../../README.md');

const titleText = 'Oops!';
const contentText = "We're sorry, but the system is temporarily unavailable.";
const tryAgainText = 'Try again later';

const tryAgainTextError = 'Try again';
const contentTextError = "We're sorry, but something went wrong.";
const homeText = 'Home';

const handleTryAgainClick = action('Try Again button was clicked!');
const handleHomeClick = action('Home button was clicked!');

storiesOf('alert', module)
    .addDecorator(withReadme(README))
    .addDecorator(checkA11y)
    .add('AlertUnavailable render', () => (
        <AlertUnavailable
            titleText={titleText}
            contentText={contentText}
            tryAgainText={tryAgainText}
            handleTryAgainClick={handleTryAgainClick}
        />
    ))
    .add('AlertPageError render', () => (
        <AlertError
            titleText={titleText}
            contentText={contentTextError}
            tryAgainText={tryAgainTextError}
            handleTryAgainClick={handleTryAgainClick}
            homeText={homeText}
            handleHomeClick={handleHomeClick}
        />
    ));

@igor-dv
Copy link
Member

igor-dv commented May 8, 2018

Looks like you are limiting your test to snapshot only stories with the kind = "component" ( storyKindRegex: /^component$/)

In the story you shread the kind = "alert"

Also, something is wrong with your code here:

      const component = story.render(context);
        const wrapper = mount(component); // what are you doing with the wrapper after
        const results = axe(html); // what is html
        expect(results).toHaveNoViolations();

@aircraft721
Copy link
Author

Sorry about that. This is my code now.

initStoryshots({
    storyKindRegex: /^alert$/,
    framework: 'react',
    test: async ({ story, context }) => {
        const component = story.render(context);
        const wrapper = mount(component);
        expect(await axe(wrapper.html())).toHaveNoViolations();
    }
});

@igor-dv
Copy link
Member

igor-dv commented May 8, 2018

I've tried now to reproduce it with the official-storybook example but didn't get this error. I think we need some more details to reproduce it. Do you have a public repo with this problem?

@aircraft721
Copy link
Author

I found the root of the problem. This issue is caused by .addDecorator(withReadme(README)) . After I removed this it works as expected. Any thoughts on how I could find a workaround?

@igor-dv
Copy link
Member

igor-dv commented May 8, 2018

This is a 3rd-party addon, just try to debug it during the test. Also maybe @tuchk4 can shed more light on this. You can try even to mock it with jest.mock, and return a story from this mocked decorator.

@aircraft721
Copy link
Author

I'm not sure how to return a story from the mocked decorator. Can you please provide an example? Thanks!

@igor-dv
Copy link
Member

igor-dv commented May 9, 2018

something like this

jest.mock('storybook-readme', () => ({
  withReadme: () => (story) => story()
}))

@aircraft721
Copy link
Author

Thanks. Everything works as expected. I will close this now.

@calaway
Copy link

calaway commented Aug 5, 2019

I don't have a question or issue to address. I'm just posting my solution here in case it helps someone else.

I am also trying to leverage StoryShots to run Axe accessibility tests on all stories and ran into a similar problem. This thread helped get me half way there, but not all the way, probably because I'm not using Enzyme to render the components.

Here is what ultimately worked for me:

import initStoryshots from '@storybook/addon-storyshots';
import ReactDOMServer from 'react-dom/server';
import { axe, toHaveNoViolations } from 'jest-axe';

expect.extend(toHaveNoViolations);

initStoryshots({
  test: async ({ story, context }) => {
    const component = story.render(context);
    const html = ReactDOMServer.renderToString(component);

    expect(await axe(html)).toHaveNoViolations();
  },
});

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