Skip to content

Commit 4759170

Browse files
committed
test: Introduce Chromatic for Visual Regression Tests
1 parent 412de7e commit 4759170

21 files changed

+139
-1
lines changed

.github/workflows/chromatic.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Workflow name
2+
name: 'Chromatic'
3+
4+
# Event for the workflow
5+
on: push
6+
7+
# List of jobs
8+
jobs:
9+
chromatic-deployment:
10+
# Operating System
11+
runs-on: ubuntu-latest
12+
# Job steps
13+
steps:
14+
- uses: actions/checkout@v1
15+
- name: Install dependencies
16+
# 👇 Install dependencies with the same package manager used in the project (replace it as needed) e.g. yarn, npm, pnpm
17+
run: npm install
18+
# 👇 Adds Chromatic as a step in the workflow
19+
- name: Publish to Chromatic
20+
uses: chromaui/action@v1
21+
# Chromatic GitHub Action options
22+
with:
23+
# 👇 Chromatic projectToken, refer to the manage page to obtain it.
24+
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
25+
skip: dependabot/**
26+
onlyChanged: true

.storybook/main.js

+2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ module.exports = {
44
stories: ['../src/**/*.stories.@(tsx|mdx)', '../stories/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
55
siteUrl: 'https://github.com/Doist/reactist',
66
features: {
7+
// Needed for Chromatic/Storybooks interactive tests
78
// See https://storybook.js.org/docs/react/writing-tests/interaction-testing
9+
// See https://www.chromatic.com/docs/interactions#how-to-write-interaction-tests
810
interactionsDebugger: true,
911
},
1012
addons: [

.storybook/preview.js

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export const parameters = {
1313
},
1414
},
1515
decorators,
16+
chromatic: {
17+
// This allows us to opt-in to Chromatic snapshots per story
18+
// See https://www.chromatic.com/docs/ignoring-elements#ignore-stories
19+
disableSnapshot: true,
20+
},
1621
}
1722

