11import type { Meta , StoryObj } from "@storybook/react" ;
22import { action } from "@storybook/addon-actions" ;
3- import { expect , userEvent } from "@storybook/test" ;
3+ import { expect , userEvent , waitFor } from "@storybook/test" ;
44import { useState } from "react" ;
55import {
66 Modal ,
@@ -202,18 +202,20 @@ export const EscapeKeyCloses: Story = {
202202 } ,
203203 play : async ( ) => {
204204 // Modal is initially open
205- let modal = document . querySelector ( '[role="dialog"]' ) ;
205+ const modal = document . querySelector ( '[role="dialog"]' ) ;
206206 await expect ( modal ) . toBeInTheDocument ( ) ;
207207
208+ // Wait for modal to be fully mounted and event listeners attached
209+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
210+
208211 // Press Escape key
209212 await userEvent . keyboard ( "{Escape}" ) ;
210213
211- // Wait a bit for state update
212- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
213-
214- // Modal should be closed
215- modal = document . querySelector ( '[role="dialog"]' ) ;
216- await expect ( modal ) . not . toBeInTheDocument ( ) ;
214+ // Wait for modal to be removed from DOM
215+ await waitFor ( async ( ) => {
216+ const closedModal = document . querySelector ( '[role="dialog"]' ) ;
217+ await expect ( closedModal ) . not . toBeInTheDocument ( ) ;
218+ } ) ;
217219 } ,
218220} ;
219221
@@ -241,20 +243,22 @@ export const OverlayClickCloses: Story = {
241243 } ,
242244 play : async ( ) => {
243245 // Modal is initially open
244- let modal = document . querySelector ( '[role="dialog"]' ) ;
246+ const modal = document . querySelector ( '[role="dialog"]' ) ;
245247 await expect ( modal ) . toBeInTheDocument ( ) ;
246248
249+ // Wait for modal to be fully mounted and event listeners attached
250+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
251+
247252 // Click on overlay (role="presentation")
248253 const overlay = document . querySelector ( '[role="presentation"]' ) ;
249254 await expect ( overlay ) . toBeInTheDocument ( ) ;
250255 await userEvent . click ( overlay ! ) ;
251256
252- // Wait a bit for state update
253- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
254-
255- // Modal should be closed
256- modal = document . querySelector ( '[role="dialog"]' ) ;
257- await expect ( modal ) . not . toBeInTheDocument ( ) ;
257+ // Wait for modal to be removed from DOM
258+ await waitFor ( async ( ) => {
259+ const closedModal = document . querySelector ( '[role="dialog"]' ) ;
260+ await expect ( closedModal ) . not . toBeInTheDocument ( ) ;
261+ } ) ;
258262 } ,
259263} ;
260264
@@ -283,18 +287,18 @@ export const ContentClickDoesNotClose: Story = {
283287 } ,
284288 play : async ( ) => {
285289 // Modal is initially open
286- let modal = document . querySelector ( '[role="dialog"]' ) ;
290+ const modal = document . querySelector ( '[role="dialog"]' ) ;
287291 await expect ( modal ) . toBeInTheDocument ( ) ;
288292
289293 // Click on the modal content itself
290294 await userEvent . click ( modal ! ) ;
291295
292- // Wait a bit to ensure no state change
296+ // Give time for any potential state change
293297 await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
294298
295299 // Modal should still be open
296- modal = document . querySelector ( '[role="dialog"]' ) ;
297- await expect ( modal ) . toBeInTheDocument ( ) ;
300+ const stillOpenModal = document . querySelector ( '[role="dialog"]' ) ;
301+ await expect ( stillOpenModal ) . toBeInTheDocument ( ) ;
298302 } ,
299303} ;
300304
@@ -319,28 +323,28 @@ export const LoadingPreventsClose: Story = {
319323 } ,
320324 play : async ( ) => {
321325 // Modal is initially open
322- let modal = document . querySelector ( '[role="dialog"]' ) ;
326+ const modal = document . querySelector ( '[role="dialog"]' ) ;
323327 await expect ( modal ) . toBeInTheDocument ( ) ;
324328
325329 // Try to press Escape (should not work due to isLoading=true)
326330 await userEvent . keyboard ( "{Escape}" ) ;
327331
328- // Wait a bit
332+ // Give time for any potential state change
329333 await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
330334
331335 // Modal should still be open
332- modal = document . querySelector ( '[role="dialog"]' ) ;
333- await expect ( modal ) . toBeInTheDocument ( ) ;
336+ const stillOpenModal1 = document . querySelector ( '[role="dialog"]' ) ;
337+ await expect ( stillOpenModal1 ) . toBeInTheDocument ( ) ;
334338
335339 // Try to click overlay (should also not work)
336340 const overlay = document . querySelector ( '[role="presentation"]' ) ;
337341 await userEvent . click ( overlay ! ) ;
338342
339- // Wait a bit
343+ // Give time for any potential state change
340344 await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
341345
342346 // Modal should still be open
343- modal = document . querySelector ( '[role="dialog"]' ) ;
344- await expect ( modal ) . toBeInTheDocument ( ) ;
347+ const stillOpenModal2 = document . querySelector ( '[role="dialog"]' ) ;
348+ await expect ( stillOpenModal2 ) . toBeInTheDocument ( ) ;
345349 } ,
346350} ;
0 commit comments