1 | # creevey
|
2 |
|
3 | Pretty easy visual testing with magic
|
4 |
|
5 | [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
|
6 |
|
7 | ## How to use
|
8 |
|
9 | - `npm install -D creevey`
|
10 | - Add `withCreevey` as top-level storybook decorator
|
11 | - Run tests `yarn creevey --gridUrl "<gridUrl>/wd/hub"`
|
12 |
|
13 | ## What's storybook decorator?
|
14 |
|
15 | [Using Decorators](https://storybook.js.org/docs/basics/writing-stories/#using-decorators)
|
16 |
|
17 | ```ts
|
18 | // .storybook/preview.js or .storybook/config.js
|
19 | import { addDecorator } from '@storybook/react';
|
20 | import { withCreevey } from 'creevey';
|
21 |
|
22 | addDecorator(withCreevey({ captureElement: '#root' }));
|
23 |
|
24 | /* ... */
|
25 | ```
|
26 |
|
27 | ## Also you can define `creevey.config.ts`
|
28 |
|
29 | ```ts
|
30 | import path from 'path';
|
31 | import { CreeveyConfig } from 'creevey';
|
32 |
|
33 | const config: CreeveyConfig = {
|
34 | gridUrl: '<gridUrl>/wd/hub',
|
35 | storybookUrl: 'http://localhost:6006',
|
36 | storybookDir: path.join(__dirname, '.storybook'),
|
37 | enableFastStoriesLoading: false, // See notes below
|
38 | screenDir: path.join(__dirname, 'images'),
|
39 | reportDir: path.join(__dirname, 'report'),
|
40 | diffOptions: { threshold: 0.1 },
|
41 | maxRetries: 2,
|
42 | browsers: {
|
43 | chrome: true,
|
44 | ff: 'firefox',
|
45 | ie11: {
|
46 | browserName: 'internet explorer',
|
47 | gridUrl: '<anotherGridUrl>/wd/hub',
|
48 | limit: 2,
|
49 | /* capabilities */
|
50 | },
|
51 | otherChrome: {
|
52 | browserName: 'chrome',
|
53 | storybookUrl: 'http://mystoryhost:6007',
|
54 | viewport: { width: 1024, height: 720 },
|
55 | },
|
56 | },
|
57 | };
|
58 |
|
59 | export default config;
|
60 | ```
|
61 |
|
62 | NOTE: By default Creevey load stories with all dependency modules recursively. But for running tests mostly of them is not needed, Creevey uses only stories meta data, like story name/kind and parameters. Load all modules may significantly increase initialization time, so you can speed it up by using `enableFastStoriesLoading` flag. But bear in mind, your stories should have no side-effects. This flag skip to load all modules except stories/config and some modules from node_modules.
|
63 |
|
64 | ## Creevey CLI options
|
65 |
|
66 | - `--config` — Specify path to config file. Default `./creevey.config`
|
67 | - `--reporter` — Use another reporter for mocha instead of default `spec`
|
68 | - `--gridUrl` — Specify selenium grid url, work only in zero-config
|
69 | - `--ui` — Start web server
|
70 | - `--update` — Approve all images from `report` directory
|
71 | - `--port` — Specify port for web server. Default `3000`
|
72 | - `--reportDir` — Path where reports will be stored
|
73 | - `--screenDir` — Path where reference images are located
|
74 |
|
75 | ## `withCreevey` decorator parameters
|
76 |
|
77 | You can specify storybook parameters for `withCreevey` decorator:
|
78 |
|
79 | ```tsx
|
80 | // Global parameters can be defined in storybook config
|
81 | addDecorator(
|
82 | withCreevey({
|
83 | captureElement: '#root',
|
84 | tests: {
|
85 | /* see examples below */
|
86 | },
|
87 | skip: {
|
88 | /* see examples below */
|
89 | },
|
90 | }),
|
91 | );
|
92 | ```
|
93 |
|
94 | ```tsx
|
95 | // For new `Component Story Format` (CSF) https://storybook.js.org/docs/formats/component-story-format/
|
96 | // Kind-level parameters work for all stories inside
|
97 | export default {
|
98 | title: 'Views',
|
99 | parameters: {
|
100 | creevey: {
|
101 | /* ... */
|
102 | },
|
103 | },
|
104 | };
|
105 |
|
106 | // Story-level parameters work only for that story
|
107 | export const simple = () => <MyComponent />;
|
108 | simple.story = {
|
109 | parameters: {
|
110 | creevey: {
|
111 | /* ... */
|
112 | },
|
113 | },
|
114 | };
|
115 | ```
|
116 |
|
117 | ```tsx
|
118 | // For Old `StoriesOf` API (Storybook version < 5.2)
|
119 | storiesOf('Views', module)
|
120 | .addParameters({
|
121 | creevey: {
|
122 | /* ... */
|
123 | },
|
124 | }) // Kind-level
|
125 | .add('simple', () => <MyComponent />, {
|
126 | creevey: {
|
127 | /* ... */
|
128 | },
|
129 | }); // Story-level
|
130 | ```
|
131 |
|
132 | NOTE: Parameters for story will be deep-merged with parameters from higher levels.
|
133 |
|
134 | ## `tests` option examples:
|
135 |
|
136 | `tests` option is a plain object where key used as test name and value is a test function.
|
137 | Under the hood of `creevey` is used `mocha+chai` and for `chai` additionally defined `matchImage` assertion.
|
138 |
|
139 | ```tsx
|
140 | import React from 'react';
|
141 | import { CSFStory } from 'creevey';
|
142 |
|
143 | export default { title: 'MyComponent' };
|
144 |
|
145 | export const Simple: CSFStory<JSX.Element> = () => <MyComponent />;
|
146 | Simple.story = {
|
147 | parameters: {
|
148 | creevey: {
|
149 | captureElement: '#root',
|
150 | tests: {
|
151 | async click() {
|
152 | await this.browser
|
153 | .actions({ bridge: true })
|
154 | .click(this.captureElement)
|
155 | .perform();
|
156 |
|
157 | await this.expect(await this.takeScreenshot()).to.matchImage('clicked component');
|
158 | },
|
159 | },
|
160 | },
|
161 | },
|
162 | };
|
163 | ```
|
164 |
|
165 | ## `skip` option examples:
|
166 |
|
167 | - Skip all stories for all browsers:
|
168 | - `skip: 'Skip reason message'`
|
169 | - `skip: { reason: 'Skip reason message' }`
|
170 | - Skip all stories for specific browsers:
|
171 | - `skip: { in: 'ie11' }`
|
172 | - `skip: { in: ['ie11', 'chrome'] }`
|
173 | - `skip: { in: /^fire.*/ }`
|
174 | - Skip all stories in specific kinds:
|
175 | - `skip: { kinds: 'Button' }`
|
176 | - `skip: { kinds: ['Button', 'Input'] }`
|
177 | - `skip: { kinds: /.*Modal$/ }`
|
178 | - Skip all tests in specific stories:
|
179 | - `skip: { stories: 'simple' }`
|
180 | - `skip: { stories: ['simple', 'special'] }`
|
181 | - `skip: { stories: /.*large$/ }`
|
182 | - Skip specific tests:
|
183 | - `skip: { tests: 'click' }`
|
184 | - `skip: { tests: ['hover', 'click'] }`
|
185 | - `skip: { tests: /^press.*$/ }`
|
186 | - Multiple skip options: `skip: [{ /* ... */ }]`
|
187 |
|
188 | NOTE: If you try to skip stories by story name, the storybook name format will be used (For more info see [storybook-export-vs-name-handling](https://storybook.js.org/docs/formats/component-story-format/#storybook-export-vs-name-handling))
|
189 |
|
190 | ## FAQ
|
191 |
|
192 | ### Get error `Cannot find module '/path/to/project/creevey.config'` with CRA
|
193 |
|
194 | CRA don't have `@babel/register` nor `ts-node` in deps, that used to load TypeScript modules in runtime. So you need to install one of those packages explicitly
|
195 |
|
196 | ### Get `SyntaxError: ...` while loading storybook config
|
197 |
|
198 | I try to figure out what transpiler I should register to load storybook config and stories in your project, but I can't cover all cases. So, if you stuck with this issue, please specify correct require hooks and options on top of creevey config.
|