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');
});