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

(addon-storyshots) Export a getStoryshots method #13403

Closed
pimlie opened this issue Dec 8, 2020 · 1 comment
Closed

(addon-storyshots) Export a getStoryshots method #13403

pimlie opened this issue Dec 8, 2020 · 1 comment

Comments

@pimlie
Copy link

pimlie commented Dec 8, 2020

ie split initStoryshots into a stories getter and a test runner

Is your feature request related to a problem? Please describe

I am using storybook to visually test my components, but have also a need for integration testing my components using Vue-Test-Utils. As I already have stories with decorators to mock certain plugins, I would like to use these stories as starting point of my integration tests.

Describe the solution you'd like

Currently I have implemented this as follows:

test/utils.js
// test/utils.js
import addons, { mockChannel } from '@storybook/addons'
import loadFramework from '@storybook/addon-storyshots/dist/frameworks/frameworkLoader'

// Required for Storyshots
addons.setChannel(mockChannel())

const isDisabled = (parameter) =>
  parameter === false || (parameter && parameter.disable === true)

export function getStoryshots(storyKindRegex) {
  const { storybook, framework } = loadFramework({})
  const data = storybook.raw().reduce((acc, item) => {
    /* if (storyNameRegex && !item.name.match(storyNameRegex)) {
        return acc;
      } */

    if (storyKindRegex && !item.kind.match(storyKindRegex)) {
      return acc
    }

    const { kind, storyFn: render, parameters } = item
    const existing = acc.find((i) => i.kind === kind)
    const { fileName } = item.parameters

    if (!isDisabled(parameters.storyshots)) {
      if (existing) {
        existing.children.push({ ...item, render, fileName })
      } else {
        acc.push({
          kind,
          children: [{ ...item, render, fileName }],
        })
      }
    }
    return acc
  }, [])

  // Lets keep the original reduce method intact as much as possible
  // and transform the data to the tables that we need for Jest
  return data.map(({ kind, children }) => [
    kind,
    children.map((story) => [story.name, story, { ...story, framework }]),
    framework,
  ])
}

next I can implement my tests as follows:

MyComponent.test.js
// MyComponent.test.js

const storyshots = getStoryshots(/MyComponent/i)

describe.each(storyshots)('%s', (kind, stories) => {
  describe.each(stories)('%s', (name, story, context) => {
    let wrapper

    beforeAll(() => {
      const el = story.render()
      wrapper = mount(el)
    })

    test('Take Snapshot', () => {
      expect(wrapper.html()).toMatchSnapshot()
    })

    // ... any other describe/test calls I would like to have
  })
})

Describe alternatives you've considered

I could implement everything with VTU but I'd like to re-use the decorators I already added for mocking plugins & state.

Are you able to assist to bring the feature to reality?
Sure, let me know what you need

Additional context

I will admit that this use-case might be a bit edgy (and Vue specific?) because its the wrong way around. But given the current storyshots implementation it should be a fairly simple to export a getStoryshots method for users who want to have full control about their story tests.

@shilman
Copy link
Member

shilman commented Dec 9, 2020

Closing this as a duplicate to #10145

Strictly speaking, I think you're asking for something different than what's being discussed there. But I think we should discuss/solve it all in one place. cc @lifeiscontent @yannbf @tmeasday

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

2 participants