The testing strategy:
- storybook for simple components & manual tests
- automated tests for business logic
The project's storybook is build by the CI and available at https://pioneer-2-storybook.netlify.app/.
To run the local instance (project root or packages/ui
directory):
yarn run storybook
For more complex components, the stories might need a query-node mocks in order to fetch data.
Example story that uses query-node mocks to fetch members
data:
import { Meta, Story } from '@storybook/react'
import React from 'react'
import { ComplexComponent } from '@/foo/bar/components/ComplexComponent'
import { MockApolloProvider } from '@/mocks/components/storybook/MockApolloProvider'
export default {
title: 'ComplexComponent',
component: ComplexComponent,
} as Meta
export const Default: Story = () => {
return (
<MockApolloProvider members>
<ComplexComponent />
</MockApolloProvider>
)
}
Note: Some components might need to connect with Polkadot.js extension. However, the extension API can't be accessed inside storybook's iframe (example story that renders warning).
Pioneer 2 use jest to run automated tests and testing-library as testing utilities. The query-node mocks uses the same setup as the front-end mocks.
In order to ease stubbing Polkadot.js API there is a bunch of testing utilities to stub common responses or states:
The most common one is stubTransction
with helpers to simulate transaction success or failure:
import { stubTransactionSuccess } from 'ui/test/_mocks/transactions'
const api = stubApi()
let transaction: any
beforeEach(() => {
// This exposes `tx.balances.transfer` on the api stub.
transaction = stubTransaction(api, 'api.tx.balances.transfer')
})
describe('Transaciton', () => {
it('Success', () => {
stubTransactionSuccess(transaction)
// ...
})
it('Data in success events', () => {
stubTransactionSuccess(transaction, [createType('ThreadId', 1337)], 'forum', 'ThreadCreated')
// ...
})
it('Failure', () => {
stubTransactionFailure(transfer)
// ...
})
})
The other stubs help with creating balances, api.query.*
responses, etc.
- To interact with dropdowns use
selectFromDropdown()
helper - To interact with Pioneer 2 buttons use
getButton()
test helper which is optimized for test speed. - Don't run the CKEditor inside tests (JSDom is not compatible with contenteditable)
jest.mock('@/common/components/CKEditor', () => ({ CKEditor: (props: CKEditorProps) => mockCKEditor(props), })) describe('Component with CKEditor inside', () => {})
Additionally, the below node modules are always mocked (see packages/ui/tests/__mocks__
):
@polkadot/extension-dapp
– used by theuseSignAndSendTransaction()
hook
If you experience a slow test:
- Reduce number of mocked data. The default
seedEntity()
methods loads all the date (with related tables) while most of the tests needs only one or two entities. - Look out for
*ByRole()
queries as they are way slower than*ByText()
or*ByTestId()
(we useid
as test-id attribute).
The repository has enabled the continuous integration for every commit that lands on main
as well as for every PR:
- Code inspection and tests (for PR only):
- linter check
- build step
- tests
- The application preview on netlify
- The storybook preview on netlify
Note: Only the PRs that pass CI check can be included in the main
branch.