Skip to content

Commit

Permalink
Storybook and unit testing setup (#1354)
Browse files Browse the repository at this point in the history
* install and config Storybook

* create basic component for initial setup

* added testing-library / jest for testing

* restore coverage for testing

* downgrade codeclimate-actions to fix viable formatter issue

* clean up - remove unnecessary components in stories

* update readme with storybook and testing

* remove unnecessary file extensions on stories config

* remove babel and moved jest-dom to devDependencies

* delete introduction stories

* change test to .tsx

* change testing description on docs

* added interface to button story

* added build phase and update test phase

* restore build in ci

* added storyshots (automate testing) to Storybook

* simplify and update codeclimate-action

* restore workable version of codeclimate-action

* test unified test action for CI

* Revert "test unified test action for CI"

This reverts commit 039cbf3485a98eb4e908aa4168ba48c593034910.

* test documented solutions for CI

* fix error on coverage CI

* added codeCoverage on jest setup

* upload coverage report from jest

* added download artifact to coverage CI

* added upload artifact to coverage CI

* remove collectCoverageFrom

* moved test step on CI

* remove coverageLocations to allow default

* load Ocean typography into storybook

* skip all PRs coming from dependabot

* improve docs (Storybook)

Co-authored-by: Matthias Kretschmann <[email protected]>
  • Loading branch information
EnzoVezzaro and kremalicious authored May 9, 2022
1 parent 6324e85 commit 89f2521
Show file tree
Hide file tree
Showing 13 changed files with 52,566 additions and 19,582 deletions.
34 changes: 20 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,25 @@ jobs:
restore-keys: ${{ runner.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-

- run: npm ci
- run: npm run codegen:apollo
- run: npm run lint
# - run: npm test
- run: npm run build
- run: npm test

# coverage:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - uses: actions/setup-node@v2
# - run: npm ci
# - uses: paambaati/[email protected]
# env:
# CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
# with:
# coverageCommand: npm test
- name: Upload coverage
uses: actions/upload-artifact@v2
with:
name: coverage
path: coverage/

coverage:
runs-on: ubuntu-latest
needs: [test]
if: ${{ success() && github.actor != 'dependabot[bot]' }}
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: coverage

- uses: paambaati/[email protected] # using 2.7.1 for issue: https://github.com/paambaati/codeclimate-action/issues/316
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
20 changes: 20 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')

module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.tsx'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions'
],
framework: '@storybook/react',
webpackFinal: async (config) => {
config.resolve.plugins = [
...(config.resolve.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve.extensions
})
]
return config
}
}
12 changes: 12 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import '@oceanprotocol/typographies/css/ocean-typo.css'
import '../src/stylesGlobal/styles.css'

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/
}
}
}
14 changes: 14 additions & 0 deletions .storybook/storyshots.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import initStoryshots from '@storybook/addon-storyshots'
import { render, waitFor } from '@testing-library/react'

// Stories are render-tested with @testing-library/react,
// overwriting default snapshot testing behavior
initStoryshots({
asyncJest: true,
test: async ({ story, done }) => {
const storyElement = story.render()
// render the story with @testing-library/react
render(storyElement)
await waitFor(() => done())
}
})
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,47 @@ npm run lint
npm run format
```

## 👩‍🎤 Storybook

Storybook helps us build UI components in isolation from our app's business logic, data, and context. That makes it easy to develop hard-to-reach states and save these UI states as stories to revisit during development, testing, or QA.

To start adding stories, create a `index.stories.tsx` inside the component's folder:

<pre>
src
└─── components
│ └─── @shared
│ └─── <your component>
│ │ index.tsx
│ │ index.module.css
│ │ <b>index.stories.tsx</b>
│ │ index.test.tsx
</pre>

You can also write a [test](https://storybook.js.org/docs/react/writing-tests/importing-stories-in-tests#example-with-testing-library) against your story by creating a `index.test.tsx` file.

Starting up the Storybook server with this command will make it accessible under `http://localhost:6006`:

```bash
npm run storybook
```

## 🤖 Testing

Interaction tests are setup with Storybook's Addon for [Testing Library](https://storybook.js.org/docs/react/writing-tests/importing-stories-in-tests#example-with-testing-library), which utilizes [Jest](https://jestjs.io/) as test runner. A combined coverage report is sent to CodeClimate via the coverage GitHub Actions job.

Executing linting, type checking, and interaction tests:

```bash
npm run test
```

Executing only interaction tests:

```bash
npm run jest
```

## 🛳 Production

To create a production build, run from the root of the project:
Expand Down
29 changes: 29 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const nextJest = require('next/jest')

const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './'
})

// Add any custom config to be passed to Jest
const customJestConfig = {
// Add more setup options before each test is run
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
moduleNameMapper: {
// '^@/components/(.*)$': '<rootDir>/components/$1',
'@shared(.*)$': '<rootDir>/src/components/@shared/$1',
'@hooks/(.*)$': '<rootDir>/src/@hooks/$1',
'@context/(.*)$': '<rootDir>/src/@context/$1',
'@images/(.*)$': '<rootDir>/src/@images/$1',
'@utils/(.*)$': '<rootDir>/src/@utils/$1',
'@content/(.*)$': '<rootDir>/@content/$1'
},
collectCoverage: true,
coverageReporters: ['lcov']
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
1 change: 1 addition & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom/extend-expect'
Loading

0 comments on commit 89f2521

Please sign in to comment.