33 */
44
55import React from 'react' ;
6- import { render } from '@testing-library/react' ;
6+ import { act , render , screen , waitFor } from '@testing-library/react' ;
77import userEvent from '@testing-library/user-event' ;
88import Accordion from '../Accordion' ;
99import AccordionItem from '../AccordionItem' ;
@@ -91,7 +91,8 @@ describe('Accordion', () => {
9191 ) . not . toHaveClass ( 'show' ) ;
9292 } ) ;
9393
94- test ( 'tracks most recently clicked item with "active_item" prop' , ( ) => {
94+ test ( 'tracks most recently clicked item with "active_item" prop' , async ( ) => {
95+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
9596 const mockSetProps = jest . fn ( ) ;
9697 const { container, rerender} = render (
9798 < Accordion setProps = { mockSetProps } active_item = "item-0" >
@@ -109,9 +110,7 @@ describe('Accordion', () => {
109110 accordionItems . children [ 1 ] . querySelector ( 'div.accordion-collapse' )
110111 ) . not . toHaveClass ( 'show' ) ;
111112
112- userEvent . click (
113- accordionItems . children [ 1 ] . querySelector ( 'h2.accordion-header > button' )
114- ) ;
113+ await user . click ( await screen . findByText ( 'item-title-2' ) ) ;
115114 expect ( mockSetProps . mock . calls ) . toHaveLength ( 1 ) ;
116115
117116 rerender (
@@ -120,7 +119,7 @@ describe('Accordion', () => {
120119 < AccordionItem title = "item-title-2" > item-content-2</ AccordionItem >
121120 </ Accordion >
122121 ) ;
123- jest . runAllTimers ( ) ;
122+ act ( ( ) => jest . runAllTimers ( ) ) ;
124123
125124 expect (
126125 accordionItems . children [ 0 ] . querySelector ( 'div.accordion-collapse' )
@@ -130,9 +129,7 @@ describe('Accordion', () => {
130129 ) . toHaveClass ( 'show' ) ;
131130
132131 // clicking on an open item closes it
133- userEvent . click (
134- accordionItems . children [ 1 ] . querySelector ( 'h2.accordion-header > button' )
135- ) ;
132+ await user . click ( await screen . findByText ( 'item-title-2' ) ) ;
136133 expect ( mockSetProps . mock . calls ) . toHaveLength ( 2 ) ;
137134
138135 rerender (
@@ -141,7 +138,7 @@ describe('Accordion', () => {
141138 < AccordionItem title = "item-title-2" > item-content-2</ AccordionItem >
142139 </ Accordion >
143140 ) ;
144- jest . runAllTimers ( ) ;
141+ act ( ( ) => jest . runAllTimers ( ) ) ;
145142
146143 expect (
147144 accordionItems . children [ 0 ] . querySelector ( 'div.accordion-collapse' )
@@ -151,7 +148,8 @@ describe('Accordion', () => {
151148 ) . not . toHaveClass ( 'show' ) ;
152149 } ) ;
153150
154- test ( 'keeps item open with "always_open" prop' , ( ) => {
151+ test ( 'keeps item open with "always_open" prop' , async ( ) => {
152+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
155153 const mockSetProps = jest . fn ( ) ;
156154
157155 const { container} = render (
@@ -172,34 +170,31 @@ describe('Accordion', () => {
172170 ) . not . toHaveClass ( 'show' ) ;
173171
174172 // Click on the second item
175- userEvent . click (
176- accordionItems . children [ 1 ] . querySelector ( 'h2.accordion-header > button' )
177- ) ;
173+ await user . click ( await screen . findByText ( 'item-title-2' ) ) ;
178174 expect ( mockSetProps . mock . calls ) . toHaveLength ( 1 ) ;
179175
180- // Allow the click to take effect
181- jest . runAllTimers ( ) ;
176+ // wait for transition to complete
177+ await waitFor ( ( ) =>
178+ expect (
179+ accordionItems . children [ 1 ] . querySelector ( 'div.accordion-collapse' )
180+ ) . toHaveClass ( 'show' )
181+ ) ;
182182
183183 // Check just the second item is open
184184 expect (
185185 accordionItems . children [ 0 ] . querySelector ( 'div.accordion-collapse' )
186186 ) . not . toHaveClass ( 'show' ) ;
187- expect (
188- accordionItems . children [ 1 ] . querySelector ( 'div.accordion-collapse' )
189- ) . toHaveClass ( 'show' ) ;
190187
191188 // Click on the first item
192- userEvent . click (
193- accordionItems . children [ 0 ] . querySelector ( 'h2.accordion-header > button' )
194- ) ;
189+ await user . click ( await screen . findByText ( 'item-title-1' ) ) ;
195190 expect ( mockSetProps . mock . calls ) . toHaveLength ( 2 ) ;
196- // Allow the click to take effect
197- jest . runAllTimers ( ) ;
198191
199192 // Check that the first child is now open, and the second remains open
200- expect (
201- accordionItems . children [ 0 ] . querySelector ( 'div.accordion-collapse' )
202- ) . toHaveClass ( 'show' ) ;
193+ await waitFor ( ( ) =>
194+ expect (
195+ accordionItems . children [ 0 ] . querySelector ( 'div.accordion-collapse' )
196+ ) . toHaveClass ( 'show' )
197+ ) ;
203198 expect (
204199 accordionItems . children [ 1 ] . querySelector ( 'div.accordion-collapse' )
205200 ) . toHaveClass ( 'show' ) ;
@@ -224,7 +219,8 @@ describe('Accordion', () => {
224219 ) . toHaveClass ( 'show' ) ;
225220 } ) ;
226221
227- test ( 'tracks most recently clicked item with "active_item" prop when always_open' , ( ) => {
222+ test ( 'tracks most recently clicked item with "active_item" prop when always_open' , async ( ) => {
223+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
228224 const mockSetProps = jest . fn ( ) ;
229225 const { container, rerender} = render (
230226 < Accordion setProps = { mockSetProps } active_item = { [ 'item-0' ] } always_open >
@@ -248,9 +244,7 @@ describe('Accordion', () => {
248244 ) . not . toHaveClass ( 'show' ) ;
249245
250246 // Click the middle option
251- userEvent . click (
252- accordionItems . children [ 1 ] . querySelector ( 'h2.accordion-header > button' )
253- ) ;
247+ await user . click ( await screen . getByText ( 'item-title-2' ) ) ;
254248 expect ( mockSetProps . mock . calls ) . toHaveLength ( 1 ) ;
255249
256250 rerender (
@@ -264,7 +258,7 @@ describe('Accordion', () => {
264258 < AccordionItem title = "item-title-3" > item-content-3</ AccordionItem >
265259 </ Accordion >
266260 ) ;
267- jest . runAllTimers ( ) ;
261+ act ( ( ) => jest . runAllTimers ( ) ) ;
268262
269263 // Check first option stayed open, middle option now open but third still
270264 // closed
@@ -279,9 +273,7 @@ describe('Accordion', () => {
279273 ) . not . toHaveClass ( 'show' ) ;
280274
281275 // clicking on 1st item closes it, but keeps second item open and 3rd closed
282- userEvent . click (
283- accordionItems . children [ 0 ] . querySelector ( 'h2.accordion-header > button' )
284- ) ;
276+ await user . click ( await screen . getByText ( 'item-title-1' ) ) ;
285277 expect ( mockSetProps . mock . calls ) . toHaveLength ( 2 ) ;
286278
287279 rerender (
@@ -295,7 +287,7 @@ describe('Accordion', () => {
295287 < AccordionItem title = "item-title-3" > item-content-3</ AccordionItem >
296288 </ Accordion >
297289 ) ;
298- jest . runAllTimers ( ) ;
290+ act ( ( ) => jest . runAllTimers ( ) ) ;
299291
300292 // Check that 1 and 3 now closed, and 2 is open
301293 expect (
0 commit comments