1- import { cleanup , render as HTMLRender , waitFor , fireEvent } from '@testing-library/react'
1+ import { cleanup , render as HTMLRender , waitFor } from '@testing-library/react'
22import userEvent from '@testing-library/user-event'
33import 'babel-polyfill'
44import { axe , toHaveNoViolations } from 'jest-axe'
@@ -49,55 +49,66 @@ describe('ActionMenu', () => {
4949
5050 it ( 'should open Menu on MenuButton click' , async ( ) => {
5151 const component = HTMLRender ( < Example /> )
52- const button = component . getByText ( 'Toggle Menu' )
53- fireEvent . click ( button )
52+ const button = component . getByRole ( 'button' )
53+
54+ const user = userEvent . setup ( )
55+ await user . click ( button )
56+
5457 expect ( component . getByRole ( 'menu' ) ) . toBeInTheDocument ( )
5558 cleanup ( )
5659 } )
5760
5861 it ( 'should open Menu on MenuButton keypress' , async ( ) => {
5962 const component = HTMLRender ( < Example /> )
60- const button = component . getByText ( 'Toggle Menu' )
63+ const button = component . getByRole ( 'button' )
64+
65+ const user = userEvent . setup ( )
66+ button . focus ( )
67+ await user . keyboard ( '{Enter}' )
6168
62- fireEvent . keyDown ( button , { key : 'Enter' } )
6369 expect ( component . getByRole ( 'menu' ) ) . toBeInTheDocument ( )
6470 cleanup ( )
6571 } )
6672
6773 it ( 'should close Menu on selecting an action with click' , async ( ) => {
6874 const component = HTMLRender ( < Example /> )
69- const button = component . getByText ( 'Toggle Menu ')
75+ const button = component . getByRole ( 'button ')
7076
71- fireEvent . click ( button )
72- const menuItems = await waitFor ( ( ) => component . getAllByRole ( 'menuitem' ) )
73- fireEvent . click ( menuItems [ 0 ] )
74- expect ( component . queryByRole ( 'menu' ) ) . toBeNull ( )
77+ const user = userEvent . setup ( )
78+ await user . click ( button )
79+
80+ const menuItems = component . getAllByRole ( 'menuitem' )
81+ await user . click ( menuItems [ 0 ] )
7582
83+ expect ( component . queryByRole ( 'menu' ) ) . toBeNull ( )
7684 cleanup ( )
7785 } )
7886
7987 it ( 'should close Menu on selecting an action with Enter' , async ( ) => {
8088 const component = HTMLRender ( < Example /> )
81- const button = component . getByText ( 'Toggle Menu ')
89+ const button = component . getByRole ( 'button ')
8290
83- fireEvent . click ( button )
84- const menuItems = await waitFor ( ( ) => component . getAllByRole ( 'menuitem' ) )
91+ const user = userEvent . setup ( )
92+ await user . click ( button )
8593
86- // We pass keycode here to navigate a implementation detail in react-testing-library
87- // https://github.com/testing-library/react-testing-library/issues/269#issuecomment-455854112
88- fireEvent . keyPress ( menuItems [ 0 ] , { key : 'Enter' , charCode : 13 } )
89- expect ( component . queryByRole ( 'menu' ) ) . toBeNull ( )
94+ const menuItems = component . getAllByRole ( 'menuitem' )
95+ menuItems [ 0 ] . focus ( )
96+ await user . keyboard ( '{Enter}' )
9097
98+ expect ( component . queryByRole ( 'menu' ) ) . toBeNull ( )
9199 cleanup ( )
92100 } )
93101
94102 it ( 'should not close Menu if event is prevented' , async ( ) => {
95103 const component = HTMLRender ( < Example /> )
96- const button = component . getByText ( 'Toggle Menu' )
104+ const button = component . getByRole ( 'button' )
105+
106+ const user = userEvent . setup ( )
107+ await user . click ( button )
108+
109+ const menuItems = component . getAllByRole ( 'menuitem' )
110+ await user . click ( menuItems [ 3 ] )
97111
98- fireEvent . click ( button )
99- const menuItems = await waitFor ( ( ) => component . getAllByRole ( 'menuitem' ) )
100- fireEvent . click ( menuItems [ 3 ] )
101112 // menu should still be open
102113 expect ( component . getByRole ( 'menu' ) ) . toBeInTheDocument ( )
103114
@@ -111,14 +122,16 @@ describe('ActionMenu', () => {
111122 </ ThemeProvider >
112123 )
113124 const button = component . getByLabelText ( 'Field type' )
114- fireEvent . click ( button )
125+
126+ const user = userEvent . setup ( )
127+ await user . click ( button )
115128
116129 // select first item by role, that would close the menu
117- fireEvent . click ( component . getAllByRole ( 'menuitemradio' ) [ 0 ] )
130+ await user . click ( component . getAllByRole ( 'menuitemradio' ) [ 0 ] )
118131 expect ( component . queryByRole ( 'menu' ) ) . not . toBeInTheDocument ( )
119132
120133 // open menu again and check if the first option is checked
121- fireEvent . click ( button )
134+ await user . click ( button )
122135 expect ( component . getAllByRole ( 'menuitemradio' ) [ 0 ] ) . toHaveAttribute ( 'aria-checked' , 'true' )
123136 cleanup ( )
124137 } )
@@ -130,7 +143,9 @@ describe('ActionMenu', () => {
130143 </ ThemeProvider >
131144 )
132145 const button = component . getByLabelText ( 'Group by' )
133- fireEvent . click ( button )
146+
147+ const user = userEvent . setup ( )
148+ await user . click ( button )
134149
135150 expect ( component . getByLabelText ( 'Status' ) ) . toHaveAttribute ( 'role' , 'menuitemradio' )
136151 expect ( component . getByLabelText ( 'Clear Group by' ) ) . toHaveAttribute ( 'role' , 'menuitem' )
@@ -142,53 +157,48 @@ describe('ActionMenu', () => {
142157 const component = HTMLRender ( < Example /> )
143158 const button = component . getByRole ( 'button' )
144159
145- userEvent . tab ( ) // tab into the story, this should focus on the first button
160+ const user = userEvent . setup ( )
161+ await user . tab ( ) // tab into the story, this should focus on the first button
146162 expect ( button ) . toEqual ( document . activeElement ) // trust, but verify
147163
148- userEvent . click ( button )
164+ await user . click ( button )
149165 expect ( component . queryByRole ( 'menu' ) ) . toBeInTheDocument ( )
150-
151- /** We use waitFor because the hook uses an effect with setTimeout
152- * and we need to wait for that to happen in the next tick
153- */
154- await waitFor ( ( ) => expect ( document . activeElement ) . toEqual ( button ) )
166+ expect ( document . activeElement ) . toEqual ( button )
155167
156168 cleanup ( )
157169 } )
158170
159171 it ( 'should select first element when ArrowDown is pressed after opening Menu with click' , async ( ) => {
160172 const component = HTMLRender ( < Example /> )
173+ const button = component . getByRole ( 'button' )
161174
162- const button = component . getByText ( 'Toggle Menu' )
163- button . focus ( ) // browsers do this automatically on click, but tests don't
164- fireEvent . click ( button )
165- expect ( component . queryByRole ( 'menu' ) ) . toBeInTheDocument ( )
175+ const user = userEvent . setup ( )
176+ await user . click ( button )
166177
167- // button should be the active element
168- fireEvent . keyDown ( document . activeElement ! , { key : 'ArrowDown' , code : 'ArrowDown' } )
178+ expect ( component . queryByRole ( 'menu' ) ) . toBeInTheDocument ( )
169179
170- await waitFor ( ( ) => {
171- expect ( component . getAllByRole ( 'menuitem' ) [ 0 ] ) . toEqual ( document . activeElement )
172- } )
180+ // assumes button is the active element at this point
181+ await user . keyboard ( '{ArrowDown}' )
173182
183+ expect ( component . getAllByRole ( 'menuitem' ) [ 0 ] ) . toEqual ( document . activeElement )
174184 cleanup ( )
175185 } )
176186
177187 it ( 'should select last element when ArrowUp is pressed after opening Menu with click' , async ( ) => {
178188 const component = HTMLRender ( < Example /> )
179189
180- const button = component . getByText ( 'Toggle Menu' )
181- button . focus ( ) // browsers do this automatically on click, but tests don't
182- fireEvent . click ( button )
190+ const button = component . getByRole ( 'button' )
191+
192+ const user = userEvent . setup ( )
193+ await user . click ( button )
194+
183195 expect ( component . queryByRole ( 'menu' ) ) . toBeInTheDocument ( )
184196
185197 // button should be the active element
186- fireEvent . keyDown ( document . activeElement ! , { key : 'ArrowUp' , code : 'ArrowUp' } )
187-
188- await waitFor ( ( ) => {
189- expect ( component . getAllByRole ( 'menuitem' ) . pop ( ) ) . toEqual ( document . activeElement )
190- } )
198+ // assumes button is the active element at this point
199+ await user . keyboard ( '{ArrowUp}' )
191200
201+ expect ( component . getAllByRole ( 'menuitem' ) . pop ( ) ) . toEqual ( document . activeElement )
192202 cleanup ( )
193203 } )
194204
@@ -201,16 +211,17 @@ describe('ActionMenu', () => {
201211 )
202212 const anchor = component . getByRole ( 'button' )
203213
204- userEvent . tab ( ) // tab into the story, this should focus on the first button
214+ const user = userEvent . setup ( )
215+ await user . tab ( ) // tab into the story, this should focus on the first button
205216 expect ( anchor ) . toEqual ( document . activeElement ) // trust, but verify
206217
207- fireEvent . keyDown ( anchor , { key : ' Enter' } )
218+ await user . keyboard ( '{ Enter}' )
208219 expect ( component . queryByRole ( 'menu' ) ) . toBeInTheDocument ( )
209-
210220 expect ( component . getAllByRole ( 'menuitem' ) [ 0 ] ) . toEqual ( document . activeElement )
211221
212- await waitFor ( ( ) => {
213- userEvent . tab ( )
222+ // TODO: revisit why we need this waitFor
223+ await waitFor ( async ( ) => {
224+ await user . tab ( )
214225 expect ( document . activeElement ) . toEqual ( component . getByPlaceholderText ( 'next focusable element' ) )
215226 expect ( component . queryByRole ( 'menu' ) ) . not . toBeInTheDocument ( )
216227 } )
0 commit comments