Skip to content

Commit

Permalink
Merge pull request #3757 from storybooks/storyshots-remove-require-co…
Browse files Browse the repository at this point in the history
…ntext

Storyshots - Replace require_context.js with babel-plugin-require-context-hook
  • Loading branch information
Hypnosphi authored Jun 16, 2018
2 parents b169f13 + 34a4a08 commit 5468468
Show file tree
Hide file tree
Showing 27 changed files with 139 additions and 206 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"presets": ["env", "stage-0", "react"],
"env": {
"test": {
"plugins": ["require-context-hook"]
},
"plugins": [
"emotion",
"babel-plugin-macros",
Expand Down
13 changes: 10 additions & 3 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
- [Keyboard shortcuts moved](#keyboard-shortcuts-moved)
- [Removed addWithInfo](#removed-add-with-info)
- [Removed RN addons](#removed-rn-addons)
- [Storyshots imageSnapshot test function moved to a separate package](#storyshots-imagesnapshot-moved)
- [Storyshots changes](#storyshots-changes)
- [From version 3.3.x to 3.4.x](#from-version-33x-to-34x)
- [From version 3.2.x to 3.3.x](#from-version-32x-to-33x)
Expand Down Expand Up @@ -44,8 +43,16 @@ The `@storybook/react-native` had built-in addons (`addon-actions` and `addon-li

### Storyshots Changes

1. `imageSnapshot` test function was extracted from `addon-storyshots` and moved to a new package - `addon-storyshots-puppeteer` that now will be dependant on puppeteer
2. `getSnapshotFileName` export was replaced with the `Stories2SnapsConverter` class that now can be overridden for a custom implementation of the snapshot-name generation
1. `imageSnapshot` test function was extracted from `addon-storyshots`
and moved to a new package - `addon-storyshots-puppeteer` that now will
be dependant on puppeteer. [README](https://github.com/storybooks/storybook/tree/master/addons/storyshots/storyshots-puppeteer)
2. `getSnapshotFileName` export was replaced with the `Stories2SnapsConverter`
class that now can be overridden for a custom implementation of the
snapshot-name generation. [README](https://github.com/storybooks/storybook/tree/master/addons/storyshots/storyshots-core#stories2snapsconverter)
3. Storybook that was configured with Webpack's `require.context()` feature
will need to add a babel plugin to polyfill this functionality.
A possible plugin might be [babel-plugin-require-context-hook](https://github.com/smrq/babel-plugin-require-context-hook).
[README](https://github.com/storybooks/storybook/tree/master/addons/storyshots/storyshots-core#configure-jest-to-work-with-webpacks-requirecontext)

## From version 3.3.x to 3.4.x

Expand Down
48 changes: 48 additions & 0 deletions addons/storyshots/storyshots-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,54 @@ If you aren't familiar with Jest, here are some resources:

> Note: If you use React 16, you'll need to follow [these additional instructions](https://github.com/facebook/react/issues/9102#issuecomment-283873039).
### Configure Jest to work with Webpack's [require.context()](https://webpack.js.org/guides/dependency-management/#require-context)

Sometimes it's useful to configure Storybook with Webpack's require.context feature:

```js
import { configure } from '@storybook/react';

const req = require.context('../stories', true, /.stories.js$/); // <- import all the stories at once

function loadStories() {
req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
```

The problem here is that it will work only during the build with webpack,
other tools may lack this feature. Since Storyshot is running under Jest,
we need to polyfill this functionality to work with Jest. The easiest
way is to integrate it to babel. One of the possible babel plugins to
polyfill this functionality might be
[babel-plugin-require-context-hook](https://github.com/smrq/babel-plugin-require-context-hook).

To register it, add the following to your jest setup:

```js
import registerRequireContextHook from 'babel-plugin-require-context-hook/register';
registerRequireContextHook();
```

And after, add the plugin to `.babelrc`:

```json
{
"presets": ["..."],
"plugins": ["..."],
"env": {
"test": {
"plugins": ["require-context-hook"]
}
}
}
```

Make sure **not** to include this babel plugin in the config
environment that applies to webpack, otherwise it may
replace a real `require.context` functionality.

### Configure Jest for React
StoryShots addon for React is dependent on [react-test-renderer](https://github.com/facebook/react/tree/master/packages/react-test-renderer), but
[doesn't](#deps-issue) install it, so you need to install it separately.
Expand Down
4 changes: 0 additions & 4 deletions addons/storyshots/storyshots-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
},
"dependencies": {
"@storybook/addons": "4.0.0-alpha.9",
"@storybook/core": "4.0.0-alpha.9",
"babel-runtime": "^6.26.0",
"glob": "^7.1.2",
"global": "^4.3.2",
Expand All @@ -31,8 +30,5 @@
"@storybook/react": "4.0.0-alpha.9",
"enzyme-to-json": "^3.3.4",
"react": "^16.4.0"
},
"peerDependencies": {
"babel-core": "^6.26.0 || ^7.0.0-0"
}
}
46 changes: 46 additions & 0 deletions addons/storyshots/storyshots-core/src/api/ensureOptionsDefaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { snapshotWithOptions } from '../test-bodies';
import Stories2SnapsConverter from '../Stories2SnapsConverter';

const ignore = ['**/node_modules/**'];
const defaultStories2SnapsConverter = new Stories2SnapsConverter();

function getIntegrityOptions({ integrityOptions }) {
if (integrityOptions === false) {
return false;
}

if (typeof integrityOptions !== 'object') {
return false;
}

return {
...integrityOptions,
ignore: [...ignore, ...(integrityOptions.ignore || [])],
absolute: true,
};
}

function ensureOptionsDefaults(options) {
const {
suite = 'Storyshots',
storyNameRegex,
storyKindRegex,
renderer,
serializer,
stories2snapsConverter = defaultStories2SnapsConverter,
test: testMethod = snapshotWithOptions({ renderer, serializer }),
} = options;

const integrityOptions = getIntegrityOptions(options);

return {
suite,
storyNameRegex,
storyKindRegex,
stories2snapsConverter,
testMethod,
integrityOptions,
};
}

export default ensureOptionsDefaults;
19 changes: 0 additions & 19 deletions addons/storyshots/storyshots-core/src/api/getIntegrityOptions.js

This file was deleted.

28 changes: 1 addition & 27 deletions addons/storyshots/storyshots-core/src/api/index.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,14 @@
import global, { describe } from 'global';
import addons, { mockChannel } from '@storybook/addons';
import ensureOptionsDefaults from './ensureOptionsDefaults';
import snapshotsTests from './snapshotsTestsTemplate';
import integrityTest from './integrityTestTemplate';
import getIntegrityOptions from './getIntegrityOptions';
import loadFramework from '../frameworks/frameworkLoader';
import Stories2SnapsConverter from '../Stories2SnapsConverter';
import { snapshotWithOptions } from '../test-bodies';

global.STORYBOOK_REACT_CLASSES = global.STORYBOOK_REACT_CLASSES || {};

const defaultStories2SnapsConverter = new Stories2SnapsConverter();
const methods = ['beforeAll', 'beforeEach', 'afterEach', 'afterAll'];

function ensureOptionsDefaults(options) {
const {
suite = 'Storyshots',
storyNameRegex,
storyKindRegex,
renderer,
serializer,
stories2snapsConverter = defaultStories2SnapsConverter,
test: testMethod = snapshotWithOptions({ renderer, serializer }),
} = options;

const integrityOptions = getIntegrityOptions(options);

return {
suite,
storyNameRegex,
storyKindRegex,
stories2snapsConverter,
testMethod,
integrityOptions,
};
}

function callTestMethodGlobals(testMethod) {
methods.forEach(method => {
if (typeof testMethod[method] === 'function') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ function load(options) {
setupAngularJestPreset();

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

configure({ configPath, config, frameworkOptions, storybook });
configure({ configPath, config, storybook });

return {
framework: 'angular',
Expand Down
43 changes: 0 additions & 43 deletions addons/storyshots/storyshots-core/src/frameworks/config-loader.js

This file was deleted.

25 changes: 15 additions & 10 deletions addons/storyshots/storyshots-core/src/frameworks/configure.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import loadConfig from './config-loader';
import runWithRequireContext from './require_context';
import fs from 'fs';
import path from 'path';

function getConfigPathParts(configPath) {
const resolvedConfigPath = path.resolve(configPath);

if (fs.lstatSync(resolvedConfigPath).isDirectory()) {
return path.join(resolvedConfigPath, 'config.js');
}

return resolvedConfigPath;
}

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

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

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

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

runWithRequireContext(content, contextOpts);
require.requireActual(resolvedConfigPath);
}

export default configure;
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ function load(options) {
global.STORYBOOK_ENV = 'html';

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

configure({ configPath, config, frameworkOptions, storybook });
configure({ configPath, config, storybook });

return {
framework: 'html',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ function test(options) {

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

configure({ configPath, config, frameworkOptions, storybook });
configure({ configPath, config, storybook });

return {
framework: 'react',
Expand Down
Loading

0 comments on commit 5468468

Please sign in to comment.