// @vitest-environment jsdom import { cleanup, fireEvent, render, screen } from '@testing-library/react'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { CustomSelect } from '../../src/components/CustomSelect'; afterEach(() => cleanup()); describe('CustomSelect', () => { it('renders the selected label and chooses an option from the portal menu', () => { const onChange = vi.fn(); render( , ); const trigger = screen.getByRole('combobox', { name: 'Model: GPT Image 2' }); expect(trigger.getAttribute('aria-expanded')).toBe('false'); fireEvent.click(trigger); expect(trigger.getAttribute('aria-expanded')).toBe('true'); fireEvent.click(screen.getByRole('option', { name: /Seedance/ })); expect(onChange).toHaveBeenCalledWith('seedance'); }); it('skips disabled options and supports keyboard selection', () => { const onChange = vi.fn(); render( , ); const trigger = screen.getByRole('combobox', { name: 'Provider: OpenAI' }); fireEvent.keyDown(trigger, { key: 'ArrowDown' }); fireEvent.keyDown(trigger, { key: 'ArrowDown' }); expect(trigger.getAttribute('aria-activedescendant')).toBe( screen.getByRole('option', { name: /Custom/ }).id, ); expect(trigger.getAttribute('aria-activedescendant')).not.toBe( screen.getByRole('option', { name: /Disabled/ }).id, ); fireEvent.keyDown(trigger, { key: 'Enter' }); expect(onChange).toHaveBeenCalledWith('custom'); expect(onChange).not.toHaveBeenCalledWith('disabled'); }); it('keeps keyboard navigation active state across parent rerenders with fresh options', () => { const onChange = vi.fn(); const options = () => [ { value: 'first', label: 'First' }, { value: 'second', label: 'Second' }, { value: 'third', label: 'Third' }, ]; const { rerender } = render( , ); const trigger = screen.getByRole('combobox', { name: 'Template: First' }); fireEvent.keyDown(trigger, { key: 'ArrowDown' }); fireEvent.keyDown(trigger, { key: 'ArrowDown' }); expect(trigger.getAttribute('aria-activedescendant')).toBe( screen.getByRole('option', { name: /Second/ }).id, ); rerender( , ); const rerenderedTrigger = screen.getByRole('combobox', { name: 'Template: First' }); expect(rerenderedTrigger.getAttribute('aria-activedescendant')).toBe( screen.getByRole('option', { name: /Second/ }).id, ); }); });