Skip to content

Commit 12bdb53

Browse files
iansan5653colebemis
authored andcommitted
Upgrade user-event to v14 (primer#2190)
* Upgrade `userEvent` to v14 * Fix Autocomplete tests Co-authored-by: Cole Bemis <[email protected]>
1 parent 80bef41 commit 12bdb53

13 files changed

+155
-120
lines changed

package-lock.json

Lines changed: 9 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
"@testing-library/jest-dom": "5.16.4",
127127
"@testing-library/react": "12.1.5",
128128
"@testing-library/react-hooks": "7.0.2",
129-
"@testing-library/user-event": "13.1.9",
129+
"@testing-library/user-event": "^14.3.0",
130130
"@types/chroma-js": "2.1.3",
131131
"@types/enzyme": "3.10.9",
132132
"@types/jest": "27.0.2",

src/SegmentedControl/SegmentedControl.test.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ describe('SegmentedControl', () => {
153153
}
154154
})
155155

156-
it('calls onChange with index of clicked segment button', () => {
156+
it('calls onChange with index of clicked segment button', async () => {
157+
const user = userEvent.setup()
157158
const handleChange = jest.fn()
158159
const {getByText} = render(
159160
<SegmentedControl aria-label="File view" onChange={handleChange}>
@@ -169,12 +170,13 @@ describe('SegmentedControl', () => {
169170

170171
expect(handleChange).not.toHaveBeenCalled()
171172
if (buttonToClick) {
172-
userEvent.click(buttonToClick)
173+
await user.click(buttonToClick)
173174
}
174175
expect(handleChange).toHaveBeenCalledWith(1)
175176
})
176177

177-
it('calls segment button onClick if it is passed', () => {
178+
it('calls segment button onClick if it is passed', async () => {
179+
const user = userEvent.setup()
178180
const handleClick = jest.fn()
179181
const {getByText} = render(
180182
<SegmentedControl aria-label="File view">
@@ -190,12 +192,13 @@ describe('SegmentedControl', () => {
190192

191193
expect(handleClick).not.toHaveBeenCalled()
192194
if (buttonToClick) {
193-
userEvent.click(buttonToClick)
195+
await user.click(buttonToClick)
194196
}
195197
expect(handleClick).toHaveBeenCalled()
196198
})
197199

198-
it('focuses the selected button first', () => {
200+
it('focuses the selected button first', async () => {
201+
const user = userEvent.setup()
199202
const {getByRole} = render(
200203
<>
201204
<button>Before</button>
@@ -212,8 +215,8 @@ describe('SegmentedControl', () => {
212215

213216
expect(document.activeElement?.id).not.toEqual(initialFocusButtonNode.id)
214217

215-
userEvent.tab() // focus the button before the segmented control
216-
userEvent.tab() // move focus into the segmented control
218+
await user.tab() // focus the button before the segmented control
219+
await user.tab() // move focus into the segmented control
217220

218221
expect(document.activeElement?.id).toEqual(initialFocusButtonNode.id)
219222
})

src/__tests__/Autocomplete.test.tsx

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22
import {render} from '../utils/testing'
3-
import {render as HTMLRender, fireEvent} from '@testing-library/react'
3+
import {render as HTMLRender, fireEvent, waitFor} from '@testing-library/react'
44
import {toHaveNoViolations} from 'jest-axe'
55
import 'babel-polyfill'
66
import Autocomplete, {AutocompleteInputProps} from '../Autocomplete'
@@ -193,7 +193,8 @@ describe('Autocomplete', () => {
193193
})
194194

195195
describe('Autocomplete.Input', () => {
196-
it('calls onChange', () => {
196+
it('calls onChange', async () => {
197+
const user = userEvent.setup()
197198
const onChangeMock = jest.fn()
198199
const {container} = HTMLRender(
199200
<LabelledAutocomplete
@@ -204,7 +205,7 @@ describe('Autocomplete', () => {
204205
const inputNode = container.querySelector('#autocompleteInput')
205206

206207
expect(onChangeMock).not.toHaveBeenCalled()
207-
inputNode && userEvent.type(inputNode, 'z')
208+
inputNode && (await user.type(inputNode, 'z'))
208209
expect(onChangeMock).toHaveBeenCalled()
209210
})
210211

@@ -244,15 +245,16 @@ describe('Autocomplete', () => {
244245
expect(onKeyUpMock).toHaveBeenCalled()
245246
})
246247

247-
it('calls onKeyPress', () => {
248+
it('calls onKeyPress', async () => {
249+
const user = userEvent.setup()
248250
const onKeyPressMock = jest.fn()
249251
const {getByLabelText} = HTMLRender(
250252
<LabelledAutocomplete inputProps={{onKeyPress: onKeyPressMock}} menuProps={{items: [], selectedItemIds: []}} />
251253
)
252254
const inputNode = getByLabelText(AUTOCOMPLETE_LABEL)
253255

254256
expect(onKeyPressMock).not.toHaveBeenCalled()
255-
userEvent.type(inputNode, '{enter}')
257+
await user.type(inputNode, '{enter}')
256258
expect(onKeyPressMock).toHaveBeenCalled()
257259
})
258260

@@ -265,7 +267,7 @@ describe('Autocomplete', () => {
265267
expect(inputNode.getAttribute('aria-expanded')).toBe('true')
266268
})
267269

268-
it('closes the menu when the input is blurred', () => {
270+
it('closes the menu when the input is blurred', async () => {
269271
const {getByLabelText} = HTMLRender(<LabelledAutocomplete menuProps={{items: [], selectedItemIds: []}} />)
270272
const inputNode = getByLabelText(AUTOCOMPLETE_LABEL)
271273

@@ -276,49 +278,50 @@ describe('Autocomplete', () => {
276278
fireEvent.blur(inputNode)
277279

278280
// wait a tick for blur to finish
279-
setTimeout(() => {
280-
expect(inputNode.getAttribute('aria-expanded')).not.toBe('true')
281-
}, 0)
281+
await waitFor(() => expect(inputNode.getAttribute('aria-expanded')).not.toBe('true'))
282282
})
283283

284-
it('sets the input value to the suggested item text and highlights the untyped part of the word', () => {
284+
it('sets the input value to the suggested item text and highlights the untyped part of the word', async () => {
285+
const user = userEvent.setup()
285286
const {container, getByDisplayValue} = HTMLRender(
286287
<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: []}} />
287288
)
288289
const inputNode = container.querySelector('#autocompleteInput')
289290

290-
inputNode && userEvent.type(inputNode, 'ze')
291+
inputNode && (await user.type(inputNode, 'ze'))
291292
expect(getByDisplayValue('zero')).toBeDefined()
292293
})
293294

294-
it('does not show or highlight suggestion text after the user hits Backspace until they hit another key', () => {
295+
it('does not show or highlight suggestion text after the user hits Backspace until they hit another key', async () => {
296+
const user = userEvent.setup()
295297
const {container, getByDisplayValue} = HTMLRender(
296298
<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: []}} />
297299
)
298300
const inputNode = container.querySelector('#autocompleteInput')
299301

300302
expect((inputNode as HTMLInputElement).selectionStart).toBe(0)
301-
inputNode && userEvent.type(inputNode, 'ze')
303+
inputNode && (await user.type(inputNode, 'ze'))
302304
expect(getByDisplayValue('zero')).toBeDefined()
303305
expect((inputNode as HTMLInputElement).selectionStart).toBe(2)
304306
expect((inputNode as HTMLInputElement).selectionEnd).toBe(4)
305-
inputNode && userEvent.type(inputNode, '{backspace}')
307+
inputNode && (await user.keyboard('{backspace}'))
306308
expect((inputNode as HTMLInputElement).selectionStart).toBe(2)
307309
expect(getByDisplayValue('ze')).toBeDefined()
308-
inputNode && userEvent.type(inputNode, 'r')
310+
inputNode && (await user.keyboard('r'))
309311
expect((inputNode as HTMLInputElement).selectionStart).toBe(3)
310312
expect((inputNode as HTMLInputElement).selectionEnd).toBe(4)
311313
expect(getByDisplayValue('zero')).toBeDefined()
312314
})
313315

314-
it('clears the input value when the user hits Escape', () => {
316+
it('clears the input value when the user hits Escape', async () => {
317+
const user = userEvent.setup()
315318
const {container} = HTMLRender(<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: []}} />)
316319
const inputNode = container.querySelector('#autocompleteInput')
317320

318321
expect(inputNode?.getAttribute('aria-expanded')).not.toBe('true')
319-
inputNode && userEvent.type(inputNode, 'ze')
322+
inputNode && (await user.type(inputNode, 'ze'))
320323
expect(inputNode?.getAttribute('aria-expanded')).toBe('true')
321-
inputNode && userEvent.type(inputNode, '{esc}')
324+
inputNode && (await user.keyboard('{escape}'))
322325
expect(inputNode?.getAttribute('aria-expanded')).not.toBe('true')
323326
})
324327

@@ -332,18 +335,20 @@ describe('Autocomplete', () => {
332335
})
333336

334337
describe('Autocomplete.Menu', () => {
335-
it('calls a custom filter function', () => {
338+
it('calls a custom filter function', async () => {
339+
const user = userEvent.setup()
336340
const filterFnMock = jest.fn()
337341
const {container} = HTMLRender(
338342
<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: [], filterFn: filterFnMock}} />
339343
)
340344
const inputNode = container.querySelector('#autocompleteInput')
341345

342-
inputNode && userEvent.type(inputNode, 'ze')
346+
inputNode && (await user.type(inputNode, 'ze'))
343347
expect(filterFnMock).toHaveBeenCalled()
344348
})
345349

346-
it('calls a custom sort function when the menu closes', () => {
350+
it('calls a custom sort function when the menu closes', async () => {
351+
const user = userEvent.setup()
347352
const sortOnCloseFnMock = jest.fn()
348353
const {container} = HTMLRender(
349354
<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: [], sortOnCloseFn: sortOnCloseFnMock}} />
@@ -354,29 +359,29 @@ describe('Autocomplete', () => {
354359
// current sort order matches the result of `sortOnCloseFnMock`
355360
expect(sortOnCloseFnMock).toHaveBeenCalledTimes(mockItems.length - 1)
356361
if (inputNode) {
357-
userEvent.type(inputNode, 'ze')
362+
await user.type(inputNode, 'ze')
358363
// eslint-disable-next-line github/no-blur
359364
fireEvent.blur(inputNode)
360365
}
361366

362367
// wait a tick for blur to finish
363-
setTimeout(() => {
364-
expect(sortOnCloseFnMock).toHaveBeenCalledTimes(mockItems.length)
365-
}, 0)
368+
await waitFor(() => expect(sortOnCloseFnMock).toHaveBeenCalled())
366369
})
367370

368-
it("calls onOpenChange with the menu's open state", () => {
371+
it("calls onOpenChange with the menu's open state", async () => {
372+
const user = userEvent.setup()
369373
const onOpenChangeMock = jest.fn()
370374
const {container} = HTMLRender(
371375
<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: [], onOpenChange: onOpenChangeMock}} />
372376
)
373377
const inputNode = container.querySelector('#autocompleteInput')
374378

375-
inputNode && userEvent.type(inputNode, 'ze')
379+
inputNode && (await user.type(inputNode, 'ze'))
376380
expect(onOpenChangeMock).toHaveBeenCalled()
377381
})
378382

379-
it('calls onSelectedChange with the data for the selected items', () => {
383+
it('calls onSelectedChange with the data for the selected items', async () => {
384+
const user = userEvent.setup()
380385
const onSelectedChangeMock = jest.fn()
381386
const {container} = HTMLRender(
382387
<LabelledAutocomplete
@@ -388,7 +393,7 @@ describe('Autocomplete', () => {
388393
expect(onSelectedChangeMock).not.toHaveBeenCalled()
389394
if (inputNode) {
390395
fireEvent.focus(inputNode)
391-
userEvent.type(inputNode, '{enter}')
396+
await user.type(inputNode, '{enter}')
392397
}
393398

394399
// wait a tick for the keyboard event to be dispatched to the menu item
@@ -397,7 +402,8 @@ describe('Autocomplete', () => {
397402
}, 0)
398403
})
399404

400-
it('does not close the menu when clicking an item in the menu if selectionVariant=multiple', () => {
405+
it('does not close the menu when clicking an item in the menu if selectionVariant=multiple', async () => {
406+
const user = userEvent.setup()
401407
const {getByText, container} = HTMLRender(
402408
<LabelledAutocomplete menuProps={{items: mockItems, selectedItemIds: [], selectionVariant: 'multiple'}} />
403409
)
@@ -408,7 +414,7 @@ describe('Autocomplete', () => {
408414
inputNode && fireEvent.focus(inputNode)
409415
expect(inputNode?.getAttribute('aria-expanded')).toBe('true')
410416
fireEvent.click(itemToClickNode)
411-
inputNode && userEvent.type(inputNode, '{enter}')
417+
inputNode && (await user.type(inputNode, '{enter}'))
412418
expect(inputNode?.getAttribute('aria-expanded')).toBe('true')
413419
})
414420

src/__tests__/Checkbox.test.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,20 @@ describe('Checkbox', () => {
4545
expect(checkbox.checked).toEqual(true)
4646
})
4747

48-
it('accepts a change handler that can alter the checkbox state', () => {
48+
it('accepts a change handler that can alter the checkbox state', async () => {
49+
const user = userEvent.setup()
4950
const handleChange = jest.fn()
5051
const {getByRole} = render(<Checkbox onChange={handleChange} />)
5152

5253
const checkbox = getByRole('checkbox') as HTMLInputElement
5354

5455
expect(checkbox.checked).toEqual(false)
5556

56-
userEvent.click(checkbox)
57+
await user.click(checkbox)
5758
expect(handleChange).toHaveBeenCalled()
5859
expect(checkbox.checked).toEqual(true)
5960

60-
userEvent.click(checkbox)
61+
await user.click(checkbox)
6162
expect(handleChange).toHaveBeenCalled()
6263
expect(checkbox.checked).toEqual(false)
6364
})
@@ -72,7 +73,8 @@ describe('Checkbox', () => {
7273
expect(checkbox.checked).toEqual(false)
7374
})
7475

75-
it('renders an inactive checkbox state correctly', () => {
76+
it('renders an inactive checkbox state correctly', async () => {
77+
const user = userEvent.setup()
7678
const handleChange = jest.fn()
7779
const {getByRole, rerender} = render(<Checkbox disabled onChange={handleChange} />)
7880

@@ -82,7 +84,7 @@ describe('Checkbox', () => {
8284
expect(checkbox.checked).toEqual(false)
8385
expect(checkbox).toHaveAttribute('aria-disabled', 'true')
8486

85-
userEvent.click(checkbox)
87+
await user.click(checkbox)
8688

8789
expect(checkbox.disabled).toEqual(true)
8890
expect(checkbox.checked).toEqual(false)
@@ -94,14 +96,15 @@ describe('Checkbox', () => {
9496
expect(checkbox).toHaveAttribute('aria-disabled', 'false')
9597
})
9698

97-
it('renders an uncontrolled component correctly', () => {
99+
it('renders an uncontrolled component correctly', async () => {
100+
const user = userEvent.setup()
98101
const {getByRole} = render(<Checkbox defaultChecked />)
99102

100103
const checkbox = getByRole('checkbox') as HTMLInputElement
101104

102105
expect(checkbox.checked).toEqual(true)
103106

104-
userEvent.click(checkbox)
107+
await user.click(checkbox)
105108

106109
expect(checkbox.checked).toEqual(false)
107110
})

0 commit comments

Comments
 (0)