From 894a04a688e4fe8330a20191a6512624bb34c257 Mon Sep 17 00:00:00 2001 From: Katerina Skroumpelou Date: Mon, 27 Mar 2023 18:14:35 +0300 Subject: [PATCH] feat(storybook): v7 e2e tests --- .github/workflows/e2e-matrix.yml | 3 + .github/workflows/e2e-windows.yml | 3 + docs/shared/mental-model/large-tasks.json | 24 ++++ e2e/storybook-7/jest.config.ts | 11 ++ e2e/storybook-7/project.json | 11 ++ e2e/storybook-7/src/storybook-nested.test.ts | 129 +++++++++++++++++++ e2e/storybook-7/src/storybook.test.ts | 102 +++++++++++++++ e2e/storybook-7/tsconfig.json | 13 ++ e2e/storybook-7/tsconfig.spec.json | 20 +++ 9 files changed, 316 insertions(+) create mode 100644 e2e/storybook-7/jest.config.ts create mode 100644 e2e/storybook-7/project.json create mode 100644 e2e/storybook-7/src/storybook-nested.test.ts create mode 100644 e2e/storybook-7/src/storybook.test.ts create mode 100644 e2e/storybook-7/tsconfig.json create mode 100644 e2e/storybook-7/tsconfig.spec.json diff --git a/.github/workflows/e2e-matrix.yml b/.github/workflows/e2e-matrix.yml index 71227f10cac82c..649e821577b2c9 100644 --- a/.github/workflows/e2e-matrix.yml +++ b/.github/workflows/e2e-matrix.yml @@ -81,6 +81,7 @@ jobs: - e2e-web - e2e-rollup - e2e-storybook + - e2e-storybook-7 - e2e-storybook-angular - e2e-vite - e2e-webpack @@ -141,6 +142,8 @@ jobs: codeowners: 'S04SJ6PL98X' - project: e2e-storybook codeowners: 'S04SVQ8H0G5' + - project: e2e-storybook-7 + codeowners: 'S04SVQ8H0G5' - project: e2e-storybook-angular codeowners: 'S04SVQ8H0G5' - project: e2e-vite diff --git a/.github/workflows/e2e-windows.yml b/.github/workflows/e2e-windows.yml index 0c6e38f66e8954..135737f0cb18c4 100644 --- a/.github/workflows/e2e-windows.yml +++ b/.github/workflows/e2e-windows.yml @@ -69,6 +69,7 @@ jobs: - e2e-web - e2e-rollup - e2e-storybook + - e2e-storybook-7 - e2e-storybook-angular - e2e-vite - e2e-webpack @@ -118,6 +119,8 @@ jobs: codeowners: 'S04SJ6PL98X' - project: e2e-storybook codeowners: 'S04SVQ8H0G5' + - project: e2e-storybook-7 + codeowners: 'S04SVQ8H0G5' - project: e2e-storybook-angular codeowners: 'S04SVQ8H0G5' - project: e2e-vite diff --git a/docs/shared/mental-model/large-tasks.json b/docs/shared/mental-model/large-tasks.json index 0931876c7fa5cb..94d8eb4fd1b6d5 100644 --- a/docs/shared/mental-model/large-tasks.json +++ b/docs/shared/mental-model/large-tasks.json @@ -36283,6 +36283,30 @@ }, "dependencies": { "e2e-storybook:run-e2e-tests": [] } }, + "e2e-storybook-7:e2e": { + "roots": ["e2e-storybook-7:e2e"], + "tasks": { + "e2e-storybook-7:e2e": { + "id": "e2e-storybook-7:e2e", + "target": { "project": "e2e-storybook-7", "target": "e2e" }, + "projectRoot": "e2e/storybook-7", + "overrides": {} + } + }, + "dependencies": { "e2e-storybook-7:e2e": [] } + }, + "e2e-storybook-7:run-e2e-tests": { + "roots": ["e2e-storybook-7:run-e2e-tests"], + "tasks": { + "e2e-storybook-7:run-e2e-tests": { + "id": "e2e-storybook-7:run-e2e-tests", + "target": { "project": "e2e-storybook-7", "target": "run-e2e-tests" }, + "projectRoot": "e2e/storybook-7", + "overrides": {} + } + }, + "dependencies": { "e2e-storybook-7:run-e2e-tests": [] } + }, "nx-dev:build": { "roots": ["graph-client:build-base:release"], "tasks": { diff --git a/e2e/storybook-7/jest.config.ts b/e2e/storybook-7/jest.config.ts new file mode 100644 index 00000000000000..05c2bb936fa459 --- /dev/null +++ b/e2e/storybook-7/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + transform: { + '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], + maxWorkers: 1, + globals: {}, + displayName: 'e2e-storybook-7', + preset: '../../jest.preset.js', +}; diff --git a/e2e/storybook-7/project.json b/e2e/storybook-7/project.json new file mode 100644 index 00000000000000..bd0bd6c0542eca --- /dev/null +++ b/e2e/storybook-7/project.json @@ -0,0 +1,11 @@ +{ + "name": "e2e-storybook-7", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "e2e/storybook", + "projectType": "application", + "targets": { + "e2e": {}, + "run-e2e-tests": {} + }, + "implicitDependencies": ["storybook"] +} diff --git a/e2e/storybook-7/src/storybook-nested.test.ts b/e2e/storybook-7/src/storybook-nested.test.ts new file mode 100644 index 00000000000000..59f602d206824f --- /dev/null +++ b/e2e/storybook-7/src/storybook-nested.test.ts @@ -0,0 +1,129 @@ +import { + checkFilesExist, + cleanupProject, + killPorts, + readJson, + runCLI, + runCommandUntil, + runCreateWorkspace, + tmpProjPath, + uniq, +} from '@nrwl/e2e/utils'; +import { writeFileSync } from 'fs'; + +describe('Storybook generators and executors for standalone workspaces - using React + Vite', () => { + const wsName = uniq('react'); + const appName = uniq('app'); + + beforeAll(() => { + // create a workspace with a single react app at the root + runCreateWorkspace(wsName, { + preset: 'react-standalone', + appName, + style: 'css', + bundler: 'vite', + }); + + runCLI( + `generate @nrwl/react:storybook-configuration ${appName} --generateStories --no-interactive --storybook7Configuration` + ); + + runCLI(`report`); + }); + + afterAll(() => { + cleanupProject(); + }); + + describe('Storybook generated files', () => { + it('should generate storybook files', () => { + checkFilesExist( + '.storybook/main.js', + '.storybook/preview.js', + '.storybook/tsconfig.json' + ); + }); + + it('should edit root tsconfig.json', () => { + const tsconfig = readJson(`tsconfig.json`); + expect(tsconfig['ts-node']?.compilerOptions?.module).toEqual('commonjs'); + }); + }); + + describe('serve storybook', () => { + afterEach(() => killPorts()); + + it('should serve a React based Storybook setup that uses Vite', async () => { + const p = await runCommandUntil(`run ${appName}:storybook`, (output) => { + return /Storybook.*started/gi.test(output); + }); + p.kill(); + }, 40000); + }); + + describe('build storybook', () => { + it('should build a React based storybook that uses Vite', () => { + runCLI(`run ${appName}:build-storybook --verbose`); + checkFilesExist(`dist/storybook/${appName}/index.html`); + }, 40000); + + // This test makes sure path resolution works + it('should build a React based storybook that references another lib and uses Vite', () => { + const reactLib = uniq('test-lib-react'); + runCLI(`generate @nrwl/react:lib ${reactLib} --no-interactive`); + // create a React component we can reference + writeFileSync( + tmpProjPath(`${reactLib}/src/lib/mytestcmp.tsx`), + ` + import React from 'react'; + + /* eslint-disable-next-line */ + export interface MyTestCmpProps {} + + export const MyTestCmp = (props: MyTestCmpProps) => { + return ( +
+

Welcome to test cmp!

+
+ ); + }; + + export default MyTestCmp; + ` + ); + // update index.ts and export it + writeFileSync( + tmpProjPath(`${reactLib}/src/index.ts`), + ` + export * from './lib/mytestcmp'; + ` + ); + + // create a story in the first lib to reference the cmp from the 2nd lib + writeFileSync( + tmpProjPath(`${reactLib}/src/lib/myteststory.stories.tsx`), + ` + import React from 'react'; + + import { MyTestCmp, MyTestCmpProps } from '@${wsName}/${reactLib}'; + + export default { + component: MyTestCmp, + title: 'MyTestCmp', + }; + + export const primary = () => { + /* eslint-disable-next-line */ + const props: MyTestCmpProps = {}; + + return ; + }; + ` + ); + + // build React lib + runCLI(`run ${reactLib}:build-storybook --verbose`); + checkFilesExist(`dist/storybook/${reactLib}/index.html`); + }, 40000); + }); +}); diff --git a/e2e/storybook-7/src/storybook.test.ts b/e2e/storybook-7/src/storybook.test.ts new file mode 100644 index 00000000000000..384e740c125e1b --- /dev/null +++ b/e2e/storybook-7/src/storybook.test.ts @@ -0,0 +1,102 @@ +import { + checkFilesExist, + cleanupProject, + killPorts, + runCLI, + runCommandUntil, + tmpProjPath, + uniq, + newProject, +} from '@nrwl/e2e/utils'; +import { writeFileSync } from 'fs'; + +describe('Storybook 7 generators and executors for monorepos', () => { + const reactStorybookLib = uniq('test-ui-lib-react'); + let proj; + beforeAll(() => { + proj = newProject(); + runCLI(`generate @nrwl/react:lib ${reactStorybookLib} --no-interactive`); + runCLI( + `generate @nrwl/react:storybook-configuration ${reactStorybookLib} --generateStories --no-interactive --bundler=webpack --storybook7Configuration` + ); + }); + + afterAll(() => { + cleanupProject(); + }); + + describe('serve and build storybook', () => { + afterEach(() => killPorts()); + + it('should serve a React based Storybook setup that uses webpack', async () => { + // serve the storybook + const p = await runCommandUntil( + `run ${reactStorybookLib}:storybook`, + (output) => { + return /Storybook.*started/gi.test(output); + } + ); + p.kill(); + }, 20000); + + it('should build a React based storybook setup that uses webpack', () => { + // build + runCLI(`run ${reactStorybookLib}:build-storybook --verbose`); + checkFilesExist(`dist/storybook/${reactStorybookLib}/index.html`); + }, 40000); + + // This test makes sure path resolution works + it('should build a React based storybook that references another lib and uses webpack', () => { + const anotherReactLib = uniq('test-another-lib-react'); + runCLI(`generate @nrwl/react:lib ${anotherReactLib} --no-interactive`); + // create a React component we can reference + writeFileSync( + tmpProjPath(`libs/${anotherReactLib}/src/lib/mytestcmp.tsx`), + ` + export function MyTestCmp() { + return ( +
+

Welcome to OtherLib!

+
+ ); + } + + export default MyTestCmp; + ` + ); + // update index.ts and export it + writeFileSync( + tmpProjPath(`libs/${anotherReactLib}/src/index.ts`), + ` + export * from './lib/mytestcmp'; + ` + ); + + // create a story in the first lib to reference the cmp from the 2nd lib + writeFileSync( + tmpProjPath( + `libs/${reactStorybookLib}/src/lib/myteststory.stories.tsx` + ), + ` + import type { Meta } from '@storybook/react'; + import { MyTestCmp } from '@${proj}/${anotherReactLib}'; + + const Story: Meta = { + component: MyTestCmp, + title: 'MyTestCmp', + }; + export default Story; + + export const Primary = { + args: {}, + }; + + ` + ); + + // build React lib + runCLI(`run ${reactStorybookLib}:build-storybook --verbose`); + checkFilesExist(`dist/storybook/${reactStorybookLib}/index.html`); + }, 40000); + }); +}); diff --git a/e2e/storybook-7/tsconfig.json b/e2e/storybook-7/tsconfig.json new file mode 100644 index 00000000000000..6d5abf84832009 --- /dev/null +++ b/e2e/storybook-7/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": ["node", "jest"] + }, + "include": [], + "files": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/e2e/storybook-7/tsconfig.spec.json b/e2e/storybook-7/tsconfig.spec.json new file mode 100644 index 00000000000000..1a24bfb0a13536 --- /dev/null +++ b/e2e/storybook-7/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "**/*.test.ts", + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx", + "**/*.d.ts", + "jest.config.ts" + ] +}