<aside> 🧹 @Michael Shilman

</aside>

Combinatorial testing is a powerful way to quickly achieve broad test coverage. This document proposes a set of features, implemented as an addon, to bring combinatorial stories to Storybook. With the recent introduction of Storybook Args, we now have a principled way to do this in CSF.

Design objectives

Consider the following story:

export const DefaultCombinations: CSFStory<JSX.Element> = () => (
  <ComponentCombinator
    Component={Button}
    presetProps={{ children: 'Button' }} 
    combinations={[useStates, sizeStates, arrowStates, contentStates]}
  />
);

One can imagine a component that renders the different states of a component in a grid, which would be a simple and valuable addon in and of itself.

https://lh5.googleusercontent.com/4hExysEUoEEDfy8gZglEjwt0jEktXfwHigkMd1bDs7y7ZfGfcTaVWIP2VP0cxsZsVnNEz2-2KHEa-I84u7WCx1SnUsEB9u0Yh9Tj5l7xd-jZJTA-dzutShMAaZDJpOWG_1KezWh6

This proposal considers an Args-based approach that achieve a few more objectives:

Combo Stories

Storybook CSF is an ES6 module-based standard for component examples. Here is an example of a single configuration of a button:

// Button.stories.js
export const Basic = {
  args: {  size: 'small',  arrow: 'left',  children: 'Button'}
}

Now consider a combinatorial specification:

// Button.combo.js
export const Basic = {
  combos: {
    size: ['small', 'medium', 'large'],
    arrow: ['left', null],
    children: ['Button', 'Long text']
  }
};

This isn’t valid CSF. But it’s a trivial transformation to make it CSF:

// Button.combo.stories.js
const Basic1 = { args: { size: 'small' arrow: 'left', children: 'Button' } };
const Basic2 = { args: { size: 'small' arrow: 'left', children: ‘Long text' } };
//...
export const Basic12 = { args: { size: 'large' arrow: null, children: ‘Long text' } };