import { test, expect, vi } from 'vitest';
import { render, screen, within } from '@testing-library/react';
import SiteSearch from './SiteSearch';
const SITE_SEARCH_ID = 'site-search';
const LABEL_TEXT = 'Search';
const PLACEHOLDER_TEXT = 'Search';
test('site search renders correctly', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchFormContainer = searchForm.parentElement;
const searchLabel = document.querySelector('label');
const searchInput = within(searchForm).getByRole('searchbox');
const inputWrapper = searchInput.parentElement;
const searchButton = within(searchForm).getByRole('button');
expect(searchFormContainer).toHaveClass('ds_site-search');
expect(searchFormContainer?.tagName).toEqual('DIV');
expect(searchFormContainer).not.toHaveAttribute('id', 'site-search-autocomplete');
expect(searchForm).toHaveClass('ds_site-search__form');
expect(searchForm).toHaveAttribute('method', 'GET');
expect(searchForm).toHaveAttribute('action', '/search');
expect(searchLabel?.textContent).toEqual(LABEL_TEXT);
expect(searchLabel).toHaveAttribute('for', SITE_SEARCH_ID);
expect(searchLabel).toHaveAttribute('id', `${SITE_SEARCH_ID}-label`);
expect(searchLabel).toHaveClass('ds_label', 'visually-hidden');
expect(inputWrapper).toHaveClass('ds_input__wrapper ds_input__wrapper--has-icon');
expect(inputWrapper?.tagName).toEqual('DIV');
expect(searchInput).toHaveClass('ds_input', 'ds_site-search__input');
expect(searchInput).toHaveAttribute('id', SITE_SEARCH_ID);
expect(searchInput).toHaveAttribute('placeholder', PLACEHOLDER_TEXT);
expect(searchInput).toHaveAttribute('required');
expect(searchInput).toHaveAttribute('spellcheck', 'false');
expect(searchInput).toHaveAttribute('type', 'search');
expect(searchInput).toHaveAttribute('name', 'q');
expect(searchInput).not.toHaveAttribute('autocomplete');
expect(searchButton).toHaveClass('ds_button');
expect(searchButton).toHaveAttribute('type', 'submit');
expect(searchButton.textContent).toEqual('Search');
});
test('custom action', () => {
render(
);
const searchForm = screen.getByRole('search');
expect(searchForm).toHaveAttribute('action', '/foo');
});
test('custom id', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchInput = within(searchForm).getByRole('searchbox');
expect(searchInput).toHaveAttribute('id', 'foo');
});
test('custom method', () => {
render(
);
const searchForm = screen.getByRole('search');
expect(searchForm).toHaveAttribute('method', 'POST');
});
test('custom name', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchInput = within(searchForm).getByRole('searchbox');
expect(searchInput).toHaveAttribute('name', 'foo');
});
test('custom placeholder', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchInput = within(searchForm).getByRole('searchbox');
expect(searchInput).toHaveAttribute('placeholder', 'foo');
});
test('autocomplete', () => {
const AUTOCOMPLETE_SUGGESTION_MAPPING_FUNCTION = vi.fn();
const SUGGESTIONS_ID = 'autocomplete-suggestions';
render(
)
const searchForm = screen.getByRole('search');
const searchFormContainer = searchForm.parentElement;
const searchInput = within(searchForm).getByRole('searchbox');
const autocompleteStatus = within(searchForm).getByRole('status');
const suggestionsContainer = document.querySelector('.ds_autocomplete__suggestions');
const suggestionsList = within(searchForm).getByRole('listbox');
expect(searchFormContainer).toHaveClass('ds_autocomplete');
expect(searchFormContainer).toHaveAttribute('id', `${SITE_SEARCH_ID}-autocomplete`);
expect(autocompleteStatus).toBeInTheDocument();
expect(autocompleteStatus).toHaveClass('visually-hidden');
expect(autocompleteStatus).toHaveAttribute('aria-live', 'polite');
expect(autocompleteStatus).toHaveAttribute('id', 'autocomplete-status');
expect(autocompleteStatus.tagName).toEqual('DIV');
expect(searchInput).toHaveAttribute('aria-autocomplete', 'list');
expect(searchInput).toHaveAttribute('aria-owns', SUGGESTIONS_ID);
expect(searchInput).toHaveAttribute('autocomplete', 'off');
expect(searchInput).toHaveClass('js-autocomplete-input');
expect(suggestionsContainer).toHaveAttribute('id', SUGGESTIONS_ID);
expect(suggestionsContainer?.tagName).toEqual('DIV');
expect(suggestionsList).toHaveClass('ds_autocomplete__suggestions-list');
expect(suggestionsList).toHaveAttribute('aria-labelledby', `${SITE_SEARCH_ID}-label`);
expect(suggestionsList.tagName).toEqual('OL');
});
test('instantiating/initialising DS component script: autocomplete', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchFormContainer = searchForm.parentElement;
expect(searchFormContainer).toHaveClass('js-initialised');
expect(searchFormContainer).toHaveClass('js-instantiated');
});
test('instantiating/initialising DS component script: no autocomplete', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchFormContainer = searchForm.parentElement;
expect(searchFormContainer).not.toHaveClass('js-initialised');
expect(searchFormContainer).not.toHaveClass('js-instantiated');
});
test('passing additional props', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchFormContainer = searchForm.parentElement;
expect(searchFormContainer?.dataset.test).toEqual('foo');
});
test('passing additional CSS classes', () => {
render(
);
const searchForm = screen.getByRole('search');
const searchFormContainer = searchForm.parentElement;
expect(searchFormContainer).toHaveClass('foo', 'ds_site-search');
});