import { flushPromises, mount } from '@vue/test-utils' import { describe, expect, it } from 'vitest' import SearchableSelect from '../../components/SearchableSelect.vue' const options = [ { value: 'alpha', label: 'Alpha', description: 'First option' }, { value: 'beta', label: 'Beta', disabled: true, disabledReason: 'Unavailable' }, { value: 'gamma', label: 'Gamma', meta: 'count' }, ] describe('SearchableSelect', () => { it('filters rich options and explains disabled choices', async () => { const wrapper = mount(SearchableSelect, { props: { options } }) await wrapper.get('.mint-searchable-select__trigger').trigger('click') await wrapper.get('input').setValue('bet') expect(wrapper.findAll('[role="option"]')).toHaveLength(1) expect(wrapper.get('[role="option"]').text()).toContain('Unavailable') expect(wrapper.get('[role="option"]').attributes('aria-disabled')).toBe('true') }) it('skips disabled options during keyboard selection', async () => { const wrapper = mount(SearchableSelect, { props: { options } }) await wrapper.get('.mint-searchable-select__trigger').trigger('click') await flushPromises() await wrapper.get('input').trigger('keydown', { key: 'ArrowDown' }) await wrapper.get('input').trigger('keydown', { key: 'Enter' }) expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['gamma']) expect(wrapper.get('.mint-searchable-select__trigger').text()).toContain('Select an option') }) it('keeps footer actions reachable until focus leaves the select', async () => { const wrapper = mount(SearchableSelect, { attachTo: document.body, props: { options }, slots: { footer: '' }, }) const outside = document.createElement('button') document.body.append(outside) try { await wrapper.get('.mint-searchable-select__trigger').trigger('click') await wrapper.get('input').trigger('keydown', { key: 'Tab' }) expect(wrapper.find('.mint-searchable-select__footer').exists()).toBe(true) const footer = wrapper.get('.mint-searchable-select__footer button') footer.element.focus() await flushPromises() expect(document.activeElement).toBe(footer.element) expect(wrapper.find('[role="listbox"]').exists()).toBe(true) outside.focus() await flushPromises() expect(wrapper.find('[role="listbox"]').exists()).toBe(false) } finally { wrapper.unmount() outside.remove() } }) it('should render the panel on the shared popover surface when opened', async () => { const wrapper = mount(SearchableSelect, { props: { options } }) await wrapper.get('.mint-searchable-select__trigger').trigger('click') expect(wrapper.get('.mint-searchable-select__panel').classes()).toContain('mint-popover') }) it('should mark the selected option as a selected menu item when opened', async () => { const wrapper = mount(SearchableSelect, { props: { options, modelValue: 'alpha' } }) await wrapper.get('.mint-searchable-select__trigger').trigger('click') expect(wrapper.findAll('[role="option"]')[0].classes()).toContain('mint-menu-item--selected') }) it('should reserve the check column on unselected options when opened', async () => { const wrapper = mount(SearchableSelect, { props: { options, modelValue: 'alpha' } }) await wrapper.get('.mint-searchable-select__trigger').trigger('click') expect(wrapper.findAll('[role="option"]')[2].find('.mint-menu-item__check').exists()).toBe(true) }) })