-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-utils.ts
More file actions
49 lines (41 loc) · 1.87 KB
/
test-utils.ts
File metadata and controls
49 lines (41 loc) · 1.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { userEvent, within, screen, waitFor } from '@storybook/test';
/**
* A robust helper to select an option from a Radix-based Select/Combobox.
* Handles portals, animations, and pointer-event blockers.
*/
export async function selectRadixOption(
canvasElement: HTMLElement,
options: {
triggerRole?: 'combobox' | 'button';
triggerName: string | RegExp;
optionName: string | RegExp;
optionTestId?: string;
},
) {
const canvas = within(canvasElement);
const { triggerRole = 'combobox', triggerName, optionName, optionTestId } = options;
// 1. Find and click the trigger within the component canvas
const trigger = await canvas.findByRole(triggerRole, { name: triggerName });
if (!trigger) throw new Error(`Trigger with role ${triggerRole} and name ${triggerName} not found`);
await userEvent.click(trigger);
// 2. Wait for the listbox to appear in the document body (Portal)
// We use a slightly longer timeout for CI stability.
const listbox = await screen.findByRole('listbox', {}, { timeout: 3000 });
if (!listbox) throw new Error('Radix listbox (portal) not found after clicking trigger');
// 3. Find the option specifically WITHIN the listbox
let option: HTMLElement | null = null;
if (optionTestId) {
option = await within(listbox).findByTestId(optionTestId);
} else {
option = await within(listbox).findByRole('option', { name: optionName });
}
if (!option) throw new Error(`Option ${optionName || optionTestId} not found in listbox`);
// 4. Click the option
// pointerEventsCheck: 0 is used to bypass Radix's temporary pointer-event locks during animations
await userEvent.click(option, { pointerEventsCheck: 0 });
// 5. Verify the dropdown closed (optional but ensures stability)
await waitFor(() => {
const listbox = screen.queryByRole('listbox');
if (listbox) throw new Error('Listbox still visible');
});
}