Skip to content

Commit d24d4e6

Browse files
committed
Fix: streamline listbox interactions in select stories for improved test reliability
Refactored select stories to remove redundant error handling and fallback mechanisms, ensuring a more straightforward approach to listbox interactions. This change enhances the clarity of the tests and maintains reliability by ensuring that dropdowns are fully rendered before interaction, reducing flakiness across various scenarios.
1 parent e173cef commit d24d4e6

File tree

1 file changed

+64
-143
lines changed

1 file changed

+64
-143
lines changed

apps/docs/src/remix-hook-form/select.stories.tsx

Lines changed: 64 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -298,21 +298,14 @@ export const USStateSelection: Story = {
298298
const stateSelect = canvas.getByLabelText('US State');
299299
await userEvent.click(stateSelect);
300300

301-
try {
302-
// Wait for the dropdown to open and find the listbox with timeout
303-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
304-
expect(listbox).toBeInTheDocument();
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();
305304

306-
// Find and click the California option
307-
const californiaOption = within(listbox).getByRole('option', { name: 'California' });
308-
expect(californiaOption).toBeInTheDocument();
309-
await userEvent.click(californiaOption);
310-
} catch (error) {
311-
// Fallback: try clicking the option directly if listbox approach fails
312-
console.warn('Listbox approach failed, trying direct option selection', error);
313-
const californiaOption = canvas.getByRole('option', { name: 'California' });
314-
await userEvent.click(californiaOption);
315-
}
305+
// Find and click the California option
306+
const californiaOption = within(listbox).getByRole('option', { name: 'California' });
307+
expect(californiaOption).toBeInTheDocument();
308+
await userEvent.click(californiaOption);
316309

317310
// Wait for the trigger text to update after portal selection
318311
await expect(canvas.findByRole('combobox', { name: 'US State' })).resolves.toHaveTextContent('California');
@@ -340,21 +333,14 @@ export const CanadaProvinceSelection: Story = {
340333
const provinceSelect = canvas.getByLabelText('Canadian Province');
341334
await userEvent.click(provinceSelect);
342335

343-
try {
344-
// Wait for the dropdown to open and find the listbox with timeout
345-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
346-
expect(listbox).toBeInTheDocument();
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();
347339

348-
// Find and click the Ontario option
349-
const ontarioOption = within(listbox).getByRole('option', { name: 'Ontario' });
350-
expect(ontarioOption).toBeInTheDocument();
351-
await userEvent.click(ontarioOption);
352-
} catch (error) {
353-
// Fallback: try clicking the option directly if listbox approach fails
354-
console.warn('Listbox approach failed, trying direct option selection', error);
355-
const ontarioOption = canvas.getByRole('option', { name: 'Ontario' });
356-
await userEvent.click(ontarioOption);
357-
}
340+
// Find and click the Ontario option
341+
const ontarioOption = within(listbox).getByRole('option', { name: 'Ontario' });
342+
expect(ontarioOption).toBeInTheDocument();
343+
await userEvent.click(ontarioOption);
358344

359345
// Wait for the trigger text to update after portal selection
360346
await expect(canvas.findByRole('combobox', { name: 'Canadian Province' })).resolves.toHaveTextContent('Ontario');
@@ -382,52 +368,31 @@ export const FormSubmission: Story = {
382368
const stateSelect = canvas.getByLabelText('US State');
383369
await userEvent.click(stateSelect);
384370

385-
try {
386-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
387-
expect(listbox).toBeInTheDocument();
388-
const californiaOption = within(listbox).getByRole('option', { name: 'California' });
389-
expect(californiaOption).toBeInTheDocument();
390-
await userEvent.click(californiaOption);
391-
} catch (error) {
392-
// Fallback: try clicking the option directly if listbox approach fails
393-
console.warn('Listbox approach failed, trying direct option selection', error);
394-
const californiaOption = canvas.getByRole('option', { name: 'California' });
395-
await userEvent.click(californiaOption);
396-
}
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);
397376

398377
// Select a province
399378
const provinceSelect = canvas.getByLabelText('Canadian Province');
400379
await userEvent.click(provinceSelect);
401380

402-
try {
403-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
404-
expect(listbox).toBeInTheDocument();
405-
const ontarioOption = within(listbox).getByRole('option', { name: 'Ontario' });
406-
expect(ontarioOption).toBeInTheDocument();
407-
await userEvent.click(ontarioOption);
408-
} catch (error) {
409-
// Fallback: try clicking the option directly if listbox approach fails
410-
console.warn('Listbox approach failed, trying direct option selection', error);
411-
const ontarioOption = canvas.getByRole('option', { name: 'Ontario' });
412-
await userEvent.click(ontarioOption);
413-
}
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);
414386

415387
// Select a custom region
416388
const regionSelect = canvas.getByLabelText('Custom Region');
417389
await userEvent.click(regionSelect);
418390

419-
try {
420-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
421-
expect(listbox).toBeInTheDocument();
422-
const customOption = within(listbox).getByRole('option', { name: 'California' });
423-
expect(customOption).toBeInTheDocument();
424-
await userEvent.click(customOption);
425-
} catch (error) {
426-
// Fallback: try clicking the option directly if listbox approach fails
427-
console.warn('Listbox approach failed, trying direct option selection', error);
428-
const customOption = canvas.getByRole('option', { name: 'California' });
429-
await userEvent.click(customOption);
430-
}
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);
431396
});
432397

