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

How to use in Storybook 5.2 Component Story Format (CSF)? #121

Open
JimmyLv opened this issue Oct 22, 2019 · 9 comments
Open

How to use in Storybook 5.2 Component Story Format (CSF)? #121

JimmyLv opened this issue Oct 22, 2019 · 9 comments

Comments

@JimmyLv
Copy link

JimmyLv commented Oct 22, 2019

export default {
  title: 'MyComponent',
  decorators: [storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>],
};

https://storybook.js.org/docs/formats/component-story-format/

@JimmyLv JimmyLv changed the title How to use in Storybook 5.0 Component Story Format (CSF)? How to use in Storybook 5.2 Component Story Format (CSF)? Oct 22, 2019
@zachmanring-natgeo
Copy link

import { mount } from 'enzyme'
import expect from 'expect'

...

export const withSampleData = () => {
  const story = (
    <div
      style={{
        position: 'absolute',
        textAlign: 'center',
        top: '50%',
        transform: 'translateY(-50%)',
        width: '100%',
      }}
    >
      <FillButton
        disabled={boolean('disabled', false)}
        fullWidth={boolean('fullWidth', false)}
        icon={object('icon', iconExample)}
        inverse={boolean('inverse', false)}
        label={text('label', 'button')}
        link={object('link', linkExample)}
        loading={boolean('loading', false)}
        size={select('size', ['small', 'large', 'xlarge'], 'large')}
        style={select('style', ['primary', 'secondary', 'outlined', 'disabled'], 'primary')}
        type={select('type (behavior)', ['button', 'link', 'submit'], 'button')}
      />
    </div>
  )

  specs(() =>
    describe('with sample data', () => {
      it('Should have label of `button`', () => {
        const output = mount(story)

        expect(output.text()).toContain('button')
      })
    }),
  )

  return story
}

withSampleData.story = {
  name: 'with sample data',

  parameters: {
    notes: 'A very simple example of addon notes',
  },
}

Example on how I got it to work.

@philipbeadle
Copy link

I cant get mount to work. Shallow works fine but mount always says "inst is null"

I've tried a bunch of different react versions but cant figure whats wrong.

My steps

  • Install React npx create-react-app . & Storybook npx -p @storybook/cli sb init --type react in the ui-src folder
  • Check they both work yarn start & yarn storybook
  • Install Enzyme yarn add -D enzyme enzyme-adapter-react-16
  • Install the Storybook addon yarn add -D storybook-addon-specifications
  • Add this line to your addons.js import 'storybook-addon-specifications/register';

My code

import React from 'react';
import { action } from '@storybook/addon-actions';
import { Button } from '@storybook/react/demo';
import { specs, describe, it } from 'storybook-addon-specifications';
import { shallow, mount } from 'enzyme';
import expect from 'expect';
import { configure as enzymeConfigure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

enzymeConfigure({ adapter: new Adapter() })

export default {
  title: 'Button'
};

export const text = () => {
  const story = (
    <Button onClick={action('Hello World')}>
      Hello World
    </Button>
  );

  specs(() => describe('Text', function () {
    it('Should have the Hello World label', function () {
      let wrap = shallow(story);
      // let wrap = mount(story);
      expect(wrap.text()).toContain('Hello World');
    });
  }));

  return story;
}

text.story = {
  name: 'Text'
}

@philipbeadle
Copy link

Weird works now.

@JakeStanger
Copy link

@philipbeadle do you know what caused it to work? I'm having the same problem where mount throws an error but shallow works.

@philipbeadle
Copy link

I set up a setupTests.js

import { configure as enzymeConfigure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
enzymeConfigure({ adapter: new Adapter() });

Moved my tests to a separate file

import React from 'react';
import { mount } from 'enzyme';
import { MessageList } from './index';
import { testMessages } from '../../testData/messageList';

export const noMessageListTests = describe('No messages', function () {
  let props = {
    messages: []
  }

  const component = (
    <MessageList {...props}/>
  );
  it('Renders witout crashing', function () {
    mount(component);
  });
  it('Does not show any messages', function () {
    let wrap = mount(component);
    expect(wrap.find('Message').length).toEqual(0)
  });
  it('Shows the no messages message', function () {
    let wrap = mount(component);
    expect(wrap.find('h2').text()).toContain('No Messages Yet');
  });
})

and import the tests

import React from 'react';
import { action } from '@storybook/addon-actions';
import { MessageList } from '../src/components/MessageList/index';
import { specs } from 'storybook-addon-specifications';
import { noMessageListTests } from '../src/components/MessageList/index.test'
import { messageListTests } from '../src/components/MessageList/index.test'
import { testMessages } from '../src/testData/messageList';
export default {
  title: 'Message List'
};

export const noMessages = () => {
  let props = {
    messages: []
  }
  const story = (
    <MessageList {...props} />
  );
  specs(() => noMessageListTests);
  return story;
}

noMessages.story = {
  name: 'No messages'
}

Also added a test.js to the .storybook folder

import { describe, it, beforeEach } from 'storybook-addon-specifications';
import expect from 'expect';
import jest from 'jest-mock';
import { shallow, mount } from 'enzyme';
import { configure as enzymeConfigure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
enzymeConfigure({ adapter: new Adapter() });

window.describe = describe;
window.beforeEach = beforeEach;
window.it = it;
window.expect = expect;
window.jest = jest;
window.shallow = shallow;
window.mount = mount;

and import that in the config.js

import { configure } from '@storybook/react';
import './test'
configure(require.context('../stories', true, /\.stories\.js$/), module);

Now it all works and I can run my tests in jest as well.

@rphmee
Copy link

rphmee commented Jan 13, 2020

@philipbeadle Just wanted to say thanks, been working through this setup for a few hours and nothing was working until I followed your post. And as an added bonus my story files don't get cluttered with the tests, nice and clean.

@andrewcorliss
Copy link

andrewcorliss commented Jun 1, 2020

Hello, I am currently trying to get this to work on CSF and am having issues setting up inside with errors coming from other modules.

The project I am working on currently is using the method where we have no config.js but use the main.js file

Any tips or advice?

My main issue is I cannot get the expect function to work. It causes an error in my build

@beccasaurus
Copy link

beccasaurus commented Jun 13, 2020

@andrewcorliss Did you ever find a solution? I'm having the same issue with expect.

Edit: I made a brand new React app and added Storybook using these steps from @philipbeadle above and it's working for me now!

I also had problems with mount() (inst is null) until I followed the follow-up example.

@neko-neko
Copy link
Collaborator

I'm working on support CSF format and support for storybook 6. Described in #123.

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

No branches or pull requests

8 participants