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

Storyshots advanced config options #3747

Merged
merged 3 commits into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions addons/storyshots/storyshots-core/.storybook/configTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { configure } from '@storybook/react';

const req = require.context('../stories/required_with_context', true, /.stories.js$/);

function loadStories() {
req.keys().forEach(filename => req(filename));
// eslint-disable-next-line global-require
require('../stories/directly_required');
}

configure(loadStories, module);
33 changes: 32 additions & 1 deletion addons/storyshots/storyshots-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,22 @@ initStoryshots({

## Options

### `config`

The `config` parameter must be a function that helps to configure storybook like the `config.js` does.
If it's not specified, storyshots will try to use [configPath](#configPath) parameter.

```js
import initStoryshots from '@storybook/addon-storyshots';

initStoryshots({
config: ({ configure }) =>
configure(() => {
require('../stories/Button.story.js');
}, module),
});
```

### `configPath`

By default, Storyshots assumes the config directory path for your project as below:
Expand All @@ -165,6 +181,21 @@ initStoryshots({
});
```

`configPath` can also specify path to the `config.js` itself. In this case, config directory will be
a base directory of the `configPath`. It may be useful when the `config.js` for test should differ from the
original one. It also may be useful for separating tests to different test configs:

```js
initStoryshots({
configPath: '.my-storybook-config-dir/testConfig1.js'
});

initStoryshots({
configPath: '.my-storybook-config-dir/testConfig2.js'
});
```


### `suite`

By default, Storyshots groups stories inside a Jest test suite called "Storyshots". You could change it like this:
Expand Down Expand Up @@ -299,7 +330,7 @@ The value is just a [settings](https://github.com/isaacs/node-glob#options) to a
```js
initStoryshots({
integrityOptions: { cwd: __dirname }, // it will start searching from the current directory
test: multiSnapshotWithOptions({}),
test: multiSnapshotWithOptions(),
});
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import runWithRequireContext from '../require_context';
import hasDependency from '../hasDependency';
import loadConfig from '../config-loader';
import configure from '../configure';

function setupAngularJestPreset() {
// Angular + Jest + Storyshots = Crazy Shit:
Expand All @@ -20,22 +19,19 @@ function test(options) {
function load(options) {
setupAngularJestPreset();

const appOptions = require.requireActual('@storybook/angular/options').default;
const { configPath, config } = options;
const frameworkOptions = '@storybook/angular/options';
const storybook = require.requireActual('@storybook/angular');

const { content, contextOpts } = loadConfig({
configDirPath: options.configPath,
appOptions,
});

runWithRequireContext(content, contextOpts);
configure({ configPath, config, frameworkOptions, storybook });

return {
framework: 'angular',
renderTree: require.requireActual('./renderTree').default,
renderShallowTree: () => {
throw new Error('Shallow renderer is not supported for angular');
},
storybook: require.requireActual('@storybook/angular'),
storybook,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
import fs from 'fs';
import path from 'path';
import { getBabelConfig } from '@storybook/core/server';

const babel = require('babel-core');

function getConfigContent({ resolvedConfigDirPath, configPath, appOptions }) {
function getConfigContent({ resolvedConfigDirPath, resolvedConfigPath, appOptions }) {
const babelConfig = getBabelConfig({
...appOptions,
configDir: resolvedConfigDirPath,
});
return babel.transformFileSync(configPath, babelConfig).code;
return babel.transformFileSync(resolvedConfigPath, babelConfig).code;
}

function load({ configDirPath, appOptions }) {
const resolvedConfigDirPath = path.resolve(configDirPath || '.storybook');
const configPath = path.join(resolvedConfigDirPath, 'config.js');
function getConfigPathParts(configPath) {
const resolvedConfigPath = path.resolve(configPath);

const content = getConfigContent({ resolvedConfigDirPath, configPath, appOptions });
const contextOpts = { filename: configPath, dirname: resolvedConfigDirPath };
if (fs.lstatSync(resolvedConfigPath).isDirectory()) {
return {
resolvedConfigDirPath: resolvedConfigPath,
resolvedConfigPath: path.join(resolvedConfigPath, 'config.js'),
};
}

return {
resolvedConfigDirPath: path.dirname(resolvedConfigPath),
resolvedConfigPath,
};
}

function load({ configPath, appOptions }) {
const { resolvedConfigPath, resolvedConfigDirPath } = getConfigPathParts(configPath);

const content = getConfigContent({ resolvedConfigDirPath, resolvedConfigPath, appOptions });
const contextOpts = { filename: resolvedConfigPath, dirname: resolvedConfigDirPath };

return {
content,
Expand Down
22 changes: 22 additions & 0 deletions addons/storyshots/storyshots-core/src/frameworks/configure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import loadConfig from './config-loader';
import runWithRequireContext from './require_context';

function configure(options) {
const { configPath = '.storybook', config, frameworkOptions, storybook } = options;

if (config && typeof config === 'function') {
config(storybook);
return;
}

const appOptions = require.requireActual(frameworkOptions).default;

const { content, contextOpts } = loadConfig({
configPath,
appOptions,
});

runWithRequireContext(content, contextOpts);
}

export default configure;
16 changes: 6 additions & 10 deletions addons/storyshots/storyshots-core/src/frameworks/html/loader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import global from 'global';
import runWithRequireContext from '../require_context';
import loadConfig from '../config-loader';
import configure from '../configure';

function test(options) {
return options.framework === 'html';
Expand All @@ -9,22 +8,19 @@ function test(options) {
function load(options) {
global.STORYBOOK_ENV = 'html';

const appOptions = require.requireActual('@storybook/html/options').default;
const { configPath, config } = options;
const frameworkOptions = '@storybook/html/options';
const storybook = require.requireActual('@storybook/html');

const { content, contextOpts } = loadConfig({
configDirPath: options.configPath,
appOptions,
});

runWithRequireContext(content, contextOpts);
configure({ configPath, config, frameworkOptions, storybook });

return {
framework: 'html',
renderTree: require.requireActual('./renderTree').default,
renderShallowTree: () => {
throw new Error('Shallow renderer is not supported for HTML');
},
storybook: require.requireActual('@storybook/html'),
storybook,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import runWithRequireContext from '../require_context';
import configure from '../configure';
import hasDependency from '../hasDependency';
import loadConfig from '../config-loader';

function test(options) {
return options.framework === 'react' || (!options.framework && hasDependency('@storybook/react'));
}

function load(options) {
const appOptions = require.requireActual('@storybook/react/options').default;
const { configPath, config } = options;
const frameworkOptions = '@storybook/react/options';
const storybook = require.requireActual('@storybook/react');

const { content, contextOpts } = loadConfig({
configDirPath: options.configPath,
appOptions,
});

runWithRequireContext(content, contextOpts);
configure({ configPath, config, frameworkOptions, storybook });

return {
framework: 'react',
renderTree: require.requireActual('./renderTree').default,
renderShallowTree: require.requireActual('./renderShallowTree').default,
storybook: require.requireActual('@storybook/react'),
storybook,
};
}

Expand Down
15 changes: 13 additions & 2 deletions addons/storyshots/storyshots-core/src/frameworks/rn/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,22 @@ function test(options) {
);
}

function configure(options, storybook) {
const { configPath = 'storybook', config } = options;

if (config && typeof config === 'function') {
config(storybook);
return;
}

const resolvedConfigPath = path.resolve(configPath);
require.requireActual(resolvedConfigPath);
}

function load(options) {
const storybook = require.requireActual('@storybook/react-native');

const configPath = path.resolve(options.configPath || 'storybook');
require.requireActual(configPath);
configure(options, storybook);

return {
renderTree: require('../react/renderTree').default,
Expand Down
16 changes: 6 additions & 10 deletions addons/storyshots/storyshots-core/src/frameworks/vue/loader.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import global from 'global';
import runWithRequireContext from '../require_context';
import hasDependency from '../hasDependency';
import loadConfig from '../config-loader';
import configure from '../configure';

function mockVueToIncludeCompiler() {
jest.mock('vue', () => require.requireActual('vue/dist/vue.common.js'));
Expand All @@ -15,22 +14,19 @@ function load(options) {
global.STORYBOOK_ENV = 'vue';
mockVueToIncludeCompiler();

const appOptions = require.requireActual('@storybook/vue/options').default;
const { configPath, config } = options;
const frameworkOptions = '@storybook/vue/options';
const storybook = require.requireActual('@storybook/vue');

const { content, contextOpts } = loadConfig({
configDirPath: options.configPath,
appOptions,
});

runWithRequireContext(content, contextOpts);
configure({ configPath, config, frameworkOptions, storybook });

return {
framework: 'vue',
renderTree: require.requireActual('./renderTree').default,
renderShallowTree: () => {
throw new Error('Shallow renderer is not supported for vue');
},
storybook: require.requireActual('@storybook/vue'),
storybook,
};
}

Expand Down
10 changes: 5 additions & 5 deletions addons/storyshots/storyshots-core/src/test-bodies.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'jest-specific-snapshot';

export const snapshotWithOptions = options => ({
export const snapshotWithOptions = (options = {}) => ({
story,
context,
renderTree,
Expand All @@ -27,7 +27,7 @@ export const snapshotWithOptions = options => ({
return match(result);
};

export const multiSnapshotWithOptions = options => ({
export const multiSnapshotWithOptions = (options = {}) => ({
story,
context,
renderTree,
Expand All @@ -45,7 +45,7 @@ export function shallowSnapshot({ story, context, renderShallowTree, options = {
expect(result).toMatchSnapshot();
}

export const renderWithOptions = options => ({ story, context, renderTree }) => {
export const renderWithOptions = (options = {}) => ({ story, context, renderTree }) => {
const result = renderTree(story, context, options);

if (typeof result.then === 'function') {
Expand All @@ -55,6 +55,6 @@ export const renderWithOptions = options => ({ story, context, renderTree }) =>
return undefined;
};

export const renderOnly = renderWithOptions({});
export const renderOnly = renderWithOptions();

export const snapshot = snapshotWithOptions({});
export const snapshot = snapshotWithOptions();
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Another Button with some emoji 1`] = `
<button
className="css-1qwzad5"
onClick={[Function]}
>
<span
aria-label="so cool"
role="img"
>
😀 😎 👍 💯
</span>
</button>
`;

exports[`Storyshots Another Button with text 1`] = `
<button
className="css-1qwzad5"
onClick={[Function]}
>
Hello Button
</button>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Another Button with some emoji 1`] = `
<button
className="css-1qwzad5"
onClick={[Function]}
>
<span
aria-label="so cool"
role="img"
>
😀 😎 👍 💯
</span>
</button>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots Another Button with text 1`] = `
<button
className="css-1qwzad5"
onClick={[Function]}
>
Hello Button
</button>
`;
Loading