From 1623555941416434a5d6b6653f402dd7bfd019d0 Mon Sep 17 00:00:00 2001 From: Aruna Herath Date: Wed, 21 Sep 2016 18:24:27 +0530 Subject: [PATCH 1/3] =?UTF-8?q?Name=20the=20tool=20=E2=80=9Cstoryshots?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/{testsnapshots.js => run_storyshots.js} | 0 package.json | 7 +++---- 2 files changed, 3 insertions(+), 4 deletions(-) rename bin/{testsnapshots.js => run_storyshots.js} (100%) diff --git a/bin/testsnapshots.js b/bin/run_storyshots.js similarity index 100% rename from bin/testsnapshots.js rename to bin/run_storyshots.js diff --git a/package.json b/package.json index 094168f3b16d..dd0363549538 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@kadira/storybook-snapshot-test", - "version": "1.0.0", + "name": "@kadira/storyshots", + "version": "0.0.0", "description": "Compare stories to saved snapshots", "repository": { "type": "git", @@ -11,7 +11,7 @@ "mocha": "--require scripts/mocha_runner src/**/__tests__/**/*.js" }, "bin": { - "testsnapshots": "./bin/testsnapshots.js" + "storyshots": "./bin/run_storyshots.js" }, "scripts": { "prepublish": ". ./scripts/prepublish.sh", @@ -20,7 +20,6 @@ "testonly": "mocha $npm_package_options_mocha", "test": "npm run lint && npm run testonly", "test-watch": "npm run testonly -- --watch --watch-extensions js", - "testsnapshots": "jasmine" }, "peerDependencies": { "@kadira/storybook": "*", From 6a95eae4891785bfdc55b7d2f43df6a7a5f63510 Mon Sep 17 00:00:00 2001 From: Aruna Herath Date: Wed, 21 Sep 2016 21:45:17 +0530 Subject: [PATCH 2/3] Directly using the babel config module storybook uses --- package.json | 6 ++-- src/cli.js | 8 +++-- src/config/default.js | 39 -------------------- src/config/index.js | 84 ------------------------------------------- 4 files changed, 8 insertions(+), 129 deletions(-) delete mode 100644 src/config/default.js delete mode 100644 src/config/index.js diff --git a/package.json b/package.json index dd0363549538..4a916dee0773 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ "lintfix": "eslint ./src --fix", "testonly": "mocha $npm_package_options_mocha", "test": "npm run lint && npm run testonly", - "test-watch": "npm run testonly -- --watch --watch-extensions js", + "test-watch": "npm run testonly -- --watch --watch-extensions js" }, "peerDependencies": { - "@kadira/storybook": "*", - "react": "*" + "@kadira/storybook": "^2.16.0", + "react": "^15.2.1" }, "devDependencies": { "nodemon": "1.7.x", diff --git a/src/cli.js b/src/cli.js index 3d0a3a935eb4..29a6483a1bbe 100644 --- a/src/cli.js +++ b/src/cli.js @@ -1,10 +1,10 @@ import runTests from './test_runner'; -import loadConfig from './config'; import { getStorybook } from '@kadira/storybook'; import path from 'path'; import program from 'commander'; import chokidar from 'chokidar'; import EventEmitter from 'events'; +import loadBabelConfig from '@kadira/storybook/dist/server/babel_config'; const { jasmine } = global; @@ -22,8 +22,10 @@ const configDir = program.configDir || './.storybook'; const configPath = path.resolve(`${configDir}`, 'config'); -const babelConfig = loadConfig(configDir); -babelConfig.babelrc = false; +const babelConfig = loadBabelConfig(configDir); + +// cacheDir is webpack babel loader specific. We don't run webpack. +delete babelConfig.cacheDirectory; require('babel-register')(babelConfig); require('babel-polyfill'); diff --git a/src/config/default.js b/src/config/default.js deleted file mode 100644 index c713ed5e6016..000000000000 --- a/src/config/default.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -module.exports = { - // Don't try to find .babelrc because we want to force this configuration. - babelrc: false, - presets: [ - // let, const, destructuring, classes, modules - require.resolve('babel-preset-es2015'), - // exponentiation - require.resolve('babel-preset-es2016'), - // JSX, Flow - require.resolve('babel-preset-react'), - ], - plugins: [ - // function x(a, b, c,) { } - require.resolve('babel-plugin-syntax-trailing-function-commas'), - // await fetch() - require.resolve('babel-plugin-syntax-async-functions'), - // class { handleClick = () => { } } - require.resolve('babel-plugin-transform-class-properties'), - // { ...todo, completed: true } - require.resolve('babel-plugin-transform-object-rest-spread'), - // function* () { yield 42; yield 43; } - require.resolve('babel-plugin-transform-regenerator'), - // Polyfills the runtime needed for async/await and generators - [require.resolve('babel-plugin-transform-runtime'), { - helpers: false, - polyfill: false, - regenerator: true, - }], - ], -}; diff --git a/src/config/index.js b/src/config/index.js deleted file mode 100644 index 2544d3fd6230..000000000000 --- a/src/config/index.js +++ /dev/null @@ -1,84 +0,0 @@ -import defaultConfig from './default' -import path from 'path'; -import fs from 'fs'; -import JSON5 from 'json5'; - -// avoid ESLint errors -const logger = console; - -function removeReactHmre(presets) { - const index = presets.indexOf('react-hmre'); - if (index > -1) { - presets.splice(index, 1); - } -} - -// Tries to load a .babelrc and returns the parsed object if successful -function loadBabelConfig(babelConfigPath) { - let config; - if (fs.existsSync(babelConfigPath)) { - const content = fs.readFileSync(babelConfigPath, 'utf-8'); - try { - config = JSON5.parse(content); - config.babelrc = false; - logger.info('=> Loading custom .babelrc'); - } catch (e) { - logger.error(`=> Error parsing .babelrc file: ${e.message}`); - throw e; - } - } - - if (!config) return null; - - // Remove react-hmre preset. - // It causes issues with react-storybook. - // We don't really need it. - // Earlier, we fix this by runnign storybook in the production mode. - // But, that hide some useful debug messages. - if (config.presets) { - removeReactHmre(config.presets); - } - - if (config.env && config.env.development && config.env.development.presets) { - removeReactHmre(config.env.development.presets); - } - - return config; -} - -// React Storybook will look in the `configDir` directory -// (inside working directory) if a config path is not provided. -function readConfig(configDir) { - // Search for a .babelrc in the config directory, then the module root - // directory. If found, use that to extend webpack configurations. - let babelConfig = loadBabelConfig(path.resolve(configDir, '.babelrc')); - let inConfigDir = true; - - if (!babelConfig) { - babelConfig = loadBabelConfig('.babelrc'); - inConfigDir = false; - } - - if (babelConfig) { - // If the custom config uses babel's `extends` clause, then replace it with - // an absolute path. `extends` will not work unless we do this. - if (babelConfig.extends) { - babelConfig.extends = inConfigDir ? - path.resolve(configDir, babelConfig.extends) : - path.resolve(babelConfig.extends); - } - return babelConfig; - } - logger.info('=> Using default babel config'); - return defaultConfig; -} - -export default function (configDir) { - const config = readConfig(configDir); - - // Should not read babelrc files anymore because we already have their info - // if they exist - config.babelrc = false; - - return config; -} From 8c9f8a52996fb317354bdb201c25063b219ee291 Mon Sep 17 00:00:00 2001 From: Aruna Herath Date: Thu, 22 Sep 2016 09:55:10 +0530 Subject: [PATCH 3/3] Add polyfills to mimic browser environment and user loaders --- package.json | 1 + src/cli.js | 32 ++++++++++++++++++++------------ src/loaders.js | 14 ++++++++++++++ src/polyfills.js | 23 +++++++++++++++++++++++ 4 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 src/loaders.js create mode 100644 src/polyfills.js diff --git a/package.json b/package.json index 4a916dee0773..207e6ca136a3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "chokidar": "^1.6.0", "jest-diff": "^15.1.0", "jest-snapshot": "^15.1.1", + "jsdom": "^9.5.0", "promptly": "^2.1.0", "react-test-renderer": "^15.3.1", "require-hijack": "^1.2.1" diff --git a/src/cli.js b/src/cli.js index 29a6483a1bbe..4dda49ff95ea 100644 --- a/src/cli.js +++ b/src/cli.js @@ -1,6 +1,7 @@ import runTests from './test_runner'; import { getStorybook } from '@kadira/storybook'; import path from 'path'; +import fs from 'fs'; import program from 'commander'; import chokidar from 'chokidar'; import EventEmitter from 'events'; @@ -16,9 +17,15 @@ program 'Update saved story snapshots interactively') .option('-g, --grep [string]', 'only test stories matching regexp') .option('-w, --watch [boolean]', 'watch file changes and rerun tests') + .option('--polyfills [string]', 'add global polyfills') + .option('--loaders [string]', 'add loaders') .parse(process.argv); -const configDir = program.configDir || './.storybook'; +const { + configDir='./.storybook', + polyfills: polyfillsPath, + loaders: loadersPath, +} = program const configPath = path.resolve(`${configDir}`, 'config'); @@ -30,20 +37,21 @@ delete babelConfig.cacheDirectory; require('babel-register')(babelConfig); require('babel-polyfill'); -const fileExts = ['jpg', 'png', 'gif', 'eot', 'svg', 'ttf', 'woff', 'woff2'] -const moduleExts = ['css', 'scss', 'sass'] +const loaders = require('./loaders'); +if (loadersPath) { + const userLoaders = require(path.resolve(userLoadersPath)); + Object.assign(loaders, userLoaders); +} -fileExts.forEach(ext => { - require.extensions[`.${ext}`] = function () { - return ''; - }; +Object.keys(loaders).forEach(ext => { + const loader = loaders[ext]; + require.extensions[`.${ext}`] = loader; }) -moduleExts.forEach(ext => { - require.extensions[`.${ext}`] = function () { - return {}; - }; -}) +require('./polyfills'); +if (polyfillsPath) { + require(path.resolve(polyfillsPath)); +} async function main () { try { diff --git a/src/loaders.js b/src/loaders.js new file mode 100644 index 000000000000..7849d29c1adb --- /dev/null +++ b/src/loaders.js @@ -0,0 +1,14 @@ +const fileExts = ['jpg', 'png', 'gif', 'eot', 'svg', 'ttf', 'woff', 'woff2'] +const moduleExts = ['css', 'scss', 'sass'] + +const loaders = {} + +fileExts.forEach(ext => { + loaders[ext] = (module, filename) => filename; +}) + +moduleExts.forEach(ext => { + loaders[ext] = () => null +}) + +module.exports = loaders; \ No newline at end of file diff --git a/src/polyfills.js b/src/polyfills.js new file mode 100644 index 000000000000..0827a50d2874 --- /dev/null +++ b/src/polyfills.js @@ -0,0 +1,23 @@ +const jsdom = require('jsdom').jsdom; + +global.document = jsdom(''); +global.window = document.defaultView; +Object.keys(document.defaultView).forEach((property) => { + if (typeof global[property] === 'undefined') { + global[property] = document.defaultView[property]; + } +}); + +global.navigator = { + userAgent: 'node.js' +}; + +global.localStorage = global.window.localStorage = { + _data : {}, + setItem : function(id, val) { return this._data[id] = String(val); }, + getItem : function(id) { return this._data.hasOwnProperty(id) ? this._data[id] : undefined; }, + removeItem : function(id) { return delete this._data[id]; }, + clear : function() { return this._data = {}; } +}; + +window.matchMedia = () => ({ matches: true }); \ No newline at end of file