Storybook boilerplate which combines ReactJS, Typescript and Visual Regression testing using WebDriverIO
As we all know ReactJS continues to lead the way as far as being the most widely used Javascript library and in the opinion of many, the most powerful. If you combine ReactJS with Storybook and visual regression testing from Webdriver IO it is possible to create a design system and a custom component library that can be safely reused between products and/or other teams. Sometimes when sharing a UI library among a large group or multiple teams we run in to issues when one person makes what might seem to be trivial or small change to a shared component. These changes might cause issues for other users who are using the same component in another place. Often times small modifications or changes can slip through code reviews too. With this boilerplate we incorporated the ability to run visual regression testing on each component. This allows developers to see even the slightest of changes and decide if it is acceptible or not before commiting to the changes.
To run this project please follow these steps:
- Make sure you have Docker & NodeJS installed on your machine
- Pull the standalone-chrome-debug or standalone-firefox-debug docker image
- Clone this repo
- Install dependencies
npm install
- Start storybook with development mode
npm run storybook
my-react-component
|-- stories/
|-- vr-test/
|-- index.spec.ts
|-- story-1.story.tsx
|-- story-2.story.tsx
|-- story-3.story.tsx
|-- index.tsx
|-- style.less
src/components/button/index.tsx
import * as React from 'react';
import * as style from './style.less';
export class Button extends React.Component<Props> {
public render(): JSX.Element {
const className = [style.container, style[this.props.size || '']];
return (
<button onClick={this.props.onClick} id="button" className={className.join(' ')}>
{this.props.children}
</button>
);
}
}
export type Props = DataProps & EventProps;
interface DataProps {
/** Children node */
children: string | React.ReactNode;
/** Size of button */
size?: 'small' | 'medium' | 'large';
}
interface EventProps {
/** Click event */
onClick?: (e: React.MouseEvent<HTMLElement>) => void;
}
src/components/button/style.less
.container {
background: blue;
width: 100%;
}
.small {
background: yellow;
}
.medium {
background: green;
}
.large {
background: red;
}
File name pattern: src/components/<component-name>/stories/<test-case-name>.story.tsx
Example:
src/components/button/stories/large.story.tsx
import { Props } from '..'; // import the Props from the component
export const test: Props = {
children: 'large size',
size: 'large',
};
src/components/button/stories/small.story.tsx
import { Props } from '..'; // import the Props from the component
export const test: Props = {
children: 'small size',
size: 'small',
};
This type of testing produces snapshots of the component as *.png
files.
For example:
Here is a visual regression test for button
component
button with large size
button with medium size
button with small size
Here is a visual regression test for text
component
text with black background
text with red background
After completing the React component, to run the visual regression test, you need to do a little set up.
Make sure to start Docker
To run Selenium of web drivers, you can choose either running Docker commands
docker run -d -p 4444:4444 -p 5900:5900 selenium/standalone-chrome-debug
or using docker-compose.yml
docker-compose up
Advance: You can customize export ports by arguments if default ports are already allocated
Port | Default | Description |
---|---|---|
CHROME_MAIN_PORT | 4444 | port of selenium chrome |
CHROME_DEBUG_PORT | 5900 | port of selenium chrome debug - for screen sharing |
FIREFOX_MAIN_PORT | 5555 | port of selenium firefox |
FIREFOX_DEBUG_PORT | 5901 | port of selenium firefox debug - for screen sharing |
Example
CHROME_MAIN_PORT=6666 CHROME_DEBUG_PORT=5909 docker-compose up
Create the file src/components/<component-name>/stories/vr-test/index.spec.ts
with code below
import { VisualRegressionTest } from 'lib/test/visual-regression-test';
import * as style from '../../style.less';
new VisualRegressionTest(__dirname, style.container).run();
style.container
is the className wrapped around the component
To run the visual regression test, make sure your
storybook
started.
Desktop
npm run test:chrome src/components/<component-name>/stories/vr-test/index.spec.ts
Smartphone
npm run test:chrome:smartphone src/components/<component-name>/stories/vr-test/index.spec.ts
Both Desktop and Smartphone
npm test src/components/<component-name>/stories/vr-test/index.spec.ts
Run all tests
npm test
Screen Sharing
To debug visual regression testing
- Open the
Screen Sharing
chrome
Hostname: `YOUR_MACHINE_IP`:5900
Password: secret
- Run test
- Navigate to
Screen Sharing
to see the step by step for running the test
Dzung Nguyen π π» π€ π π |
Hoc Nguyen π» π€ π π |
Khoa Do π» π π |
Nguyen Van Hao π» π |
Ben Lee π π» |