storybook-detox-test-runner v1.0.1
Storybook Detox Test Runner
This project enables you to test your Storybook for React Native stories using Detox.
How it works
The test runner injects itself into your Detox tests by overridding the Jest configuration.
Before the tests run it generates a Jest test file for each of your Storybook story files.
Each test uses Storybook's websockets to render the appropriate story, it then runs your story's play function, which may use the Detox API.
Getting started
- Install
storybook-detox-test-runner
yarn add -D storybook-detox-test-runner- Ensure that Storybook, running on your app, has websockets enabled
// .storybook/index.js
...
const StorybookUIRoot = view.getStorybookUI({
enableWebsockets: true
})
...!NOTE This is different to the
websocketsproperty ofwithStorybookinmetro.config.jsDo not enable the
websocketsproperty.
- Install Detox
Follow Detox's environment setup and project setup
Remove the
testRunnersection from the Detox configuration and extendstorybook-detox-test-runner
// .detoxrc.js
/** @type {Detox.DetoxConfig} */
module.exports = {
extends: 'storybook-detox-test-runner',
configurations: {
...- If you use a flag to toggle Storybook, ensure it's enabled during the build, for example:
// .detoxrc.js
...
"app": {
"type": "android.apk",
"build": "cd android && STORYBOOK=true ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release",
"binaryPath": "android/app/build/outputs/apk/release/app-release.apk"
}
...- Add
.storybook/.detox-teststo your.gitignore
The test runner generates tests in your Storybook config directory, these don't need to be committed to source control.
!NOTE This assumes your Storybook config directory is
.storybookIf you use a different directory, declare the environment variable
STORYBOOK_CONFIG_DIRwhen running the tests.STORYBOOK_CONFIG_DIR=custom-dir yarn detox test
- Build your test app with
yarn detox build
Writing a test
Give your story a play function, using Detox functions like element and by to find and interact with elements.
// counter.stories.tsx
import { type Meta, type StoryObj } from '@storybook/react'
import Counter from 'src/components/counter'
const component: Meta<typeof Counter> = {
component: Counter
}
export default component
export const WhenIClickOnTheCounterThenTheNumberGoesUp: StoryObj<typeof Counter> = {
play: async () => {
// Wait for initial render.
await waitFor(element(by.text(/Count up/))).toBeVisible().withTimeout(1000)
// When
await element(by.text(/Count up/)).tap()
await element(by.text(/Count up/)).tap()
await element(by.text(/Count up/)).tap()
await element(by.text(/Count up/)).tap()
await element(by.text(/Count up/)).tap()
// Then
await waitFor(element(by.text(/5/))).toBeVisible()
}
}Running the test
Run Detox as normal with yarn detox test