diff --git a/.circleci/config.yml b/.circleci/config.yml
index 1eb5a6b1b4a4..389a649622dc 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,4 +1,4 @@
-version: 2
+version: 2.1
aliases:
- &defaults
@@ -6,9 +6,6 @@ aliases:
docker:
- image: circleci/node:10
-dependencies:
- pre:
- - yarn global add npm
jobs:
build:
<<: *defaults
@@ -17,7 +14,7 @@ jobs:
- restore_cache:
name: Restore core dependencies cache
keys:
- - core-dependencies-v3-{{ checksum "yarn.lock" }}
+ - core-dependencies-v4-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
command: yarn install
@@ -29,9 +26,11 @@ jobs:
command: yarn bootstrap --core
- save_cache:
name: Cache core dependencies
- key: core-dependencies-v3-{{ checksum "yarn.lock" }}
+ key: core-dependencies-v4-{{ checksum "yarn.lock" }}
paths:
- - ~/.cache/yarn
+ - ~/.cache
+ - node_modules
+ - /root/.cache
- persist_to_workspace:
root: .
paths:
@@ -47,9 +46,6 @@ jobs:
- checkout
- attach_workspace:
at: .
- - run:
- name: Generate static examples
- command: yarn build-storybooks
- run:
name: Run chromatic on the pre-built storybook
command: yarn chromatic
@@ -66,97 +62,50 @@ jobs:
yarn packtracker
examples:
<<: *defaults
+ parallelism: 4
steps:
- checkout
- attach_workspace:
at: .
- run:
- name: Workaround for https://github.com/GoogleChrome/puppeteer/issues/290
- command: sh ./scripts/workaround-puppeteer-issue-290.sh
- - run:
- name: Build react kitchen-sink
- command: |
- cd examples/cra-kitchen-sink
- yarn build-storybook
- - run:
- name: Build react typescript kitchen-sink
- command: |
- cd examples/cra-ts-kitchen-sink
- yarn build-storybook
- - run:
- name: Build vue kitchen-sink
- command: |
- cd examples/vue-kitchen-sink
- yarn build-storybook
- - run:
- name: Build svelte kitchen-sink
- command: |
- cd examples/svelte-kitchen-sink
- yarn build-storybook
- - run:
- name: Build angular-cli
+ name: examples
command: |
- cd examples/angular-cli
- yarn build-storybook
- - run:
- name: Build ember-cli
- command: |
- cd examples/ember-cli
- yarn build-storybook
- - run:
- name: Build polymer-cli
- command: |
- cd examples/polymer-cli
- yarn build-storybook
- - run:
- name: Build marko-cli
- command: |
- cd examples/marko-cli
- yarn build-storybook
- - run:
- name: Build mithril kitchen-sink
- command: |
- cd examples/mithril-kitchen-sink
- yarn build-storybook
- - run:
- name: Build html kitchen-sink
- command: |
- cd examples/html-kitchen-sink
- yarn build-storybook
- - run:
- name: Build riot kitchen-sink
- command: |
- cd examples/riot-kitchen-sink
- yarn build-storybook
- - run:
- name: Build preact kitchen-sink
- command: |
- cd examples/preact-kitchen-sink
- yarn build-storybook
- - run:
- name: Build cra react15
- command: |
- cd examples/cra-react15
- yarn build-storybook
- - run:
- name: Build official-storybook
- command: |
- cd examples/official-storybook
- yarn build-storybook
- # - run:
- # name: Run image snapshots
- # command: yarn test --image
- - store_artifacts:
- path: examples/official-storybook/image-snapshots/__image_snapshots__
- destination: official_storybook_image_snapshots
+ yarn build-storybooks
- persist_to_workspace:
root: .
paths:
+ - built-storybooks
+ e2e:
+ working_directory: /tmp/storybook
+ docker:
+ - image: cypress/base:8
+ environment:
+ TERM: xterm
+ steps:
+ - checkout
+ - attach_workspace:
+ at: .
+ - run:
+ name: install cypress
+ command: yarn cypress install
+ - save_cache:
+ name: Cache core dependencies
+ key: core-dependencies-v4-{{ checksum "yarn.lock" }}
+ paths:
+ - ~/.cache
- node_modules
- - examples
- - addons
- - app
- - lib
+ - /root/.cache
+ - run:
+ name: running example
+ command: yarn serve-storybooks
+ background: true
+ - run:
+ name: await running examples
+ command: yarn await-serve-storybooks
+ - run:
+ name: cypress run
+ command: yarn cypress run
+
smoke-tests:
<<: *defaults
steps:
@@ -253,18 +202,13 @@ jobs:
- restore_cache:
name: Restore core dependencies cache
keys:
- - core-dependencies-v3-{{ checksum "yarn.lock" }}
+ - core-dependencies-v4-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
- command: yarn install
+ command: yarn bootstrap --install
- run:
name: Trigger build
command: ./scripts/build-frontpage.js
- - save_cache:
- name: Cache core dependencies
- key: core-dependencies-v3-{{ checksum "yarn.lock" }}
- paths:
- - ~/.cache/yarn
docs:
<<: *defaults
steps:
@@ -287,12 +231,7 @@ jobs:
name: Cache docs dependencies
key: docs-dependencies-v2-{{ checksum "docs/yarn.lock" }}
paths:
- - ~/.cache/yarn
- - persist_to_workspace:
- root: .
- paths:
- - docs/public
- - docs/node_modules
+ - ~/.cache
lint:
<<: *defaults
steps:
@@ -325,19 +264,18 @@ jobs:
name: Upload coverage
command: yarn coverage
workflows:
- version: 2
- build_test_deploy:
+ test:
jobs:
- build
- - docs
- - frontpage
- lint:
requires:
- - docs
- build
- examples:
requires:
- build
+ - e2e:
+ requires:
+ - examples
- smoke-tests:
requires:
- build
@@ -355,4 +293,8 @@ workflows:
- test
- chromatic:
requires:
- - build
+ - examples
+ deploy:
+ jobs:
+ - docs
+ - frontpage
diff --git a/.github/workflows/tests-unit.yml b/.github/workflows/tests-unit.yml
index 6481b025e3ce..26e640026d7f 100644
--- a/.github/workflows/tests-unit.yml
+++ b/.github/workflows/tests-unit.yml
@@ -7,17 +7,11 @@ jobs:
name: Test on node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
- strategy:
- matrix:
- node-version: [10]
- os: [ubuntu-latest]
-
steps:
- uses: actions/checkout@v1
- - name: Use Node.js ${{ matrix.node_version }}
- uses: actions/setup-node@v1
+ - uses: actions/setup-node@v1
with:
- version: ${{ matrix.node_version }}
+ node-version: '10.x'
- name: install, bootstrap
run: |
yarn bootstrap --core
diff --git a/.gitignore b/.gitignore
index 124238c64b88..48f61b11955e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@ htpasswd
storybook-out
/addons/docs/common/config-*
built-storybooks
+cypress/videos
+cypress/screenshots
diff --git a/cypress.json b/cypress.json
new file mode 100644
index 000000000000..0967ef424bce
--- /dev/null
+++ b/cypress.json
@@ -0,0 +1 @@
+{}
diff --git a/cypress/.eslintrc.json b/cypress/.eslintrc.json
new file mode 100644
index 000000000000..373914272e56
--- /dev/null
+++ b/cypress/.eslintrc.json
@@ -0,0 +1,5 @@
+{
+ "extends": [
+ "plugin:cypress/recommended"
+ ]
+}
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
new file mode 100644
index 000000000000..da18d9352a17
--- /dev/null
+++ b/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
\ No newline at end of file
diff --git a/cypress/helper.ts b/cypress/helper.ts
new file mode 100644
index 000000000000..61c9920125e4
--- /dev/null
+++ b/cypress/helper.ts
@@ -0,0 +1,55 @@
+/* eslint-disable no-unused-expressions */
+/* eslint-disable jest/valid-expect */
+const baseUrl = 'http://localhost:8001';
+
+type StorybookApps = 'official-storybook';
+
+type Addons = 'Knobs';
+
+export const visitExample = (app: StorybookApps, route = '') => {
+ return cy
+ .clearLocalStorage()
+ .visit(`${baseUrl}/${app}/${route}`)
+ .get(`#storybook-preview-iframe`)
+ .then({ timeout: 10000 }, iframe => {
+ return cy.wrap(iframe).should(() => {
+ const content: Document | null = (iframe[0] as HTMLIFrameElement).contentDocument;
+ const element: HTMLElement | null = content !== null ? content.documentElement : null;
+
+ expect(element).not.null;
+
+ if (element !== null) {
+ expect(element.querySelector('#root > *')).not.null;
+ }
+ });
+ });
+};
+
+export const clickAddon = (addonName: Addons) => {
+ return cy
+ .get(`[role=tablist] button[role=tab]`)
+ .contains(addonName)
+ .click();
+};
+
+export const getStorybookPreview = () => {
+ return cy.get(`#storybook-preview-iframe`).then({ timeout: 10000 }, iframe => {
+ const content: Document | null = (iframe[0] as HTMLIFrameElement).contentDocument;
+ const element: HTMLElement | null = content !== null ? content.documentElement : null;
+
+ console.log({ element, content, iframe });
+
+ return cy
+ .wrap(iframe)
+ .should(() => {
+ expect(element).not.null;
+
+ if (element !== null) {
+ expect(element.querySelector('#root > *')).not.null;
+ }
+ })
+ .then(() => {
+ return cy.wrap(element).get('#root');
+ });
+ });
+};
diff --git a/cypress/integration/knobs.spec.ts b/cypress/integration/knobs.spec.ts
new file mode 100644
index 000000000000..a670ef486b22
--- /dev/null
+++ b/cypress/integration/knobs.spec.ts
@@ -0,0 +1,21 @@
+import { clickAddon, visitExample } from '../helper';
+
+describe('Knobs', () => {
+ beforeEach(() => {
+ visitExample('official-storybook', '?path=/story/addons-knobs-withknobs--tweaks-static-values');
+ });
+
+ it('[text] it should change a string value', () => {
+ clickAddon('Knobs');
+
+ cy.get('#Name')
+ .clear()
+ .type('John Doe');
+
+ cy.preview()
+ .console('info')
+ .find('p')
+ .eq(0)
+ .should('contain.text', 'My name is John Doe');
+ });
+});
diff --git a/cypress/integration/navigation.spec.ts b/cypress/integration/navigation.spec.ts
new file mode 100644
index 000000000000..942cf47cc643
--- /dev/null
+++ b/cypress/integration/navigation.spec.ts
@@ -0,0 +1,40 @@
+import { visitExample } from '../helper';
+
+describe('Navigation', () => {
+ beforeEach(() => {
+ visitExample('official-storybook');
+ });
+
+ it('should search navigation item', () => {
+ cy.get('#storybook-explorer-searchfield')
+ .click()
+ .type('persisting the action logger');
+
+ cy.get('.sidebar-container a')
+ .should('contain', 'Persisting the action logger')
+ .and('not.contain', 'a11y');
+ });
+
+ it('should display no results after searching a non-existing navigation item', () => {
+ cy.get('#storybook-explorer-searchfield')
+ .click()
+ .type('zzzzzzzzzz');
+
+ cy.get('.sidebar-container').should('contain', 'This filter resulted in 0 results');
+ });
+});
+
+describe('Routing', () => {
+ it('should navigate to story addons-a11y-basebutton--default', () => {
+ visitExample('official-storybook');
+ cy.get('#exploreraddons-a11y-basebutton--label').click();
+
+ cy.url().should('include', 'path=/story/addons-a11y-basebutton--label');
+ });
+
+ it('should directly visit a certain story and render correctly', () => {
+ visitExample('official-storybook', '?path=/story/addons-a11y-basebutton--label');
+
+ cy.preview().should('contain.text', 'Testing the a11y addon');
+ });
+});
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
new file mode 100644
index 000000000000..e699dc68b670
--- /dev/null
+++ b/cypress/plugins/index.js
@@ -0,0 +1,22 @@
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+const wp = require('@cypress/webpack-preprocessor');
+const webpackConfig = require('./webpack.config');
+
+module.exports = on => {
+ const options = {
+ webpackOptions: webpackConfig,
+ };
+ on('file:preprocessor', wp(options));
+};
diff --git a/cypress/plugins/webpack.config.js b/cypress/plugins/webpack.config.js
new file mode 100644
index 000000000000..01774bb3d143
--- /dev/null
+++ b/cypress/plugins/webpack.config.js
@@ -0,0 +1,21 @@
+module.exports = {
+ resolve: {
+ extensions: ['.ts', '.js'],
+ },
+ module: {
+ rules: [
+ {
+ test: /\.ts$/,
+ exclude: [/node_modules/],
+ use: [
+ {
+ loader: 'ts-loader',
+ options: {
+ transpileOnly: true,
+ },
+ },
+ ],
+ },
+ ],
+ },
+};
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
new file mode 100644
index 000000000000..d7377c5df89d
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,59 @@
+/* eslint-disable no-unused-expressions */
+/* eslint-disable jest/valid-expect */
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add("login", (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This is will overwrite an existing command --
+// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
+
+const logger = console;
+Cypress.Commands.add(
+ 'console',
+ {
+ prevSubject: true,
+ },
+ (subject, method = 'log') => {
+ logger[method]('The subject is', subject);
+ return subject;
+ }
+);
+
+Cypress.Commands.add('preview', {}, () => {
+ return cy.get(`#storybook-preview-iframe`).then({ timeout: 10000 }, iframe => {
+ const content = iframe[0].contentDocument;
+ const element = content !== null ? content.documentElement : null;
+
+ return cy
+ .wrap(iframe)
+ .should(() => {
+ expect(element).not.null;
+
+ if (element !== null) {
+ expect(element.querySelector('#root > *')).not.null;
+ }
+ })
+ .then(() => {
+ return element.querySelector('#root');
+ });
+ });
+});
diff --git a/cypress/support/index.js b/cypress/support/index.js
new file mode 100644
index 000000000000..37a498fb5bf3
--- /dev/null
+++ b/cypress/support/index.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands';
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json
new file mode 100644
index 000000000000..6375e4c73dfa
--- /dev/null
+++ b/cypress/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "baseUrl": "../node_modules",
+ "target": "es5",
+ "lib": ["es2017", "dom"],
+ "types": ["cypress"]
+ },
+ "include": ["**/*.ts"]
+}
diff --git a/examples/ember-cli/package.json b/examples/ember-cli/package.json
index 95110f343d5e..059f45fad102 100644
--- a/examples/ember-cli/package.json
+++ b/examples/ember-cli/package.json
@@ -4,7 +4,7 @@
"private": true,
"scripts": {
"build": "ember build",
- "prebuild-storybook": "yarn build && cp -r public/* dist",
+ "prebuild-storybook": "yarn build && shx cp -r public/* dist",
"build-storybook": "build-storybook -s dist",
"dev": "ember serve",
"storybook": "yarn build && start-storybook -p 9009 -s dist",
diff --git a/examples/official-storybook/stories/app-acceptance.stories.js b/examples/official-storybook/stories/app-acceptance.stories.js
deleted file mode 100644
index edea0adc9125..000000000000
--- a/examples/official-storybook/stories/app-acceptance.stories.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from 'react';
-import { storiesOf } from '@storybook/react';
-
-// For these stories to work, you must build the static version of the
-// example storybooks *before* running this storybook.
-
-const chapter = storiesOf('App|acceptance', module);
-
-const style = {
- border: 0,
- position: 'absolute',
- top: 0,
- left: 0,
- width: '100vw',
- height: '100vh',
-};
-
-[
- 'cra-kitchen-sink',
- 'cra-ts-kitchen-sink',
- 'vue-kitchen-sink',
- 'svelte-kitchen-sink',
- 'angular-cli',
- 'polymer-cli',
- 'mithril-kitchen-sink',
- 'html-kitchen-sink',
- 'riot-kitchen-sink',
- 'preact-kitchen-sink',
- 'cra-react15',
-].forEach(name => {
- chapter.add(name, () => , {
- chromatic: { delay: 2000 },
- notes: `You must build the storybook for the ${name} example for this story to work.`,
- });
-});
diff --git a/package.json b/package.json
index aa0ac6333870..261a519f9d19 100644
--- a/package.json
+++ b/package.json
@@ -40,13 +40,14 @@
"lib/cli/test/run/*"
],
"scripts": {
+ "await-serve-storybooks": "wait-on http://localhost:8001",
"bootstrap": "node ./scripts/bootstrap.js",
"bootstrap:docs": "yarn install --cwd docs",
"build-packs": "lerna exec --scope '@storybook/*' -- \\$LERNA_ROOT_PATH/scripts/build-pack.sh \\$LERNA_ROOT_PATH/packs",
"build-storybooks": "cross-env STORYBOOK_DISPLAY_WARNING=true DISPLAY_WARNING=true ./scripts/build-storybooks.js",
"changelog": "pr-log --sloppy --cherry-pick",
"changelog:next": "pr-log --sloppy --since-prerelease",
- "chromatic": "chromatic --storybook-build-dir=\"./built-storybooks/official-storybook/\" --exit-zero-on-changes --app-code=\"ab7m45tp9p\"",
+ "chromatic": "chromatic --storybook-build-dir=\"built-storybooks/official-storybook\" --exit-zero-on-changes --app-code=\"ab7m45tp9p\"",
"coverage": "codecov",
"danger": "danger",
"dev": "concurrently --kill-others \"yarn dev:tsc\" \"yarn dev:babel\"",
@@ -62,16 +63,18 @@
"lint:js": "cross-env NODE_ENV=production eslint --cache --cache-location=.cache/eslint --ext .js,.jsx,.json,.html,.ts,.tsx,.mjs --report-unused-disable-directives",
"lint:md": "remark -q",
"lint:package": "sort-package-json",
- "now-build": "yarn build-storybooks",
+ "now-build": "yarn bootstrap --core && yarn build-storybooks",
"publish:crna": "yarn --cwd examples-native/crna-kitchen-sink expo publish",
"publish:debug": "npm run publish:latest -- --npm-tag=debug --no-push",
"publish:latest": "lerna publish --exact --concurrency 1 --force-publish",
"publish:next": "npm run publish:latest -- --npm-tag=next",
"repo-dirty-check": "node ./scripts/repo-dirty-check",
+ "serve-storybooks": "http-server ./built-storybooks -p 8001",
"start": "yarn --cwd examples/official-storybook storybook",
"test": "node ./scripts/test.js",
"test-latest-cra": "yarn --prefix --cwd lib/cli run test-latest-cra",
- "test:cli": "npm --prefix lib/cli run test"
+ "test:cli": "npm --prefix lib/cli run test",
+ "test:e2e-gui": "concurrently --success first --kill-others \"cypress open\" \"yarn serve-storybooks\""
},
"husky": {
"hooks": {
@@ -113,9 +116,6 @@
]
},
"browserslist": "defaults",
- "dependencies": {
- "node-sass": "^4.12.0"
- },
"devDependencies": {
"@angular/common": "^8.2.8",
"@angular/compiler": "^8.2.8",
@@ -174,6 +174,7 @@
"esm": "^3.2.25",
"github-release-from-changelog": "^2.1.0",
"glob": "^7.1.3",
+ "http-server": "^0.11.1",
"husky": "^3.0.8",
"inquirer": "^7.0.0",
"jest": "^24.8.0",
@@ -196,6 +197,7 @@
"lodash": "^4.17.15",
"node-cleanup": "^2.1.2",
"node-fetch": "^2.6.0",
+ "node-sass": "^4.12.0",
"npmlog": "^4.1.2",
"prettier": "^1.16.4",
"raf": "^3.4.0",
@@ -209,6 +211,7 @@
"remark-preset-lint-recommended": "^3.0.2",
"riot-jest-transformer": "^2.0.0",
"shelljs": "^0.8.3",
+ "shx": "^0.3.2",
"sort-package-json": "^1.21.0",
"storybook-chromatic": "^3.0.0",
"svelte": "^3.4.1",
@@ -216,7 +219,13 @@
"trash": "^6.0.0",
"ts-dedent": "^1.1.0",
"ts-jest": "^24.0.2",
- "typescript": "^3.4.0"
+ "typescript": "^3.4.0",
+ "wait-on": "^3.3.0"
+ },
+ "optionalDependencies": {
+ "@cypress/webpack-preprocessor": "^4.1.0",
+ "cypress": "^3.4.1",
+ "eslint-plugin-cypress": "^2.7.0"
},
"engines": {
"node": ">=8.6.0",
diff --git a/scripts/build-storybooks.js b/scripts/build-storybooks.js
index 9d8af1993b9a..a2fe741672a6 100755
--- a/scripts/build-storybooks.js
+++ b/scripts/build-storybooks.js
@@ -1,7 +1,5 @@
#!/usr/bin/env node
-/* eslint-disable global-require */
-
const { spawn } = require('child_process');
const { promisify } = require('util');
const {
@@ -9,7 +7,6 @@ const {
readFile: readFileRaw,
writeFile: writeFileRaw,
statSync,
- cop,
} = require('fs');
const { join } = require('path');
@@ -22,15 +19,20 @@ const logger = console;
const exec = async (command, args = [], options = {}) =>
new Promise((resolve, reject) => {
- const child = spawn(command, args, { ...options, stdio: 'inherit' });
-
- child.on('close', code => {
- if (code) {
+ const child = spawn(command, args, { ...options, stdio: 'inherit', shell: true });
+
+ child
+ .on('close', code => {
+ if (code) {
+ reject();
+ } else {
+ resolve();
+ }
+ })
+ .on('error', e => {
+ logger.error(e);
reject();
- } else {
- resolve();
- }
- });
+ });
});
const hasBuildScript = async l => {
@@ -40,64 +42,8 @@ const hasBuildScript = async l => {
return !!json.scripts['build-storybook'];
};
-const handleExamples = async files => {
- const deployables = files.filter(f => {
- const packageJsonLocation = p(['examples', f, 'package.json']);
- const stats = statSync(packageJsonLocation);
-
- return stats.isFile() && hasBuildScript(packageJsonLocation);
- });
-
- await deployables.reduce(async (acc, d) => {
- await acc;
-
- logger.log('');
- logger.log(
- `-----------------${Array(d.length)
- .fill('-')
- .join('')}`
- );
- logger.log(`▶️ building: ${d}`);
- logger.log(
- `-----------------${Array(d.length)
- .fill('-')
- .join('')}`
- );
- const out = p(['built-storybooks', d]);
- const cwd = p(['examples', d]);
-
- await exec(`yarn`, [`build-storybook`, `--output-dir=${out}`, '--quiet'], { cwd });
-
- logger.log('-------');
- logger.log('✅ done');
- logger.log('-------');
- }, Promise.resolve());
-
- const copy = require('recursive-copy');
- const target = 'official-storybook';
- const copyables = deployables.filter(f => f !== target);
-
- await copyables.reduce(async (acc, d) => {
- await acc;
-
- logger.log(`💿 copy ${d} to built-storybooks`);
- const to = p(['built-storybooks', target, d]);
- const from = p(['built-storybooks', d]);
-
- await copy(from, to, {
- overwrite: true,
- });
- }, Promise.resolve());
-
- logger.log('-------');
- logger.log('✅ done');
- logger.log('-------');
- logger.log('');
-
- logger.log(`📑 creating index`);
-
- const indexLocation = p(['built-storybooks', 'index.html']);
- const indexContent = `
+const createContent = deployables => {
+ return `