diff --git a/addons/storyshots/README.md b/addons/storyshots/README.md index 813db6023f9f..6416a4f4bb5e 100644 --- a/addons/storyshots/README.md +++ b/addons/storyshots/README.md @@ -145,6 +145,10 @@ Just render the story, don't check the output at all (useful if you just want to Like the default, but allows you to specify a set of options for the test renderer. [See for example here](https://github.com/storybooks/storybook/blob/b915b5439786e0edb17d7f5ab404bba9f7919381/examples/test-cra/src/storyshots.test.js#L14-L16). +### `multiSnapshotWithOptions(options)` + +Like `snapshotWithOptions`, but generate a separate snapshot file for each stories file rather than a single monolithic file (as is the convention in Jest). This makes it dramatically easier to review changes. + ### `shallowSnapshot` Take a snapshot of a shallow-rendered version of the component. diff --git a/addons/storyshots/package.json b/addons/storyshots/package.json index b61abc267705..40b6eed59f2d 100644 --- a/addons/storyshots/package.json +++ b/addons/storyshots/package.json @@ -11,11 +11,14 @@ "scripts": { "build-storybook": "build-storybook", "prepublish": "babel ./src --out-dir ./dist", - "storybook": "start-storybook -p 6006" + "storybook": "start-storybook -p 6006", + "example": "jest storyshot.test" }, "dependencies": { "babel-runtime": "^6.23.0", + "glob": "^7.1.2", "global": "^4.3.2", + "jest-specific-snapshot": "^0.2.0", "prop-types": "^15.5.10", "read-pkg-up": "^2.0.0" }, @@ -24,11 +27,14 @@ "@storybook/channels": "^3.2.0", "@storybook/react": "^3.2.8", "babel-cli": "^6.24.1", + "babel-jest": "^20.0.3", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.0", "babel-preset-react": "^6.24.1", "react": "^15.6.1", - "react-dom": "^15.6.1" + "react-dom": "^15.6.1", + "jest": "^20.0.4", + "jest-cli": "^20.0.4" }, "peerDependencies": { "@storybook/addons": "^3.2.6", diff --git a/addons/storyshots/src/index.js b/addons/storyshots/src/index.js index 245b28a9b78f..3da1bc04e098 100644 --- a/addons/storyshots/src/index.js +++ b/addons/storyshots/src/index.js @@ -1,4 +1,6 @@ import path from 'path'; +import fs from 'fs'; +import glob from 'glob'; import global, { describe, it } from 'global'; import readPkgUp from 'read-pkg-up'; import addons from '@storybook/addons'; @@ -6,8 +8,15 @@ import addons from '@storybook/addons'; import runWithRequireContext from './require_context'; import createChannel from './storybook-channel-mock'; import { snapshot } from './test-bodies'; +import { getPossibleStoriesFiles } from './utils'; -export { snapshotWithOptions, snapshot, shallowSnapshot, renderOnly } from './test-bodies'; +export { + snapshot, + multiSnapshotWithOptions, + snapshotWithOptions, + shallowSnapshot, + renderOnly, +} from './test-bodies'; let storybook; let configPath; @@ -48,6 +57,7 @@ export default function testStorySnapshots(options = {}) { runWithRequireContext(content, contextOpts); } else if (isRNStorybook) { storybook = require.requireActual('@storybook/react-native'); + configPath = path.resolve(options.configPath || 'storybook'); require.requireActual(configPath); } else { @@ -70,13 +80,15 @@ export default function testStorySnapshots(options = {}) { // eslint-disable-next-line for (const group of stories) { - if (options.storyKindRegex && !group.kind.match(options.storyKindRegex)) { + const { fileName, kind } = group; + + if (options.storyKindRegex && !kind.match(options.storyKindRegex)) { // eslint-disable-next-line continue; } describe(suite, () => { - describe(group.kind, () => { + describe(kind, () => { // eslint-disable-next-line for (const story of group.stories) { if (options.storyNameRegex && !story.name.match(options.storyNameRegex)) { @@ -85,7 +97,7 @@ export default function testStorySnapshots(options = {}) { } it(story.name, () => { - const context = { kind: group.kind, story: story.name }; + const context = { fileName, kind, story: story.name }; options.test({ story, context }); }); } @@ -93,3 +105,16 @@ export default function testStorySnapshots(options = {}) { }); } } + +describe('Storyshots Integrity', () => { + describe('Abandoned Storyshots', () => { + const storyshots = glob.sync('**/*.storyshot'); + + const abandonedStoryshots = storyshots.filter(fileName => { + const possibleStoriesFiles = getPossibleStoriesFiles(fileName); + return !possibleStoriesFiles.some(fs.existsSync); + }); + + expect(abandonedStoryshots).toHaveLength(0); + }); +}); diff --git a/addons/storyshots/src/test-bodies.js b/addons/storyshots/src/test-bodies.js index 48362bca93c1..bf71ca3f4994 100644 --- a/addons/storyshots/src/test-bodies.js +++ b/addons/storyshots/src/test-bodies.js @@ -1,12 +1,40 @@ import renderer from 'react-test-renderer'; import shallow from 'react-test-renderer/shallow'; +import 'jest-specific-snapshot'; +import { getStoryshotFile } from './utils'; -export const snapshotWithOptions = options => ({ story, context }) => { +function getRenderedTree(story, context, options) { const storyElement = story.render(context); - const tree = renderer.create(storyElement, options).toJSON(); + return renderer.create(storyElement, options).toJSON(); +} + +function getSnapshotFileName(context) { + const fileName = context.fileName; + + if (!fileName) { + return null; + } + + return getStoryshotFile(fileName); +} + +export const snapshotWithOptions = options => ({ story, context }) => { + const tree = getRenderedTree(story, context, options); expect(tree).toMatchSnapshot(); }; +export const multiSnapshotWithOptions = options => ({ story, context }) => { + const tree = getRenderedTree(story, context, options); + const snapshotFileName = getSnapshotFileName(context); + + if (!snapshotFileName) { + expect(tree).toMatchSnapshot(); + return; + } + + expect(tree).toMatchSpecificSnapshot(snapshotFileName); +}; + export const snapshot = snapshotWithOptions({}); export function shallowSnapshot({ story, context }) { diff --git a/addons/storyshots/src/utils.js b/addons/storyshots/src/utils.js new file mode 100644 index 000000000000..86f2d3f92941 --- /dev/null +++ b/addons/storyshots/src/utils.js @@ -0,0 +1,15 @@ +import path from 'path'; + +export function getStoryshotFile(fileName) { + const { dir, name } = path.parse(fileName); + return path.format({ dir: path.join(dir, '__snapshots__'), name, ext: '.storyshot' }); +} + +export function getPossibleStoriesFiles(storyshotFile) { + const { dir, name } = path.parse(storyshotFile); + + return [ + path.format({ dir: path.dirname(dir), name, ext: '.js' }), + path.format({ dir: path.dirname(dir), name, ext: '.jsx' }), + ]; +} diff --git a/addons/storyshots/stories/directly_required/__snapshots__/index.storyshot b/addons/storyshots/stories/directly_required/__snapshots__/index.storyshot new file mode 100644 index 000000000000..354841be656e --- /dev/null +++ b/addons/storyshots/stories/directly_required/__snapshots__/index.storyshot @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Another Button with some emoji 1`] = ` + +`; + +exports[`Storyshots Another Button with text 1`] = ` + +`; diff --git a/addons/storyshots/stories/required_with_context/__snapshots__/Button.stories.storyshot b/addons/storyshots/stories/required_with_context/__snapshots__/Button.stories.storyshot new file mode 100644 index 000000000000..56b21f7fdec4 --- /dev/null +++ b/addons/storyshots/stories/required_with_context/__snapshots__/Button.stories.storyshot @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Button with some emoji 1`] = ` + +`; + +exports[`Storyshots Button with text 1`] = ` + +`; diff --git a/addons/storyshots/stories/required_with_context/__snapshots__/Welcome.stories.storyshot b/addons/storyshots/stories/required_with_context/__snapshots__/Welcome.stories.storyshot new file mode 100644 index 000000000000..bc6abe86a6e7 --- /dev/null +++ b/addons/storyshots/stories/required_with_context/__snapshots__/Welcome.stories.storyshot @@ -0,0 +1,104 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Welcome to Storybook 1`] = ` +
+

+ Welcome to storybook +

+

+ This is a UI component dev environment for your app. +

+

+ We've added some basic stories inside the + + + src/stories + + + directory. +
+ A story is a single state of one or more UI components. You can have as many stories as you want. +
+ (Basically a story is like a visual test case.) +

+

+ See these sample + + + stories + + + for a component called + + + Button + + . +

+

+ Just like that, you can add your own components as stories. +
+ You can also edit those components and see changes right away. +
+ (Try editing the + + Button + + stories located at + + src/stories/index.js + + .) +

+

+ Usually we create stories with smaller UI components in the app. +
+ Have a look at the + + + Writing Stories + + + section in our documentation. +

+

+ + NOTE: + +
+ Have a look at the + + + .storybook/webpack.config.js + + + to add webpack loaders and plugins you are using in this project. +

+
+`; diff --git a/addons/storyshots/stories/storyshot.test.js b/addons/storyshots/stories/storyshot.test.js new file mode 100644 index 000000000000..6e5a0fea82c2 --- /dev/null +++ b/addons/storyshots/stories/storyshot.test.js @@ -0,0 +1,8 @@ +import path from 'path'; +import initStoryshots, { multiSnapshotWithOptions } from '../src'; + +initStoryshots({ + framework: 'react', + configPath: path.join(__dirname, '..', '.storybook'), + test: multiSnapshotWithOptions({}), +}); diff --git a/app/react-native/src/preview/index.js b/app/react-native/src/preview/index.js index 04edb17cbe16..ece4bd2319c3 100644 --- a/app/react-native/src/preview/index.js +++ b/app/react-native/src/preview/index.js @@ -23,7 +23,10 @@ export default class Preview { if (module && module.hot) { // TODO remove the kind on dispose } - return new StoryKindApi(this._stories, this._addons, this._decorators, kind); + + const fileName = module ? module.filename : null; + + return new StoryKindApi(this._stories, this._addons, this._decorators, kind, fileName); } setAddon(addon) { @@ -44,11 +47,14 @@ export default class Preview { getStorybook() { return this._stories.getStoryKinds().map(kind => { + const fileName = this._stories.getStoryFileName(kind); + const stories = this._stories.getStories(kind).map(name => { const render = this._stories.getStory(kind, name); return { name, render }; }); - return { kind, stories }; + + return { kind, fileName, stories }; }); } diff --git a/app/react-native/src/preview/story_kind.js b/app/react-native/src/preview/story_kind.js index edec71a5d483..01024277cac4 100644 --- a/app/react-native/src/preview/story_kind.js +++ b/app/react-native/src/preview/story_kind.js @@ -1,10 +1,11 @@ /* eslint no-underscore-dangle: 0 */ export default class StoryKindApi { - constructor(stories, addons, decorators, kind) { + constructor(stories, addons, decorators, kind, fileName) { this.kind = kind; this._stories = stories; this._decorators = decorators.slice(); + this._fileName = fileName; Object.assign(this, addons); } @@ -15,7 +16,7 @@ export default class StoryKindApi { add(story, fn) { const decorated = this._decorate(fn); - this._stories.addStory(this.kind, story, decorated); + this._stories.addStory(this.kind, story, decorated, this._fileName); return this; } diff --git a/app/react-native/src/preview/story_store.js b/app/react-native/src/preview/story_store.js index 07e91876b125..f202ab8c6b2b 100644 --- a/app/react-native/src/preview/story_store.js +++ b/app/react-native/src/preview/story_store.js @@ -9,11 +9,12 @@ export default class StoryStore extends EventEmitter { this._data = {}; } - addStory(kind, name, fn) { + addStory(kind, name, fn, fileName) { count += 1; if (!this._data[kind]) { this._data[kind] = { kind, + fileName, index: count, stories: {}, }; @@ -46,6 +47,15 @@ export default class StoryStore extends EventEmitter { .map(info => info.name); } + getStoryFileName(kind) { + const storiesKind = this._data[kind]; + if (!storiesKind) { + return null; + } + + return storiesKind.fileName; + } + getStory(kind, name) { const storiesKind = this._data[kind]; if (!storiesKind) { diff --git a/app/react/src/client/preview/client_api.js b/app/react/src/client/preview/client_api.js index b711d4e96e0c..85d448683ff9 100644 --- a/app/react/src/client/preview/client_api.js +++ b/app/react/src/client/preview/client_api.js @@ -76,8 +76,10 @@ export default class ClientApi { getStory ); + const fileName = m ? m.filename : null; + // Add the fully decorated getStory function. - this._storyStore.addStory(kind, storyName, fn); + this._storyStore.addStory(kind, storyName, fn, fileName); return api; }; @@ -91,11 +93,14 @@ export default class ClientApi { getStorybook() { return this._storyStore.getStoryKinds().map(kind => { + const fileName = this._storyStore.getStoryFileName(kind); + const stories = this._storyStore.getStories(kind).map(name => { const render = this._storyStore.getStory(kind, name); return { name, render }; }); - return { kind, stories }; + + return { kind, fileName, stories }; }); } } diff --git a/app/react/src/client/preview/client_api.test.js b/app/react/src/client/preview/client_api.test.js index 529579003cdb..8a83cbcba977 100644 --- a/app/react/src/client/preview/client_api.test.js +++ b/app/react/src/client/preview/client_api.test.js @@ -7,8 +7,8 @@ class StoryStore { this.stories = []; } - addStory(kind, story, fn) { - this.stories.push({ kind, story, fn }); + addStory(kind, story, fn, fileName) { + this.stories.push({ kind, story, fn, fileName }); } getStoryKinds() { @@ -29,6 +29,11 @@ class StoryStore { }, []); } + getStoryFileName(kind) { + const story = this.stories.find(info => info.kind === kind); + return story ? story.fileName : null; + } + getStory(kind, name) { return this.stories.reduce((fn, info) => { if (!fn && info.kind === kind && info.story === name) { @@ -219,16 +224,53 @@ describe('preview.client_api', () => { 'story-2.1': () => 'story-2.1', 'story-2.2': () => 'story-2.2', }; - const kind1 = api.storiesOf('kind-1', module); + const kind1 = api.storiesOf('kind-1', { filename: 'kind1.js' }); + kind1.add('story-1.1', functions['story-1.1']); + kind1.add('story-1.2', functions['story-1.2']); + const kind2 = api.storiesOf('kind-2', { filename: 'kind2.js' }); + kind2.add('story-2.1', functions['story-2.1']); + kind2.add('story-2.2', functions['story-2.2']); + const book = api.getStorybook(); + expect(book).toEqual([ + { + kind: 'kind-1', + fileName: 'kind1.js', + stories: [ + { name: 'story-1.1', render: functions['story-1.1'] }, + { name: 'story-1.2', render: functions['story-1.2'] }, + ], + }, + { + kind: 'kind-2', + fileName: 'kind2.js', + stories: [ + { name: 'story-2.1', render: functions['story-2.1'] }, + { name: 'story-2.2', render: functions['story-2.2'] }, + ], + }, + ]); + }); + + it('should return storybook with file names when module with file name provided', () => { + const storyStore = new StoryStore(); + const api = new ClientAPI({ storyStore }); + const functions = { + 'story-1.1': () => 'story-1.1', + 'story-1.2': () => 'story-1.2', + 'story-2.1': () => 'story-2.1', + 'story-2.2': () => 'story-2.2', + }; + const kind1 = api.storiesOf('kind-1', { filename: 'foo' }); kind1.add('story-1.1', functions['story-1.1']); kind1.add('story-1.2', functions['story-1.2']); - const kind2 = api.storiesOf('kind-2', module); + const kind2 = api.storiesOf('kind-2', { filename: 'bar' }); kind2.add('story-2.1', functions['story-2.1']); kind2.add('story-2.2', functions['story-2.2']); const book = api.getStorybook(); expect(book).toEqual([ { kind: 'kind-1', + fileName: 'foo', stories: [ { name: 'story-1.1', render: functions['story-1.1'] }, { name: 'story-1.2', render: functions['story-1.2'] }, @@ -236,6 +278,7 @@ describe('preview.client_api', () => { }, { kind: 'kind-2', + fileName: 'bar', stories: [ { name: 'story-2.1', render: functions['story-2.1'] }, { name: 'story-2.2', render: functions['story-2.2'] }, diff --git a/app/react/src/client/preview/story_store.js b/app/react/src/client/preview/story_store.js index b7051c1ea3be..a82bba34d24d 100644 --- a/app/react/src/client/preview/story_store.js +++ b/app/react/src/client/preview/story_store.js @@ -12,10 +12,11 @@ export default class StoryStore { this._data = {}; } - addStory(kind, name, fn) { + addStory(kind, name, fn, fileName) { if (!this._data[kind]) { this._data[kind] = { kind, + fileName, index: getId(), stories: {}, }; @@ -47,6 +48,15 @@ export default class StoryStore { .map(info => info.name); } + getStoryFileName(kind) { + const storiesKind = this._data[kind]; + if (!storiesKind) { + return null; + } + + return storiesKind.fileName; + } + getStory(kind, name) { const storiesKind = this._data[kind]; if (!storiesKind) { diff --git a/app/react/src/server/babel_config.js b/app/react/src/server/babel_config.js index 8eab74ed4283..6256c660a5e8 100644 --- a/app/react/src/server/babel_config.js +++ b/app/react/src/server/babel_config.js @@ -1,11 +1,9 @@ import fs from 'fs'; import path from 'path'; import JSON5 from 'json5'; +import { console as logger } from 'global'; import defaultConfig from './config/babel'; -// avoid ESLint errors -const logger = console; - function removeReactHmre(presets) { const index = presets.indexOf('react-hmre'); if (index > -1) { diff --git a/app/react/src/server/babel_config.test.js b/app/react/src/server/babel_config.test.js index 7fc9fac65c6c..70001015cfae 100644 --- a/app/react/src/server/babel_config.test.js +++ b/app/react/src/server/babel_config.test.js @@ -1,6 +1,8 @@ import mock from 'mock-fs'; import loadBabelConfig from './babel_config'; +jest.mock('global', () => ({ console: { log: jest.fn(), error: jest.fn(), info: jest.fn() } })); + describe('babel_config', () => { // As the 'fs' is going to be mocked, let's call require.resolve // so the require.cache has the correct route to the file. diff --git a/app/vue/src/client/preview/client_api.js b/app/vue/src/client/preview/client_api.js index 32b10bef8a23..4362755997b8 100644 --- a/app/vue/src/client/preview/client_api.js +++ b/app/vue/src/client/preview/client_api.js @@ -89,8 +89,10 @@ export default class ClientApi { getStory ); + const fileName = m ? m.filename : null; + // Add the fully decorated getStory function. - this._storyStore.addStory(kind, storyName, getDecoratedStory); + this._storyStore.addStory(kind, storyName, getDecoratedStory, fileName); return api; }; @@ -104,11 +106,14 @@ export default class ClientApi { getStorybook() { return this._storyStore.getStoryKinds().map(kind => { + const fileName = this._storyStore.getStoryFileName(kind); + const stories = this._storyStore.getStories(kind).map(name => { const render = this._storyStore.getStory(kind, name); return { name, render }; }); - return { kind, stories }; + + return { kind, fileName, stories }; }); } } diff --git a/app/vue/src/client/preview/client_api.test.js b/app/vue/src/client/preview/client_api.test.js index 484eea98e831..ba7ec39502e8 100644 --- a/app/vue/src/client/preview/client_api.test.js +++ b/app/vue/src/client/preview/client_api.test.js @@ -7,8 +7,8 @@ class StoryStore { this.stories = []; } - addStory(kind, story, fn) { - this.stories.push({ kind, story, fn }); + addStory(kind, story, fn, fileName) { + this.stories.push({ kind, story, fn, fileName }); } getStoryKinds() { @@ -29,6 +29,11 @@ class StoryStore { }, []); } + getStoryFileName(kind) { + const story = this.stories.find(info => info.kind === kind); + return story ? story.fileName : null; + } + getStory(kind, name) { return this.stories.reduce((fn, info) => { if (!fn && info.kind === kind && info.story === name) { @@ -221,16 +226,53 @@ describe('preview.client_api', () => { 'story-2.1': () => 'story-2.1', 'story-2.2': () => 'story-2.2', }; - const kind1 = api.storiesOf('kind-1', module); + const kind1 = api.storiesOf('kind-1', { filename: 'kind1.js' }); + kind1.add('story-1.1', functions['story-1.1']); + kind1.add('story-1.2', functions['story-1.2']); + const kind2 = api.storiesOf('kind-2', { filename: 'kind2.js' }); + kind2.add('story-2.1', functions['story-2.1']); + kind2.add('story-2.2', functions['story-2.2']); + const book = api.getStorybook(); + expect(book).toEqual([ + { + kind: 'kind-1', + fileName: 'kind1.js', + stories: [ + { name: 'story-1.1', render: functions['story-1.1'] }, + { name: 'story-1.2', render: functions['story-1.2'] }, + ], + }, + { + kind: 'kind-2', + fileName: 'kind2.js', + stories: [ + { name: 'story-2.1', render: functions['story-2.1'] }, + { name: 'story-2.2', render: functions['story-2.2'] }, + ], + }, + ]); + }); + + it('should return storybook with file names when module with file name provided', () => { + const storyStore = new StoryStore(); + const api = new ClientAPI({ storyStore }); + const functions = { + 'story-1.1': () => 'story-1.1', + 'story-1.2': () => 'story-1.2', + 'story-2.1': () => 'story-2.1', + 'story-2.2': () => 'story-2.2', + }; + const kind1 = api.storiesOf('kind-1', { filename: 'foo' }); kind1.add('story-1.1', functions['story-1.1']); kind1.add('story-1.2', functions['story-1.2']); - const kind2 = api.storiesOf('kind-2', module); + const kind2 = api.storiesOf('kind-2', { filename: 'bar' }); kind2.add('story-2.1', functions['story-2.1']); kind2.add('story-2.2', functions['story-2.2']); const book = api.getStorybook(); expect(book).toEqual([ { kind: 'kind-1', + fileName: 'foo', stories: [ { name: 'story-1.1', render: functions['story-1.1'] }, { name: 'story-1.2', render: functions['story-1.2'] }, @@ -238,6 +280,7 @@ describe('preview.client_api', () => { }, { kind: 'kind-2', + fileName: 'bar', stories: [ { name: 'story-2.1', render: functions['story-2.1'] }, { name: 'story-2.2', render: functions['story-2.2'] }, diff --git a/app/vue/src/client/preview/story_store.js b/app/vue/src/client/preview/story_store.js index b7051c1ea3be..a82bba34d24d 100644 --- a/app/vue/src/client/preview/story_store.js +++ b/app/vue/src/client/preview/story_store.js @@ -12,10 +12,11 @@ export default class StoryStore { this._data = {}; } - addStory(kind, name, fn) { + addStory(kind, name, fn, fileName) { if (!this._data[kind]) { this._data[kind] = { kind, + fileName, index: getId(), stories: {}, }; @@ -47,6 +48,15 @@ export default class StoryStore { .map(info => info.name); } + getStoryFileName(kind) { + const storiesKind = this._data[kind]; + if (!storiesKind) { + return null; + } + + return storiesKind.fileName; + } + getStory(kind, name) { const storiesKind = this._data[kind]; if (!storiesKind) { diff --git a/examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap b/examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot similarity index 99% rename from examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap rename to examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot index 7a2ec1259fe3..3b27e86a5a5c 100644 --- a/examples/cra-kitchen-sink/src/__snapshots__/storyshots.test.js.snap +++ b/examples/cra-kitchen-sink/src/stories/__snapshots__/index.storyshot @@ -2489,29 +2489,6 @@ exports[`Storyshots Cells/Molecules/Atoms.more with text2 1`] = ` `; -exports[`Storyshots Navigation Menu link 1`] = ` -
- - Menu link item - -
-`; - -exports[`Storyshots Navigation Routed link 1`] = ` - - Try clicking with different mouse buttons and modifier keys (shift/ctrl/alt/cmd) - -`; - exports[`Storyshots Some really long story kind description with text 1`] = `
+ + Menu link item + +
+`; + +exports[`Storyshots Navigation Routed link 1`] = ` + + Try clicking with different mouse buttons and modifier keys (shift/ctrl/alt/cmd) + +`; diff --git a/examples/cra-kitchen-sink/src/storyshots.test.js b/examples/cra-kitchen-sink/src/storyshots.test.js index 51cce11163f0..e0fd0a58cd40 100644 --- a/examples/cra-kitchen-sink/src/storyshots.test.js +++ b/examples/cra-kitchen-sink/src/storyshots.test.js @@ -1,4 +1,4 @@ -import initStoryshots, { snapshotWithOptions } from '@storybook/addon-storyshots'; +import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots'; import path from 'path'; function createNodeMock(element) { @@ -11,7 +11,7 @@ function createNodeMock(element) { initStoryshots({ framework: 'react', configPath: path.join(__dirname, '..', '.storybook'), - test: snapshotWithOptions({ + test: multiSnapshotWithOptions({ createNodeMock, }), }); diff --git a/lib/ui/src/modules/ui/components/layout/index.test.js b/lib/ui/src/modules/ui/components/layout/index.test.js index 76717982f48f..9578d947da39 100755 --- a/lib/ui/src/modules/ui/components/layout/index.test.js +++ b/lib/ui/src/modules/ui/components/layout/index.test.js @@ -28,9 +28,9 @@ describe('manager.ui.components.layout.index', () => { test('should only render preview', () => { const wrap = shallow( 'LeftPanel'} downPanel={() => 'DownPanel'} @@ -51,8 +51,8 @@ describe('manager.ui.components.layout.index', () => { 'LeftPanel'} downPanel={() => 'DownPanel'} preview={() => 'Preview'}