Files
2024-02-15 17:01:50 +00:00

686 lines
26 KiB
TypeScript

import {useEffect} from 'react';
import {fireEvent, render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
import type {AutoCompleteProps} from 'sentry/components/autoComplete';
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: any[] = [];
const mocks = {
onSelect: jest.fn(),
onClose: jest.fn(),
onOpen: jest.fn(),
};
afterEach(() => {
jest.resetAllMocks();
autoCompleteState = [];
});
function List({registerItemCount, itemCount, ...props}) {
useEffect(() => void registerItemCount(itemCount), [itemCount, registerItemCount]);
return <ul {...props} />;
}
function Item({registerVisibleItem, item, index, ...props}) {
useEffect(() => registerVisibleItem(index, item), [registerVisibleItem, index, item]);
return <li {...props} />;
}
const createComponent = (props: Partial<AutoCompleteProps<any>>) => (
<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?: any) => {
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('only scrolls highlighted item into view on keyboard events', function () {
const scrollIntoViewMock = jest.fn();
Element.prototype.scrollIntoView = scrollIntoViewMock;
createWrapper({isOpen: true});
expect(screen.getByTestId('test-autocomplete')).toBeInTheDocument();
fireEvent.mouseEnter(screen.getByText('Pineapple'));
expect(scrollIntoViewMock).not.toHaveBeenCalled();
fireEvent.keyDown(input, {key: 'ArrowDown', charCode: 40});
expect(scrollIntoViewMock).toHaveBeenCalledTimes(1);
});
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();
});
});