Skip to content

Commit 9f619a0

Browse files
committed
replace fireEvent with userEvent
1 parent 10af6a5 commit 9f619a0

File tree

5 files changed

+92
-81
lines changed

5 files changed

+92
-81
lines changed

src/components/Dropdown/Dropdown.test.tsx

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { fireEvent, render } from '@testing-library/react'
1+
import { act, render } from '@testing-library/react'
2+
import { userEvent } from '@testing-library/user-event'
23
import { describe, expect, it, vi } from 'vitest'
34
import Dropdown from './Dropdown'
45
import styles from './Dropdown.module.css'
@@ -14,7 +15,7 @@ describe('Dropdown Component', () => {
1415
expect(div?.classList).toContain(styles.dropdownLeft)
1516
})
1617

17-
it('toggles dropdown content on button click', () => {
18+
it('toggles dropdown content on button click', async () => {
1819
const { container: { children: [ div ] }, getByRole } = render(
1920
<Dropdown label='go'>
2021
<div>Child 1</div>
@@ -24,15 +25,16 @@ describe('Dropdown Component', () => {
2425
const dropdownButton = getByRole('button')
2526

2627
// open menu with click
27-
fireEvent.click(dropdownButton)
28+
const user = userEvent.setup()
29+
await user.click(dropdownButton)
2830
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('true')
2931

3032
// click again to close
31-
fireEvent.click(dropdownButton)
33+
await user.click(dropdownButton)
3234
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('false')
3335
})
3436

35-
it('closes dropdown when clicking outside', () => {
37+
it('closes dropdown when clicking outside', async () => {
3638
const { container: { children: [ div ] }, getByRole } = render(
3739
<Dropdown>
3840
<div>Child 1</div>
@@ -41,15 +43,16 @@ describe('Dropdown Component', () => {
4143
)
4244

4345
const dropdownButton = getByRole('button')
44-
fireEvent.click(dropdownButton) // open dropdown
46+
const user = userEvent.setup()
47+
await user.click(dropdownButton) // open dropdown
4548
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('true')
4649

4750
// Simulate a click outside
48-
fireEvent.mouseDown(document)
51+
await user.click(document.body)
4952
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('false')
5053
})
5154

52-
it('does not close dropdown when clicking inside', () => {
55+
it('close dropdown when clicking inside', async () => {
5356
const { container: { children: [ div ] }, getByRole, getByText } = render(
5457
<Dropdown>
5558
<div>Child 1</div>
@@ -58,16 +61,17 @@ describe('Dropdown Component', () => {
5861
)
5962

6063
const dropdownButton = getByRole('button')
61-
fireEvent.click(dropdownButton) // open dropdown
64+
const user = userEvent.setup()
65+
await user.click(dropdownButton) // open dropdown
6266
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('true')
6367

6468
const dropdownContent = getByText('Child 1').parentElement
6569
if (!dropdownContent) throw new Error('Dropdown content not found')
66-
fireEvent.mouseDown(dropdownContent)
67-
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('true')
70+
await user.click(dropdownContent)
71+
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('false')
6872
})
6973

70-
it('closes dropdown on escape key press', () => {
74+
it('closes dropdown on escape key press', async () => {
7175
const { container: { children: [ div ] }, getByRole } = render(
7276
<Dropdown>
7377
<div>Child 1</div>
@@ -76,11 +80,12 @@ describe('Dropdown Component', () => {
7680
)
7781

7882
const dropdownButton = getByRole('button')
79-
fireEvent.click(dropdownButton) // open dropdown
83+
const user = userEvent.setup()
84+
await user.click(dropdownButton) // open dropdown
8085
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('true')
8186

8287
// Press escape key
83-
fireEvent.keyDown(document, { key: 'Escape', code: 'Escape' })
88+
await user.keyboard('{Escape}')
8489
expect(div?.children[0]?.getAttribute('aria-expanded')).toBe('false')
8590
})
8691

@@ -107,7 +112,7 @@ describe('Dropdown Component', () => {
107112
})
108113

109114
// Keyboard navigation tests
110-
it('opens dropdown and focuses first item on ArrowDown when closed', () => {
115+
it('opens dropdown and focuses first item on ArrowDown when closed', async () => {
111116
const { getByRole, getAllByRole } = render(
112117
<Dropdown label="Menu">
113118
<button role="menuitem">Item 1</button>
@@ -120,15 +125,20 @@ describe('Dropdown Component', () => {
120125
// initially closed
121126
expect(dropdownButton.getAttribute('aria-expanded')).toBe('false')
122127

128+
// focus the button
129+
act(() => {
130+
dropdownButton.focus()
131+
})
123132
// down arrow to open menu
124-
fireEvent.keyDown(dropdownButton, { key: 'ArrowDown', code: 'ArrowDown' })
133+
const user = userEvent.setup()
134+
await user.keyboard('{ArrowDown}')
125135
expect(dropdownButton.getAttribute('aria-expanded')).toBe('true')
126136

127137
// first menu item should be focused
128138
expect(document.activeElement).toBe(menuItems[0])
129139
})
130140

131-
it('focuses the next item on ArrowDown and wraps to first item if at the end', () => {
141+
it('focuses the next item on ArrowDown and wraps to first item if at the end', async () => {
132142
const { getByRole, getAllByRole } = render(
133143
<Dropdown label="Menu">
134144
<button role="menuitem">Item 1</button>
@@ -139,19 +149,20 @@ describe('Dropdown Component', () => {
139149
const dropdownButton = getByRole('button')
140150

141151
// open menu, first item has focus
142-
fireEvent.click(dropdownButton)
152+
const user = userEvent.setup()
153+
await user.click(dropdownButton)
143154
expect(document.activeElement).toBe(menuItems[0])
144155

145156
// second item should be focused
146-
fireEvent.keyDown(menuItems[0], { key: 'ArrowDown', code: 'ArrowDown' })
157+
await user.keyboard('{ArrowDown}')
147158
expect(document.activeElement).toBe(menuItems[1])
148159

149160
// wrap back to first item
150-
fireEvent.keyDown(menuItems[1], { key: 'ArrowDown', code: 'ArrowDown' })
161+
await user.keyboard('{ArrowDown}')
151162
expect(document.activeElement).toBe(menuItems[0])
152163
})
153164

154-
it('focuses the previous item on ArrowUp and wraps to the last item if at the top', () => {
165+
it('focuses the previous item on ArrowUp and wraps to the last item if at the top', async () => {
155166
const { getByRole, getAllByRole } = render(
156167
<Dropdown label="Menu">
157168
<button role="menuitem">Item 1</button>
@@ -162,15 +173,16 @@ describe('Dropdown Component', () => {
162173
const dropdownButton = getByRole('button')
163174

164175
// open menu, first item has focus
165-
fireEvent.click(dropdownButton)
176+
const user = userEvent.setup()
177+
await user.click(dropdownButton)
166178
expect(document.activeElement).toBe(menuItems[0])
167179

168180
// ArrowUp -> should wrap to last item
169-
fireEvent.keyDown(menuItems[0], { key: 'ArrowUp', code: 'ArrowUp' })
181+
await user.keyboard('{ArrowUp}')
170182
expect(document.activeElement).toBe(menuItems[1])
171183
})
172184

173-
it('focuses first item on Home key press', () => {
185+
it('focuses first item on Home key press', async () => {
174186
const { getByRole, getAllByRole } = render(
175187
<Dropdown label="Menu">
176188
<button role="menuitem">Item 1</button>
@@ -182,19 +194,20 @@ describe('Dropdown Component', () => {
182194
const dropdownButton = getByRole('button')
183195

184196
// open menu, first item has focus
185-
fireEvent.click(dropdownButton)
197+
const user = userEvent.setup()
198+
await user.click(dropdownButton)
186199
expect(document.activeElement).toBe(menuItems[0])
187200

188201
// move to the second item
189-
fireEvent.keyDown(menuItems[0], { key: 'ArrowDown', code: 'ArrowDown' })
202+
await user.keyboard('{ArrowDown}')
190203
expect(document.activeElement).toBe(menuItems[1])
191204

192205
// Home key should focus first item
193-
fireEvent.keyDown(menuItems[1], { key: 'Home', code: 'Home' })
206+
await user.keyboard('{Home}')
194207
expect(document.activeElement).toBe(menuItems[0])
195208
})
196209

197-
it('focuses last item on End key press', () => {
210+
it('focuses last item on End key press', async () => {
198211
const { getByRole, getAllByRole } = render(
199212
<Dropdown label="Menu">
200213
<button role="menuitem">Item 1</button>
@@ -206,15 +219,16 @@ describe('Dropdown Component', () => {
206219
const dropdownButton = getByRole('button')
207220

208221
// open menu, first item has focus
209-
fireEvent.click(dropdownButton)
222+
const user = userEvent.setup()
223+
await user.click(dropdownButton)
210224
expect(document.activeElement).toBe(menuItems[0])
211225

212226
// End key should focus the last item
213-
fireEvent.keyDown(menuItems[0], { key: 'End', code: 'End' })
227+
await user.keyboard('{End}')
214228
expect(document.activeElement).toBe(menuItems[2])
215229
})
216230

217-
it('closes the menu and puts focus back on the button on Escape', () => {
231+
it('closes the menu and puts focus back on the button on Escape', async () => {
218232
const { getByRole, getAllByRole } = render(
219233
<Dropdown label="Menu">
220234
<button role="menuitem">Item 1</button>
@@ -225,12 +239,13 @@ describe('Dropdown Component', () => {
225239
const dropdownButton = getByRole('button')
226240

227241
// open menu, first item has focus
228-
fireEvent.click(dropdownButton)
242+
const user = userEvent.setup()
243+
await user.click(dropdownButton)
229244
expect(document.activeElement).toBe(menuItems[0])
230245
expect(dropdownButton.getAttribute('aria-expanded')).toBe('true')
231246

232247
// escape closes menu
233-
fireEvent.keyDown(menuItems[0], { key: 'Escape', code: 'Escape' })
248+
await user.keyboard('{Escape}')
234249
expect(dropdownButton.getAttribute('aria-expanded')).toBe('false')
235250

236251
// focus returns to the button

src/components/Folder/Folder.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { render, waitFor } from '@testing-library/react'
2+
import { userEvent } from '@testing-library/user-event'
23
import { strict as assert } from 'assert'
34
import { act } from 'react'
45
import { beforeEach, describe, expect, it, test, vi } from 'vitest'
56
import { Config, ConfigProvider } from '../../hooks/useConfig.js'
67
import { DirSource, FileMetadata, HyperparamFileMetadata, getHyperparamSource } from '../../lib/sources/index.js'
78
import Folder from './Folder.js'
8-
import { userEvent } from '@testing-library/user-event'
99

1010
const endpoint = 'http://localhost:3000'
1111
const mockFiles: HyperparamFileMetadata[] = [

src/components/Json/Json.test.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { fireEvent, render } from '@testing-library/react'
1+
import { render } from '@testing-library/react'
2+
import { userEvent } from '@testing-library/user-event'
23
import { describe, expect, it } from 'vitest'
34
import Json from './Json.js'
45
import { isPrimitive, shouldObjectCollapse } from './helpers.js'
@@ -89,13 +90,14 @@ describe('Json Component', () => {
8990
it.for([
9091
{ obj: [314, null] },
9192
{ obj: { nested: true } },
92-
])('hides the content and append number of entries when objects with non-primitive values are collapsed', (obj) => {
93+
])('hides the content and append number of entries when objects with non-primitive values are collapsed', async (obj) => {
9394
const { getAllByRole, getByText } = render(<Json json={obj} />)
9495
const root = getAllByRole('treeitem')[0]
9596
if (!root) { /* type assertion, getAllByRole would already have thrown */
9697
throw new Error('No root element found')
9798
}
98-
fireEvent.click(root)
99+
const user = userEvent.setup()
100+
await user.click(root)
99101
expect(root.getAttribute('aria-expanded')).toBe('false')
100102
getByText('...')
101103
getByText(/entries/)
@@ -119,25 +121,27 @@ describe('Json Component', () => {
119121
getByText(/entries/)
120122
})
121123

122-
it('toggles array collapse state', () => {
124+
it('toggles array collapse state', async () => {
123125
const longArray = Array.from({ length: 101 }, (_, i) => i)
124126
const { getByRole, getByText, queryByText } = render(<Json json={longArray} />)
125127
const treeItem = getByRole('treeitem')
126128
getByText('...')
127-
fireEvent.click(treeItem)
129+
const user = userEvent.setup()
130+
await user.click(treeItem)
128131
expect(queryByText('...')).toBeNull()
129-
fireEvent.click(treeItem)
132+
await user.click(treeItem)
130133
getByText('...')
131134
})
132135

133-
it('toggles object collapse state', () => {
136+
it('toggles object collapse state', async () => {
134137
const longObject = Object.fromEntries(Array.from({ length: 101 }, (_, i) => [`key${i}`, { nested: true }]))
135138
const { getByRole, getByText, queryByText } = render(<Json json={longObject} />)
136139
const treeItem = getByRole('treeitem') // only one treeitem because the inner objects are collapsed and not represented as treeitems
137140
getByText('...')
138-
fireEvent.click(treeItem)
141+
const user = userEvent.setup()
142+
await user.click(treeItem)
139143
expect(queryByText('...')).toBeNull()
140-
fireEvent.click(treeItem)
144+
await user.click(treeItem)
141145
getByText('...')
142146
})
143147
})

src/components/SlidePanel/SlidePanel.test.tsx

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

2-
import { act, fireEvent, render } from '@testing-library/react'
2+
import { act, render } from '@testing-library/react'
3+
import { userEvent } from '@testing-library/user-event'
34
import { beforeEach, describe, expect, it, vi } from 'vitest'
45
import { ConfigProvider } from '../../hooks/useConfig.js'
56
import SlidePanel from './SlidePanel.js'
@@ -86,7 +87,7 @@ describe('SlidePanel', () => {
8687
expect(panel.style.width).toBe('400px')
8788
})
8889

89-
it('respects minWidth from config', () => {
90+
it('respects minWidth from config', async () => {
9091
const { getByRole } = render(
9192
<ConfigProvider value={{ slidePanel: { minWidth: 300 } }}>
9293
<SlidePanel
@@ -100,22 +101,20 @@ describe('SlidePanel', () => {
100101
const panel = getByRole('complementary')
101102
expect(panel.style.width).toBe('400px')
102103

103-
// Simulate mousedown on resizer with clientX 800
104-
act(() => {
105-
fireEvent.mouseDown(resizer, { clientX: 800 })
106-
})
107-
108-
// Simulate mousemove on document with clientX such that new width is less than minWidth
109-
act(() => {
110-
fireEvent.mouseMove(document, { clientX: 950 })
111-
fireEvent.mouseUp(document)
112-
})
104+
const user = userEvent.setup()
105+
await user.pointer([
106+
// Simulate mousedown on resizer with clientX 800
107+
{ keys: '[MouseLeft>]', target: resizer, coords: { x: 800, y: 0 } },
108+
// Simulate mousemove on document with clientX such that new width is less than minWidth
109+
{ coords: { x: 950, y: 0 } },
110+
{ keys: '[/MouseLeft]' },
111+
])
113112

114113
// resizingClientX was set to 800 + 400 = 1200 so new width = max(300, 1200 - 950) = 300
115114
expect(panel.style.width).toBe('300px')
116115
})
117116

118-
it('handles dragging to resize', () => {
117+
it('handles dragging to resize', async () => {
119118
const { getByRole } = render(
120119
<SlidePanel
121120
mainContent={<div>Main</div>}
@@ -130,20 +129,12 @@ describe('SlidePanel', () => {
130129
// Mock panel's offsetWidth to be 400px
131130
Object.defineProperty(panel, 'offsetWidth', { value: 400, configurable: true })
132131

133-
// Simulate mousedown
134-
act(() => {
135-
fireEvent.mouseDown(resizer, { clientX: 800 })
136-
})
137-
138-
// Simulate dragging
139-
act(() => {
140-
fireEvent.mouseMove(document, { clientX: 750 })
141-
})
142-
143-
// End dragging
144-
act(() => {
145-
fireEvent.mouseUp(document)
146-
})
132+
const user = userEvent.setup()
133+
await user.pointer([
134+
{ keys: '[MouseLeft>]', target: resizer, coords: { x: 800, y: 0 } },
135+
{ coords: { x: 750, y: 0 } },
136+
{ keys: '[/MouseLeft]' },
137+
])
147138

148139
// Expected new width = 1200 - 750 = 450
149140
expect(panel.style.width).toBe('450px')

0 commit comments

Comments
 (0)