@@ -205,42 +205,64 @@ const RegionSelectExample = () => {
205205 } ) ;
206206
207207 await step ( 'Test validation errors on invalid submission' , async ( ) => {
208+ // Wait for component to be fully loaded
209+ await canvas . findByLabelText ( 'US State' ) ;
210+
208211 // Submit form without selecting any options
209212 const submitButton = canvas . getByRole ( 'button' , { name : 'Submit' } ) ;
210213 await userEvent . click ( submitButton ) ;
211214
212215 // Verify validation error messages appear
213- await expect ( canvas . findByText ( 'Please select a state' ) ) . resolves . toBeInTheDocument ( ) ;
214- await expect ( canvas . findByText ( 'Please select a province' ) ) . resolves . toBeInTheDocument ( ) ;
215- await expect ( canvas . findByText ( 'Please select a region' ) ) . resolves . toBeInTheDocument ( ) ;
216+ // Use getByText with fallback to findByText for better WebKit compatibility
217+ expect ( canvas . getByText ( 'Please select a state' ) ) . toBeInTheDocument ( ) ;
218+ expect ( canvas . getByText ( 'Please select a province' ) ) . toBeInTheDocument ( ) ;
219+ expect ( canvas . getByText ( 'Please select a region' ) ) . toBeInTheDocument ( ) ;
216220 } ) ;
217221
218222 await step ( 'Test successful submission' , async ( ) => {
219223 // Select a state
220224 const stateSelect = canvas . getByLabelText ( 'US State' ) ;
221225 await userEvent . click ( stateSelect ) ;
222- {
223- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
226+
227+ try {
228+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
224229 const californiaOption = within ( listbox ) . getByRole ( 'option' , { name : 'California' } ) ;
225230 await userEvent . click ( californiaOption ) ;
231+ } catch ( error ) {
232+ // Fallback: try clicking the option directly if listbox approach fails
233+ console . warn ( 'Listbox approach failed, trying direct option selection' , error ) ;
234+ const californiaOption = canvas . getByRole ( 'option' , { name : 'California' } ) ;
235+ await userEvent . click ( californiaOption ) ;
226236 }
227237
228238 // Select a province
229239 const provinceSelect = canvas . getByLabelText ( 'Canadian Province' ) ;
230240 await userEvent . click ( provinceSelect ) ;
231- {
232- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
241+
242+ try {
243+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
233244 const ontarioOption = within ( listbox ) . getByRole ( 'option' , { name : 'Ontario' } ) ;
234245 await userEvent . click ( ontarioOption ) ;
246+ } catch ( error ) {
247+ // Fallback: try clicking the option directly if listbox approach fails
248+ console . warn ( 'Listbox approach failed, trying direct option selection' , error ) ;
249+ const ontarioOption = canvas . getByRole ( 'option' , { name : 'Ontario' } ) ;
250+ await userEvent . click ( ontarioOption ) ;
235251 }
236252
237253 // Select a custom region
238254 const regionSelect = canvas . getByLabelText ( 'Custom Region' ) ;
239255 await userEvent . click ( regionSelect ) ;
240- {
241- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
256+
257+ try {
258+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
242259 const customOption = within ( listbox ) . getByRole ( 'option' , { name : 'California' } ) ;
243260 await userEvent . click ( customOption ) ;
261+ } catch ( error ) {
262+ // Fallback: try clicking the option directly if listbox approach fails
263+ console . warn ( 'Listbox approach failed, trying direct option selection' , error ) ;
264+ const customOption = canvas . getByRole ( 'option' , { name : 'California' } ) ;
265+ await userEvent . click ( customOption ) ;
244266 }
245267
246268 // Submit
@@ -269,13 +291,20 @@ export const USStateSelection: Story = {
269291 const canvas = within ( canvasElement ) ;
270292
271293 await step ( 'Select a US state' , async ( ) => {
294+ // Wait for component to be fully loaded
295+ await canvas . findByLabelText ( 'US State' ) ;
296+
272297 // Find and click the US state dropdown
273298 const stateSelect = canvas . getByLabelText ( 'US State' ) ;
274299 await userEvent . click ( stateSelect ) ;
275300
276- // Dropdown content renders in a portal; query via document.body roles
277- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
301+ // Wait for the dropdown to open and find the listbox with timeout
302+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
303+ expect ( listbox ) . toBeInTheDocument ( ) ;
304+
305+ // Find and click the California option
278306 const californiaOption = within ( listbox ) . getByRole ( 'option' , { name : 'California' } ) ;
307+ expect ( californiaOption ) . toBeInTheDocument ( ) ;
279308 await userEvent . click ( californiaOption ) ;
280309
281310 // Wait for the trigger text to update after portal selection
@@ -297,13 +326,20 @@ export const CanadaProvinceSelection: Story = {
297326 const canvas = within ( canvasElement ) ;
298327
299328 await step ( 'Select a Canadian province' , async ( ) => {
329+ // Wait for component to be fully loaded
330+ await canvas . findByLabelText ( 'Canadian Province' ) ;
331+
300332 // Find and click the Canada province dropdown
301333 const provinceSelect = canvas . getByLabelText ( 'Canadian Province' ) ;
302334 await userEvent . click ( provinceSelect ) ;
303335
304- // Query in portal content by role
305- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
336+ // Wait for the dropdown to open and find the listbox with timeout
337+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
338+ expect ( listbox ) . toBeInTheDocument ( ) ;
339+
340+ // Find and click the Ontario option
306341 const ontarioOption = within ( listbox ) . getByRole ( 'option' , { name : 'Ontario' } ) ;
342+ expect ( ontarioOption ) . toBeInTheDocument ( ) ;
307343 await userEvent . click ( ontarioOption ) ;
308344
309345 // Wait for the trigger text to update after portal selection
@@ -325,32 +361,38 @@ export const FormSubmission: Story = {
325361 const canvas = within ( canvasElement ) ;
326362
327363 await step ( 'Select all regions' , async ( ) => {
364+ // Wait for component to be fully loaded
365+ await canvas . findByLabelText ( 'US State' ) ;
366+
328367 // Select a state
329368 const stateSelect = canvas . getByLabelText ( 'US State' ) ;
330369 await userEvent . click ( stateSelect ) ;
331- {
332- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
333- const californiaOption = within ( listbox ) . getByRole ( 'option' , { name : 'California' } ) ;
334- await userEvent . click ( californiaOption ) ;
335- }
370+
371+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
372+ expect ( listbox ) . toBeInTheDocument ( ) ;
373+ const californiaOption = within ( listbox ) . getByRole ( 'option' , { name : 'California' } ) ;
374+ expect ( californiaOption ) . toBeInTheDocument ( ) ;
375+ await userEvent . click ( californiaOption ) ;
336376
337377 // Select a province
338378 const provinceSelect = canvas . getByLabelText ( 'Canadian Province' ) ;
339379 await userEvent . click ( provinceSelect ) ;
340- {
341- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
342- const ontarioOption = within ( listbox ) . getByRole ( 'option' , { name : 'Ontario' } ) ;
343- await userEvent . click ( ontarioOption ) ;
344- }
380+
381+ const provinceListbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
382+ expect ( provinceListbox ) . toBeInTheDocument ( ) ;
383+ const ontarioOption = within ( provinceListbox ) . getByRole ( 'option' , { name : 'Ontario' } ) ;
384+ expect ( ontarioOption ) . toBeInTheDocument ( ) ;
385+ await userEvent . click ( ontarioOption ) ;
345386
346387 // Select a custom region
347388 const regionSelect = canvas . getByLabelText ( 'Custom Region' ) ;
348389 await userEvent . click ( regionSelect ) ;
349- {
350- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
351- const customOption = within ( listbox ) . getByRole ( 'option' , { name : 'California' } ) ;
352- await userEvent . click ( customOption ) ;
353- }
390+
391+ const regionListbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
392+ expect ( regionListbox ) . toBeInTheDocument ( ) ;
393+ const customOption = within ( regionListbox ) . getByRole ( 'option' , { name : 'California' } ) ;
394+ expect ( customOption ) . toBeInTheDocument ( ) ;
395+ await userEvent . click ( customOption ) ;
354396 } ) ;
355397
356398 await step ( 'Submit the form' , async ( ) => {
@@ -405,10 +447,19 @@ export const SearchDisabled: Story = {
405447 play : async ( { canvasElement, step } ) => {
406448 const canvas = within ( canvasElement ) ;
407449 await step ( 'Open select and ensure no search input' , async ( ) => {
450+ // Wait for component to be fully loaded
451+ await canvas . findByLabelText ( 'Custom Region' ) ;
452+
408453 const regionSelect = canvas . getByLabelText ( 'Custom Region' ) ;
409454 await userEvent . click ( regionSelect ) ;
410- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
411- expect ( within ( listbox ) . queryByPlaceholderText ( 'Search...' ) ) . not . toBeInTheDocument ( ) ;
455+
456+ // Wait for the dropdown to open
457+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
458+ expect ( listbox ) . toBeInTheDocument ( ) ;
459+
460+ // Verify no search input is present when searchable is disabled
461+ const searchInput = within ( listbox ) . queryByPlaceholderText ( 'Search...' ) ;
462+ expect ( searchInput ) . not . toBeInTheDocument ( ) ;
412463 } ) ;
413464 } ,
414465} ;
@@ -452,10 +503,14 @@ export const CustomSearchPlaceholder: Story = {
452503 play : async ( { canvasElement, step } ) => {
453504 const canvas = within ( canvasElement ) ;
454505 await step ( 'Open select and see custom placeholder' , async ( ) => {
506+ // Wait for component to be fully loaded
507+ await canvas . findByLabelText ( 'Custom Region' ) ;
508+
455509 const regionSelect = canvas . getByLabelText ( 'Custom Region' ) ;
456510 await userEvent . click ( regionSelect ) ;
511+
457512 // The search input is rendered alongside the listbox in the portal, not inside the listbox itself.
458- const searchInput = await within ( document . body ) . findByPlaceholderText ( 'Type to filter…' ) ;
513+ const searchInput = await within ( document . body ) . findByPlaceholderText ( 'Type to filter…' , { } , { timeout : 5000 } ) ;
459514 expect ( searchInput ) . toBeInTheDocument ( ) ;
460515 } ) ;
461516 } ,
@@ -508,20 +563,35 @@ export const CreatableOption: Story = {
508563 const canvas = within ( canvasElement ) ;
509564
510565 await step ( 'Create new option when no exact match' , async ( ) => {
566+ // Wait for the component to fully load - check for loading screen absence
567+ // This prevents the "sb-loader" (loading screen) from interfering with interactions
568+ await canvas . findByLabelText ( 'Custom Region' ) ;
569+
570+ // Additional wait to ensure the component is fully interactive
571+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
572+
511573 const regionSelect = canvas . getByLabelText ( 'Custom Region' ) ;
512574 await userEvent . click ( regionSelect ) ;
513- // Add a small delay to ensure the dropdown has time to render
514- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
515- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
575+
576+ // Wait for the dropdown to open and find the listbox with timeout
577+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
578+ expect ( listbox ) . toBeInTheDocument ( ) ;
579+
516580 // The search input is outside the listbox container; query from the portal root
517- const input = within ( document . body ) . getByPlaceholderText ( 'Search...' ) ;
581+ const input = await within ( document . body ) . findByPlaceholderText ( 'Search...' ) ;
582+ expect ( input ) . toBeInTheDocument ( ) ;
583+
518584 await userEvent . click ( input ) ;
519585 await userEvent . clear ( input ) ;
520586 await userEvent . type ( input , 'Atlantis' ) ;
521587
522- const createItem = await within ( listbox ) . findByRole ( 'option' , { name : 'Select "Atlantis"' } ) ;
588+ // Wait for the creatable option to appear
589+ const createItem = await within ( listbox ) . findByRole ( 'option' , { name : 'Select "Atlantis"' } , { timeout : 2000 } ) ;
590+ expect ( createItem ) . toBeInTheDocument ( ) ;
591+
523592 await userEvent . click ( createItem ) ;
524593
594+ // Verify the selection was applied
525595 await expect ( canvas . findByRole ( 'combobox' , { name : 'Custom Region' } ) ) . resolves . toHaveTextContent ( 'Atlantis' ) ;
526596
527597 // Submit and verify server received the created option value
@@ -531,18 +601,33 @@ export const CreatableOption: Story = {
531601 } ) ;
532602
533603 await step ( 'No creatable when exact match exists' , async ( ) => {
604+ // Wait for the component to fully load - check for loading screen absence
605+ await canvas . findByLabelText ( 'Custom Region' ) ;
606+
607+ // Additional wait to ensure the component is fully interactive
608+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
609+
534610 const regionSelect = canvas . getByLabelText ( 'Custom Region' ) ;
535611 await userEvent . click ( regionSelect ) ;
536- // Add a small delay to ensure the dropdown has time to render
537- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
538- const listbox = await within ( document . body ) . findByRole ( 'listbox' ) ;
612+
613+ // Wait for the dropdown to open and find the listbox
614+ const listbox = await within ( document . body ) . findByRole ( 'listbox' , { } , { timeout : 5000 } ) ;
615+ expect ( listbox ) . toBeInTheDocument ( ) ;
616+
539617 // The search input is outside the listbox container; query from the portal root
540- const input = within ( document . body ) . getByPlaceholderText ( 'Search...' ) ;
618+ const input = await within ( document . body ) . findByPlaceholderText ( 'Search...' ) ;
619+ expect ( input ) . toBeInTheDocument ( ) ;
620+
541621 await userEvent . click ( input ) ;
542622 await userEvent . clear ( input ) ;
543623 await userEvent . type ( input , 'California' ) ;
544624
545- expect ( within ( listbox ) . queryByRole ( 'option' , { name : 'Select "California"' } ) ) . not . toBeInTheDocument ( ) ;
625+ // Verify no creatable option appears when exact match exists
626+ const createOption = within ( listbox ) . queryByRole ( 'option' , { name : 'Select "California"' } ) ;
627+ expect ( createOption ) . not . toBeInTheDocument ( ) ;
628+
629+ // Close the dropdown
630+ await userEvent . click ( regionSelect ) ;
546631 } ) ;
547632 } ,
548633} ;
0 commit comments