433398
await step('Submit the form', async () => {
@@ -488,18 +453,13 @@ export const SearchDisabled: Story = {
488453
const regionSelect = canvas.getByLabelText('Custom Region');
489454
await userEvent.click(regionSelect);
490455

491-
try {
492-
// Wait for the dropdown to open
493-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
494-
expect(listbox).toBeInTheDocument();
456+
// Wait for the dropdown to open
457+
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
458+
expect(listbox).toBeInTheDocument();
495459

496-
// Verify no search input is present when searchable is disabled
497-
const searchInput = within(listbox).queryByPlaceholderText('Search...');
498-
expect(searchInput).not.toBeInTheDocument();
499-
} catch (error) {
500-
// If listbox approach fails, that's okay - we're testing search disabled
501-
console.warn('Listbox approach failed for search disabled test', error);
502-
}
460+
// Verify no search input is present when searchable is disabled
461+
const searchInput = within(listbox).queryByPlaceholderText('Search...');
462+
expect(searchInput).not.toBeInTheDocument();
503463
});
504464
},
505465
};
@@ -549,16 +509,9 @@ export const CustomSearchPlaceholder: Story = {
549509
const regionSelect = canvas.getByLabelText('Custom Region');
550510
await userEvent.click(regionSelect);
551511

552-
try {
553-
// The search input is rendered alongside the listbox in the portal, not inside the listbox itself.
554-
const searchInput = await within(document.body).findByPlaceholderText('Type to filter…', {}, { timeout: 5000 });
555-
expect(searchInput).toBeInTheDocument();
556-
} catch (error) {
557-
// Fallback: try to find the search input within the canvas
558-
console.warn('Portal search input approach failed, trying canvas search', error);
559-
const searchInput = canvas.getByPlaceholderText('Type to filter…');
560-
expect(searchInput).toBeInTheDocument();
561-
}
512+
// The search input is rendered alongside the listbox in the portal, not inside the listbox itself.
513+
const searchInput = await within(document.body).findByPlaceholderText('Type to filter…', {}, { timeout: 5000 });
514+
expect(searchInput).toBeInTheDocument();
562515
});
563516
},
564517
};
@@ -611,6 +564,7 @@ export const CreatableOption: Story = {
611564

612565
await step('Create new option when no exact match', async () => {
613566
// Wait for the component to fully load - check for loading screen absence
567+
// This prevents the "sb-loader" (loading screen) from interfering with interactions
614568
await canvas.findByLabelText('Custom Region');
615569

616570
// Additional wait to ensure the component is fully interactive
@@ -619,41 +573,23 @@ export const CreatableOption: Story = {
619573
const regionSelect = canvas.getByLabelText('Custom Region');
620574
await userEvent.click(regionSelect);
621575

622-
try {
623-
// Wait for the dropdown to open and find the listbox with more specific timeout and error handling
624-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
625-
626-
// Verify the listbox is properly rendered
627-
expect(listbox).toBeInTheDocument();
628-
expect(listbox).toHaveAttribute('role', 'listbox');
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();
629579

630-
// The search input is outside the listbox container; query from the portal root
631-
const input = await within(document.body).findByPlaceholderText('Search...');
632-
expect(input).toBeInTheDocument();
580+
// The search input is outside the listbox container; query from the portal root
581+
const input = await within(document.body).findByPlaceholderText('Search...');
582+
expect(input).toBeInTheDocument();
633583

634-
await userEvent.click(input);
635-
await userEvent.clear(input);
636-
await userEvent.type(input, 'Atlantis');
584+
await userEvent.click(input);
585+
await userEvent.clear(input);
586+
await userEvent.type(input, 'Atlantis');
637587

638-
// Wait for the creatable option to appear
639-
const createItem = await within(listbox).findByRole('option', { name: 'Select "Atlantis"' }, { timeout: 2000 });
640-
expect(createItem).toBeInTheDocument();
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();
641591

642-
await userEvent.click(createItem);
643-
} catch (error) {
644-
// Fallback: try to find and interact with elements within the canvas
645-
console.warn('Portal approach failed, trying canvas-based interaction', error);
646-
647-
// Try to find and type in the search input within the canvas
648-
const input = canvas.getByPlaceholderText('Search...');
649-
await userEvent.click(input);
650-
await userEvent.clear(input);
651-
await userEvent.type(input, 'Atlantis');
652-
653-
// Try to find and click the create option
654-
const createItem = canvas.getByRole('option', { name: 'Select "Atlantis"' });
655-
await userEvent.click(createItem);
656-
}
592+
await userEvent.click(createItem);
657593

658594
// Verify the selection was applied
659595
await expect(canvas.findByRole('combobox', { name: 'Custom Region' })).resolves.toHaveTextContent('Atlantis');
@@ -674,36 +610,21 @@ export const CreatableOption: Story = {
674610
const regionSelect = canvas.getByLabelText('Custom Region');
675611
await userEvent.click(regionSelect);
676612

677-
try {
678-
// Wait for the dropdown to open and find the listbox
679-
const listbox = await within(document.body).findByRole('listbox', {}, { timeout: 5000 });
680-
expect(listbox).toBeInTheDocument();
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();
681616

682-
// The search input is outside the listbox container; query from the portal root
683-
const input = await within(document.body).findByPlaceholderText('Search...');
684-
expect(input).toBeInTheDocument();
617+
// The search input is outside the listbox container; query from the portal root
618+
const input = await within(document.body).findByPlaceholderText('Search...');
619+
expect(input).toBeInTheDocument();
685620

686-
await userEvent.click(input);
687-
await userEvent.clear(input);
688-
await userEvent.type(input, 'California');
621+
await userEvent.click(input);
622+
await userEvent.clear(input);
623+
await userEvent.type(input, 'California');
689624

690-
// Verify no creatable option appears when exact match exists
691-
const createOption = within(listbox).queryByRole('option', { name: 'Select "California"' });
692-
expect(createOption).not.toBeInTheDocument();
693-
} catch (error) {
694-
// Fallback: try canvas-based approach
695-
console.warn('Portal approach failed for exact match test', error);
696-
697-
// Try to find and type in the search input within the canvas
698-
const input = canvas.getByPlaceholderText('Search...');
699-
await userEvent.click(input);
700-
await userEvent.clear(input);
701-
await userEvent.type(input, 'California');
702-
703-
// Verify no creatable option appears when exact match exists
704-
const createOption = canvas.queryByRole('option', { name: 'Select "California"' });
705-
expect(createOption).not.toBeInTheDocument();
706-
}
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();
707628

708629
// Close the dropdown
709630
await userEvent.click(regionSelect);

0 commit comments

Comments
 (0)