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
Vulcan + Storybook Discussion #1939
Comments
The part where you have to mock out the child component that are referenced via |
@Discordius Hey thanks for the feedback. I ran into this issue and what I did was to import the subcomponents (the non-container versions of them). It was a reasonable amount of mocking, but not much more than i'd have to do if I was testing it with a normal test framework anyway. In my normal app, my The only things I couldn't really mock were the Vulcan specific components, but if I just want to test my components, it's not so bad. So stuff like the Modal Trigger I haven't figured out a way to get that out yet, although I'm not too worried about that - I mainly wanted it for UI development of my own components. import React from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import { linkTo } from '@storybook/addon-links'
import { Button, Welcome } from '@storybook/react/demo'
import ClientsList from '../components/clients/ClientsList'
import ClientsItem from '../components/clients/ClientsItem'
import { Link } from 'react-router'
import moment from 'moment'
const columns = [
{
label: 'Name',
field: 'firstName',
order: 10,
component: ({ document: d }) => (
<Link to={`/client/${d._id}`}>{`${d.firstName} ${d.lastName}`}</Link>
),
sort: true
},
{
label: 'Last Interaction',
field: 'lastInteraction',
order: 10,
component: ({ document: d }) =>
d.lastInteraction ? (
<div>
{moment(d.lastInteraction).format('dddd, MMMM Do YYYY, hh:mm:ss')}
</div>
) : (
'N/A'
),
sort: true
}
]
const mockData = [
{
//...
}
]
const ComponentsMocks = {
ModalTrigger: () => <div>Edit Client</div>,
EditForm: () => <div />,
ClientsItem: ({ client }) => (
<ClientsItem
check={() => true}
Components={ComponentsMocks}
columns={columns}
client={client}
/>
),
ClientsNewForm: () => <div />
}
storiesOf('Clients List', module).add('with Text', () => (
<ClientsList
results={mockData}
currentUser={{}}
loading={false}
loadMore={() => true}
count={mockData.length}
totalCount={mockData.length}
terms={{}}
setTerms={() => true}
Components={ComponentsMocks}
/>
)) |
For style import I use a main decorator that imports all needed libs.
Then in your storybook Concerning Meteor + Storybook, another direction would be to replace Node by Meteor as the runtime executable. Right now I avoid Meteor stuffs in my React components too but that can be annoying. This is especially true in Vulcan, that exploits cleverly the Meteor features even for purely frontend stuffs, like Also, Storybook should not be only a unit development interface, it should also enable people to test fully integrated components, including Meteor/React components. In other projects I use it with full fledged containers, and even allow API calls. That makes me gain an infinite amount of time and that is the desirable goal. |
Can you please elaborate this part? |
@Hypnosphi a sample Meteor import might be:
|
So what's the error when you try to do that? |
Meteor packages are kept instead the .meteor folder and to be compliant with certain tools allows you to use 'meteor/[package name]'. Storybook uses webpack so it doesn't have any way of resolving those paths to the actual location of the Meteor package. Therefore for that to work either Meteor packages and the core Meteor packages would have to be on npm or the storybook webpack would have to be able to resolve meteor packages somehow |
does this work?
|
No, because Meteor packages are just not NPM packages. They have a |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
I think we can close this :) Storybook install is documented here: https://github.com/VulcanJS/vulcan-docs/blob/master/source/storybook.md |
Problem
Storybook does not understand how to parse the meteor npm imports.
Possible Solution
After some playing around I managed to get it to work if I extract all Vulcan packages and higher order components that contain queries into a container component and the 'dumb' components just contain the UI. This component has no UI components inside it and it passes the Vulcan components to its children. This allows you to import the non-container components into Storybook and pass it mock functions and Components that are not from Vulcan as props into your dumb components.
The container components will not be imported into your stories. It gets a little more complicated with nested components as you need to mock even more components and then pass them through.
Thoughts
Components have to be more verbose and have separate files for each. Must avoid imports from Meteor/Vulcan in your storybook tested components. However promotes better testing practice as all testable components needs to be pure(ish), they can't even have a single Meteor import, so promotes separation of concerns of your components to container vs UI components.
Vulcan's
registerComponent
makes it quite easy to mock the components as all of the components you need to pass as prop are contained under one object. Makes me think about keeping components pure by using therecompose
library to map props and not directly import them in to make it easier to mock them out.Jest allows you to setup mocks for certain paths. I'm not that experienced with Storybook, so maybe there is a way to mock out modules such as Meteor in the way Jest mocks it out.
Things that need to be worked out
I haven't figured out how to import css in yet such as bootstrap, but that isn't Vulcan specific so should be worked out easily.
Code
The text was updated successfully, but these errors were encountered: