import { test, expect, vi } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/react'; import Select from './Select'; const SELECT_ID = 'select-component'; const LABEL_TEXT = 'choose a component'; const OPTIONS = <> ; test('select renders correctly', () => { render( ); const select = screen.getByRole('combobox'); const selectWrapper = select.parentElement; const label = selectWrapper?.previousElementSibling; const selectArrow = select.nextElementSibling; expect(select).toHaveClass('ds_select'); expect(select.id).toEqual(SELECT_ID); expect(select).toHaveAttribute('name', SELECT_ID); expect(selectWrapper).toHaveClass('ds_select-wrapper'); expect(selectWrapper?.tagName).toEqual('DIV'); expect(label).toHaveClass('ds_label'); expect(label).toHaveAttribute('for', SELECT_ID); expect(selectArrow).toHaveClass('ds_select-arrow'); expect(selectArrow).toHaveAttribute('aria-hidden'); expect(selectArrow?.textContent).toEqual(''); }); test('select with width', () => { const SELECTWIDTH = 'fixed-10'; render( ); const selectWrapper = screen.getByRole('combobox').parentElement; expect(selectWrapper).toHaveClass(`ds_input--${SELECTWIDTH}`); }); test('select with hint text', () => { const HINT_TEXT = 'hint text'; render( ); const hintTextEl = screen.getByText(HINT_TEXT); const select = screen.getByRole('combobox'); expect(hintTextEl).toBeInTheDocument(); expect(select).toHaveAttribute('aria-describedby', hintTextEl.id); }); test('select with custom name', () => { const SELECT_NAME = 'foo'; render( ); const select = screen.getByRole('combobox'); expect(select).toHaveAttribute('name', SELECT_NAME); }); test('select with blur function', () => { const ONBLUR_FUNCTION = vi.fn(); render( ); const select = screen.getByRole('combobox'); fireEvent.blur(select); expect(ONBLUR_FUNCTION).toHaveBeenCalled(); }); test('select with change function', () => { const ONCHANGE_FUNCTION = vi.fn(); render( ); const select = screen.getByRole('combobox'); fireEvent.change(select, {target: {value: 'button'}}); expect(ONCHANGE_FUNCTION).toHaveBeenCalled(); }); test('select with onBlur that is not a function', () => { render( ); const select = screen.getByRole('combobox'); fireEvent.blur(select); // todo: assertion // success indicated by no errors thrown // error would be thrown on an untestable thread }); test('select with onChange that is not a function', () => { render( ); const select = screen.getByRole('combobox'); fireEvent.change(select, {target: {value: 'button'}}); // todo: assertion // success indicated by no errors thrown // error would be thrown on an untestable thread }); test('select with placeholder option', () => { const PLACEHOLDER_TEXT = 'foo'; render( ); const select = screen.getByRole('combobox'); const firstOption = select.childNodes[0]; expect(firstOption.textContent).toEqual(PLACEHOLDER_TEXT); expect(firstOption).toHaveAttribute('value', ''); }); test('select with initial value', () => { const INITIAL_VALUE = 'button'; render( ); const select = screen.getByRole('combobox'); const selectedOption = [].slice.call(select.childNodes).filter(childNode => childNode.selected)[0]; expect(selectedOption).toHaveAttribute('value', INITIAL_VALUE); }); test('select with error message', () => { const ERROR_MESSAGE_TEXT = 'This is a required field'; render( ); const select = screen.getByRole('combobox'); const selectWrapper = select.parentElement; const errorMessageElement = screen.getByText(ERROR_MESSAGE_TEXT); expect(selectWrapper).toHaveClass('ds_input--error') expect(select).toHaveAttribute('aria-describedby', errorMessageElement.id); expect(select).toHaveAttribute('aria-invalid', 'true'); expect(errorMessageElement).toBeInTheDocument(); expect(errorMessageElement).toHaveClass('ds_question__error-message'); }); test('passing additional props', () => { render( ); const select = screen.getByRole('combobox'); const selectWrapper = select.parentElement; expect(selectWrapper?.dataset.test).toEqual('foo'); }); test('passing additional CSS classes', () => { render( ); const select = screen.getByRole('combobox'); const selectWrapper = select.parentElement; expect(selectWrapper).toHaveClass('foo', 'ds_select-wrapper'); });