123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670 |
- import {useEffect} from 'react';
- import {fireEvent, render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
- import AutoComplete from 'sentry/components/autoComplete';
- const items = [
- {
- name: 'Apple',
- },
- {
- name: 'Pineapple',
- },
- {
- name: 'Orange',
- },
- ];
- /**
- * For every render, we push all injected params into `autoCompleteState`, we probably want to
- * assert against those instead of the wrapper's state since component state will be different if we have
- * "controlled" props where <AutoComplete> does not handle state
- */
- describe('AutoComplete', function () {
- let input;
- let autoCompleteState = [];
- const mocks = {
- onSelect: jest.fn(),
- onClose: jest.fn(),
- onOpen: jest.fn(),
- };
- afterEach(() => {
- jest.resetAllMocks();
- autoCompleteState = [];
- });
- const List = ({registerItemCount, itemCount, ...props}) => {
- useEffect(() => void registerItemCount(itemCount), [itemCount, registerItemCount]);
- return <ul {...props} />;
- };
- const Item = ({registerVisibleItem, item, index, ...props}) => {
- useEffect(() => registerVisibleItem(index, item), [registerVisibleItem, index, item]);
- return <li {...props} />;
- };
- const createComponent = props => (
- <AutoComplete {...mocks} itemToString={item => item.name} {...props}>
- {injectedProps => {
- const {
- getRootProps,
- getInputProps,
- getMenuProps,
- getItemProps,
- inputValue,
- isOpen,
- registerItemCount,
- registerVisibleItem,
- highlightedIndex,
- } = injectedProps;
- // This is purely for testing
- autoCompleteState.push(injectedProps);
- const filteredItems = items.filter(item =>
- item.name.toLowerCase().includes(inputValue.toLowerCase())
- );
- return (
- <div {...getRootProps()}>
- <input placeholder="autocomplete" {...getInputProps()} />
- {isOpen && (
- <div {...getMenuProps()} data-test-id="test-autocomplete">
- <List
- registerItemCount={registerItemCount}
- itemCount={filteredItems.length}
- >
- {filteredItems.map((item, index) => (
- <Item
- key={item.name}
- registerVisibleItem={registerVisibleItem}
- index={index}
- item={item}
- aria-selected={highlightedIndex === index}
- {...getItemProps({item, index})}
- >
- {item.name}
- </Item>
- ))}
- </List>
- </div>
- )}
- </div>
- );
- }}
- </AutoComplete>
- );
- const createWrapper = props => {
- const wrapper = render(createComponent(props));
- input = screen.getByPlaceholderText('autocomplete');
- return wrapper;
- };
- describe('Uncontrolled', function () {
- it('shows dropdown menu when input has focus', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- for (const item of items) {
- expect(screen.getByText(item.name)).toBeInTheDocument();
- }
- });
- it('only tries to close once if input is blurred and click outside occurs', async function () {
- createWrapper();
- jest.useFakeTimers();
- fireEvent.focus(input);
- fireEvent.blur(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- // Click outside dropdown
- fireEvent.click(document.body);
- jest.runAllTimers();
- await waitFor(() => expect(mocks.onClose).toHaveBeenCalledTimes(1));
- });
- it('only calls onClose dropdown menu when input is blurred', function () {
- createWrapper();
- jest.useFakeTimers();
- fireEvent.focus(input);
- fireEvent.blur(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- jest.runAllTimers();
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('can close dropdown menu when Escape is pressed', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'Escape', charCode: 27});
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- });
- it('can open and close dropdown menu using injected actions', function () {
- createWrapper();
- const [injectedProps] = autoCompleteState;
- injectedProps.actions.open();
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(mocks.onOpen).toHaveBeenCalledTimes(1);
- injectedProps.actions.close();
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('reopens dropdown menu after Escape is pressed and input is changed', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'Escape', charCode: 27});
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- fireEvent.change(input, {target: {value: 'a', charCode: 65}});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getAllByRole('option')).toHaveLength(3);
- });
- it('reopens dropdown menu after item is selected and then input is changed', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.change(input, {target: {value: 'eapp'}});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByRole('option')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- fireEvent.change(input, {target: {value: 'app'}});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getAllByRole('option')).toHaveLength(2);
- });
- it('selects dropdown item by clicking and sets input to selected value', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.click(screen.getByText(items[1].name));
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({inputValue: '', highlightedIndex: 0}),
- expect.anything()
- );
- expect(input).toHaveValue('Pineapple');
- expect(screen.queryByRole('option')).not.toBeInTheDocument();
- });
- it('can navigate dropdown items with keyboard and select with "Enter" keypress', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[2],
- expect.objectContaining({inputValue: '', highlightedIndex: 2}),
- expect.anything()
- );
- expect(screen.queryByRole('option')).not.toBeInTheDocument();
- expect(input).toHaveValue('Orange');
- });
- it('respects list bounds when navigating filtered items with arrow keys', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(3);
- });
- it('can filter items and then navigate with keyboard', function () {
- createWrapper();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.keyDown(input, {target: {value: 'a', charCode: 65}});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(input).toHaveValue('a');
- // Apple, pineapple, orange
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.change(input, {target: {value: 'ap'}});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(input).toHaveValue('ap');
- expect(autoCompleteState[autoCompleteState.length - 1].inputValue).toBe('ap');
- // Apple, pineapple
- expect(screen.getAllByRole('option')).toHaveLength(2);
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(2);
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({inputValue: 'ap', highlightedIndex: 1}),
- expect.anything()
- );
- expect(screen.queryByRole('option')).not.toBeInTheDocument();
- expect(input).toHaveValue('Pineapple');
- });
- it('can reset input when menu closes', function () {
- const wrapper = createWrapper();
- jest.useFakeTimers();
- wrapper.rerender(createComponent({resetInputOnClose: true}));
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {target: {value: 'a', charCode: 65}});
- expect(input).toHaveValue('a');
- fireEvent.blur(input);
- jest.runAllTimers();
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- expect(input).toHaveValue('');
- });
- });
- describe('isOpen controlled', function () {
- it('has dropdown menu initially open', function () {
- createWrapper({isOpen: true});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getAllByRole('option')).toHaveLength(3);
- });
- it('closes when props change', function () {
- const wrapper = createWrapper({isOpen: true});
- wrapper.rerender(createComponent({isOpen: false}));
- // Menu should be closed
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- expect(screen.queryByRole('option')).not.toBeInTheDocument();
- });
- it('remains closed when input is focused, but calls `onOpen`', function () {
- createWrapper({isOpen: false});
- jest.useFakeTimers();
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- fireEvent.focus(input);
- jest.runAllTimers();
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- expect(screen.queryByRole('option')).not.toBeInTheDocument();
- expect(mocks.onOpen).toHaveBeenCalledTimes(1);
- });
- it('remains open when input focus/blur events occur, but calls `onClose`', function () {
- createWrapper({isOpen: true});
- jest.useFakeTimers();
- fireEvent.focus(input);
- fireEvent.blur(input);
- jest.runAllTimers();
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- // This still gets called even though menu is open
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('calls onClose when Escape is pressed', function () {
- createWrapper({isOpen: true});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'Escape', charCode: 27});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('does not open and close dropdown menu using injected actions', function () {
- createWrapper({isOpen: true});
- const [injectedProps] = autoCompleteState;
- injectedProps.actions.open();
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(mocks.onOpen).toHaveBeenCalledTimes(1);
- injectedProps.actions.close();
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('onClose is called after item is selected', function () {
- createWrapper({isOpen: true});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.change(input, {target: {value: 'eapp'}});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByRole('option')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('selects dropdown item by clicking and sets input to selected value', function () {
- createWrapper({isOpen: true});
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.click(screen.getByText(items[1].name));
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({inputValue: '', highlightedIndex: 0}),
- expect.anything()
- );
- expect(input).toHaveValue('Pineapple');
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- });
- it('can navigate dropdown items with keyboard and select with "Enter" keypress', function () {
- createWrapper({isOpen: true});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[2],
- expect.objectContaining({inputValue: '', highlightedIndex: 2}),
- expect.anything()
- );
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- expect(input).toHaveValue('Orange');
- });
- it('respects list bounds when navigating filtered items with arrow keys', function () {
- createWrapper({isOpen: true});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowUp', charCode: 38});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(3);
- });
- it('can filter items and then navigate with keyboard', function () {
- createWrapper({isOpen: true});
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.keyDown(input, {target: {value: 'a', charCode: 65}});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(input).toHaveValue('a');
- // Apple, pineapple, orange
- expect(screen.getAllByRole('option')).toHaveLength(3);
- fireEvent.change(input, {target: {value: 'ap'}});
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(input).toHaveValue('ap');
- expect(autoCompleteState[autoCompleteState.length - 1].inputValue).toBe('ap');
- // Apple, pineapple
- expect(screen.getAllByRole('option')).toHaveLength(2);
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(2);
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({inputValue: 'ap', highlightedIndex: 1}),
- expect.anything()
- );
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- expect(input).toHaveValue('Pineapple');
- });
- it('can reset input value when menu closes', function () {
- const wrapper = createWrapper({isOpen: true});
- jest.useFakeTimers();
- wrapper.rerender(createComponent({resetInputOnClose: true}));
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {target: {value: 'a', charCode: 65}});
- expect(input).toHaveValue('a');
- fireEvent.blur(input);
- jest.runAllTimers();
- expect(input).toHaveValue('');
- });
- });
- describe('inputValue controlled', () => {
- it('follows the inputValue prop', () => {
- const wrapper = createWrapper({inputValue: 'initial value'});
- expect(input).toHaveValue('initial value');
- wrapper.rerender(createComponent({inputValue: 'new value'}));
- expect(input).toHaveValue('new value');
- });
- it('calls onInputValueChange on input', () => {
- const wrapper = createWrapper({inputValue: 'initial value'});
- const onInputValueChange = jest.fn();
- wrapper.rerender(createComponent({onInputValueChange}));
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.change(input, {target: {value: 'a'}});
- expect(onInputValueChange).toHaveBeenCalledWith('a');
- });
- it('input value does not change when typed into', () => {
- createWrapper({inputValue: 'initial value'});
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.change(input, {target: {value: 'a'}});
- expect(input).toHaveValue('initial value');
- });
- it('input value does not change when blurred', () => {
- createWrapper({inputValue: 'initial value'});
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.blur(input);
- expect(input).toHaveValue('initial value');
- });
- it('can search for and select an item without changing the input value', () => {
- const wrapper = createWrapper({inputValue: 'initial value'});
- fireEvent.focus(input);
- wrapper.rerender(createComponent({inputValue: 'apple'}));
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getAllByRole('option')).toHaveLength(2);
- fireEvent.click(screen.getByText('Apple'));
- expect(screen.queryByTestId('test-autocomplete')).not.toBeInTheDocument();
- expect(input).toHaveValue('apple');
- expect(mocks.onSelect).toHaveBeenCalledWith(
- {name: 'Apple'},
- expect.anything(),
- expect.anything()
- );
- });
- it('can filter and navigate dropdown items with keyboard and select with "Enter" keypress without changing input value', function () {
- const wrapper = createWrapper({inputValue: 'initial value'});
- wrapper.rerender(createComponent({inputValue: 'apple'}));
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- expect(screen.getByText('Apple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getAllByRole('option')).toHaveLength(2);
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({highlightedIndex: 1}),
- expect.anything()
- );
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- expect(input).toHaveValue('apple');
- });
- });
- it('selects using enter key', function () {
- const wrapper = createWrapper({isOpen: true, shouldSelectWithEnter: false});
- fireEvent.change(input, {target: {value: 'pine'}});
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).not.toHaveBeenCalled();
- wrapper.unmount();
- createWrapper({isOpen: true, shouldSelectWithEnter: true});
- fireEvent.change(input, {target: {value: 'pine'}});
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({inputValue: 'pine', highlightedIndex: 0}),
- expect.anything()
- );
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- expect(input).toHaveValue('Pineapple');
- });
- it('selects using tab key', function () {
- let wrapper = createWrapper({isOpen: true, shouldSelectWithTab: false});
- fireEvent.change(input, {target: {value: 'pine'}});
- fireEvent.keyDown(input, {key: 'Tab', charCode: 9});
- expect(mocks.onSelect).not.toHaveBeenCalled();
- wrapper.unmount();
- wrapper = createWrapper({isOpen: true, shouldSelectWithTab: true});
- fireEvent.change(input, {target: {value: 'pine'}});
- fireEvent.keyDown(input, {key: 'Tab'});
- expect(mocks.onSelect).toHaveBeenCalledWith(
- items[1],
- expect.objectContaining({inputValue: 'pine', highlightedIndex: 0}),
- expect.anything()
- );
- expect(mocks.onClose).toHaveBeenCalledTimes(1);
- expect(input).toHaveValue('Pineapple');
- });
- it('does not reset highlight state if `closeOnSelect` is false and we select a new item', function () {
- createWrapper({closeOnSelect: false});
- jest.useFakeTimers();
- fireEvent.focus(input);
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- // Select item
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- // Should still remain open with same highlightedIndex
- expect(screen.getByText('Pineapple')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- // Select item
- fireEvent.keyDown(input, {key: 'Enter', charCode: 13});
- // Should still remain open with same highlightedIndex
- expect(screen.getByText('Orange')).toHaveAttribute('aria-selected', 'true');
- expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
- });
- });
|