1823
const badgeFontStyles = {

package-lock.json

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"autoprefixer": "^9.8.0",
9797
"babel-core": "^7.0.0-bridge.0",
9898
"babel-loader": "^8.1.0",
99+
"chromatic": "^6.11.4",
99100
"classnames": "^2.2.5",
100101
"css-loader": "^4.2.2",
101102
"cssnano": "^4.1.10",

src/new-components/alert/alert.stories.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ A simple Alert component.
4949
name="Main demo"
5050
parameters={{
5151
docs: { source: { type: 'code' } },
52+
chromatic: { disableSnapshot: false },
5253
}}
5354
>
5455
<Stack space="xxlarge">

src/new-components/badge/badge.stories.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ The use of variants does not provide extra semantic meaning and is strictly visu
2121
<Story
2222
parameters={{
2323
docs: { source: { type: 'code' } },
24+
chromatic: { disableSnapshot: false },
2425
}}
2526
name="Main demo"
2627
>

src/new-components/button/button.stories.mdx

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ A semantic button that provides all the necessary visual variants. It follows th
3636
name="Main demo"
3737
parameters={{
3838
docs: { source: { type: 'code' } },
39+
chromatic: { disableSnapshot: false },
3940
}}
4041
>
4142
<Stack space="xxlarge">
@@ -153,6 +154,7 @@ this is discouraged, and not guaranteed to be supported in the future.
153154
name="With label and icon"
154155
parameters={{
155156
docs: { source: { type: 'code' } },
157+
chromatic: { disableSnapshot: false },
156158
}}
157159
>
158160
<Stack space="xxlarge">
@@ -223,6 +225,7 @@ as a tooltip if no tooltip is provided.
223225
name="Icon-only buttons"
224226
parameters={{
225227
docs: { source: { type: 'code' } },
228+
chromatic: { disableSnapshot: false },
226229
}}
227230
>
228231
<Stack space="large">
@@ -268,6 +271,7 @@ for this purpose.
268271
name="With different size"
269272
parameters={{
270273
docs: { source: { type: 'code' } },
274+
chromatic: { disableSnapshot: false },
271275
}}
272276
>
273277
<Stack space="xxlarge">
@@ -531,6 +535,7 @@ export function FullWidthTemplate({ label, ...otherProps }) {
531535
name="Full-width"
532536
parameters={{
533537
docs: { source: { type: 'code' } },
538+
chromatic: { disableSnapshot: false },
534539
}}
535540
argTypes={{
536541
label: {

src/new-components/checkbox-field/checkbox-field.stories.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ A checkbox field with a `ReactNode` as label.
131131
name="Indeterminate Example"
132132
parameters={{
133133
docs: { source: { type: 'dynamic' } },
134+
chromatic: { disableSnapshot: false },
134135
}}
135136
>
136137
{() => {

src/new-components/heading/heading.stories.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ export function HeadingStory() {
6969
)
7070
}
7171

72+
HeadingStory.parameters = {
73+
chromatic: { disableSnapshot: false },
74+
}
75+
7276
export function TruncatedHeadingStory() {
7377
return (
7478
<section className="story">
@@ -87,6 +91,10 @@ export function TruncatedHeadingStory() {
8791
)
8892
}
8993

94+
TruncatedHeadingStory.parameters = {
95+
chromatic: { disableSnapshot: false },
96+
}
97+
9098
export function ResponsiveHeadingStory(props: React.ComponentProps<typeof Heading>) {
9199
return (
92100
<>

src/new-components/modal/modal-examples.stories.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ ModalWithStandardActionsFooter.storyName = 'Modal with standard actions footer'
102102
ModalWithStandardActionsFooter.play = openModal
103103
ModalWithStandardActionsFooter.parameters = {
104104
docs: { source: { type: 'dynamic' } },
105+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
105106
}
106107

107108
//
@@ -144,6 +145,7 @@ ModalWithHeaderBodyAndCustomFooter.storyName = 'Modal with header, body and cust
144145
ModalWithHeaderBodyAndCustomFooter.play = openModal
145146
ModalWithHeaderBodyAndCustomFooter.parameters = {
146147
docs: { source: { type: 'dynamic' } },
148+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
147149
}
148150

149151
//
@@ -201,6 +203,7 @@ ModalWithSidebar.storyName = 'Modal with a sidebar'
201203
ModalWithSidebar.play = openModal
202204
ModalWithSidebar.parameters = {
203205
docs: { source: { type: 'dynamic' } },
206+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
204207
}
205208

206209
//
@@ -277,6 +280,7 @@ ModalWithScrollableTabPanels.storyName = 'Modal with scrollable tab panels'
277280
ModalWithScrollableTabPanels.play = openModal
278281
ModalWithScrollableTabPanels.parameters = {
279282
docs: { source: { type: 'dynamic' } },
283+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
280284
}
281285

282286
//
@@ -312,6 +316,7 @@ MinimalisticConfirmationModal.storyName = 'Minimalistic confirmation modal'
312316
MinimalisticConfirmationModal.play = openModal
313317
MinimalisticConfirmationModal.parameters = {
314318
docs: { source: { type: 'dynamic' } },
319+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
315320
}
316321

317322
//
@@ -353,6 +358,7 @@ EnrichedConfirmationModal.storyName = 'Enriched confirmation modal'
353358
EnrichedConfirmationModal.play = openModal
354359
EnrichedConfirmationModal.parameters = {
355360
docs: { source: { type: 'dynamic' } },
361+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
356362
}
357363

358364
//
@@ -408,6 +414,7 @@ ModalAutofocus.storyName = 'Autofocus'
408414
ModalAutofocus.play = openModal
409415
ModalAutofocus.parameters = {
410416
docs: { source: { type: 'dynamic' } },
417+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
411418
}
412419

413420
//
@@ -462,4 +469,5 @@ StackingModals.storyName = 'Stacking modals'
462469
StackingModals.play = openModal
463470
StackingModals.parameters = {
464471
docs: { source: { type: 'dynamic' } },
472+
chromatic: { disableSnapshot: false, pauseAnimationAtEnd: true },
465473
}

src/new-components/modal/modal-stories-components.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ function Modal(props: WithOptionals<ModalProps, 'isOpen' | 'onDismiss' | 'width'
197197

198198
/**
199199
* Needed to make sure the modals are mounted inside the story's #root element
200+
* @see https://www.chromatic.com/docs/snapshots#why-isn%E2%80%99t-my-modal-or-dialog-captured
200201
*/
201202
const getPortalElement = React.useCallback(() => {
202203
const div = document.createElement('div')

src/new-components/password-field/password-field.stories.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ export function InteractivePropsStory({
4040
)
4141
}
4242

43+
InteractivePropsStory.parameters = {
44+
chromatic: { disableSnapshot: false },
45+
}
46+
4347
InteractivePropsStory.argTypes = {
4448
label: {
4549
control: { type: 'text' },
@@ -115,6 +119,10 @@ export function MessageToneStory() {
115119
)
116120
}
117121

122+
MessageToneStory.parameters = {
123+
chromatic: { disableSnapshot: false },
124+
}
125+
118126
export function WithoutLabelStory() {
119127
return (
120128
<Stack space="xlarge" dividers="secondary" maxWidth="small">

src/new-components/select-field/select-field.stories.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ export function InteractivePropsStory({
5353
)
5454
}
5555

56+
InteractivePropsStory.parameters = {
57+
chromatic: { disableSnapshot: false },
58+
}
59+
5660
InteractivePropsStory.argTypes = {
5761
label: {
5862
control: { type: 'text' },
@@ -143,6 +147,10 @@ export function MessageToneStory() {
143147
)
144148
}
145149

150+
MessageToneStory.parameters = {
151+
chromatic: { disableSnapshot: false },
152+
}
153+
146154
export function WithoutLabelStory() {
147155
return (
148156
<Stack space="xlarge" dividers="secondary" maxWidth="small">

src/new-components/spinner/spinner.tsx

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ import styles from './spinner.module.css'
33

44
function Spinner({ size = 24 }: { size?: number }) {
55
return (
6-
<svg aria-hidden width={size} height={size} viewBox="0 0 24 24" className={styles.svg}>
6+
<svg
7+
aria-hidden
8+
width={size}
9+
height={size}
10+
viewBox="0 0 24 24"
11+
className={styles.svg}
12+
data-chromatic="ignore"
13+
>
714
<g fill="none" fillRule="nonzero">
815
<path
916
className={styles.tint}

src/new-components/switch-field/switch-field.stories.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ A checkbox with a built-in label element that visually looks like a toggle switc
2020
name="Playground"
2121
parameters={{
2222
docs: { source: { type: 'dynamic' } },
23+
chromatic: { disableSnapshot: false },
2324
}}
2425
argTypes={{
2526
label: {

src/new-components/tabs/tabs.stories.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export const Template = ({
6363
parameters={{
6464
docs: { source: { type: 'code' } },
6565
controls: { exclude: ['children'] },
66+
chromatic: { disableSnapshot: false },
6667
}}
6768
args={{
6869
'aria-label': 'Main demo for Tabs',

src/new-components/text-area/text-area.stories.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ export function InteractivePropsStory({
4040
)
4141
}
4242

43+
InteractivePropsStory.parameters = {
44+
chromatic: { disableSnapshot: false },
45+
}
46+
4347
InteractivePropsStory.argTypes = {
4448
label: {
4549
control: { type: 'text' },
@@ -115,6 +119,10 @@ export function MessageToneStory() {
115119
)
116120
}
117121

122+
MessageToneStory.parameters = {
123+
chromatic: { disableSnapshot: false },
124+
}
125+
118126
export function WithoutLabelStory() {
119127
return (
120128
<Stack space="xlarge" dividers="secondary">

src/new-components/text-field/text-field.stories.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export function InteractivePropsStory({
4141
)
4242
}
4343

44+
InteractivePropsStory.parameters = {
45+
chromatic: { disableSnapshot: false },
46+
}
47+
4448
InteractivePropsStory.argTypes = {
4549
label: {
4650
control: { type: 'text' },
@@ -116,6 +120,10 @@ export function MessageToneStory() {
116120
)
117121
}
118122

123+
MessageToneStory.parameters = {
124+
chromatic: { disableSnapshot: false },
125+
}
126+
119127
export function WithoutLabelStory() {
120128
return (
121129
<Stack space="xlarge" dividers="secondary" maxWidth="small">

0 commit comments

Comments
 (0)