When attempting to execute the test, the following error message is displayed:
● Search Bar › Displays when search phrase is matching
Unable to find an element with the text: /element/. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher
to make your matcher more flexible.
Ignored nodes: comments, script, style
<body>
<div />
<div
aria-live="polite"
aria-relevant="additions text"
id="a11y-status-message"
role="status"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;"
/>
</body>
22 | const input = screen.getByPlaceholderText('Search');
23 | fireEvent.change(input, { target: { value: 'el' } });
> 24 | await screen.findByText(/element/);
| ^
25 | });
26 | });
27 |
at waitForWrapper (node_modules/@testing-library/dom/dist/wait-for.js:163:27)
at findByText (node_modules/@testing-library/dom/dist/query-helpers.js:86:33)
at Object.<anonymous> (src/components/organisms/SearchBar/SearchBar.test.js:24:18)
Test Suites: 1 failed, 2 passed, 3 total
Tests: 1 failed, 4 passed, 5 total
Snapshots: 0 total
Time: 2.833 s, estimated 3 s
Ran all test suites related to changed files.
Here is the test:
it('Displays when search phrase is matching', async () => {
render(<SearchBar />);
const input = screen.getByPlaceholderText('Search');
fireEvent.change(input, { target: { value: 'el' } });
await screen.findByText(/element/);
});
And the component I am referring to:
import { Input } from 'components/atoms/Input/Input.styles';
import React, { useState } from 'react';
import debounce from 'lodash.debounce';
import {
SearchBarWrapper,
SearchResults,
SearchResultsItem,
SearchWrapper,
} from 'components/organisms/SearchBar/SearchBar.styles';
import { useElements } from 'hooks/useElements';
import { useCombobox } from 'downshift';
export const SearchBar = () => {
const [matchingElements, setMatchingElements] = useState([]);
const { findElements } = useElements();
const getMatchingStudents = debounce(async ({ inputValue }) => {
const elements = await findElements(inputValue);
setMatchingElements(elements);
}, 500);
const {
isOpen,
getMenuProps,
getInputProps,
getComboboxProps,
highlightedIndex,
getItemProps,
} = useCombobox({
items: matchingElements,
onInputValueChange: getMatchingElements,
});
return (
<SearchBarWrapper>
<SearchWrapper {...getComboboxProps}>
<Input
{...getInputProps()}
name="Search"
id="Search"
placeholder="Search"
/>
<SearchResults
$isVisible={isOpen && matchingElements.length > 0}
{...getMenuProps()}
>
{isOpen &&
matchingElements.map((item, index) => (
<SearchResultsItem
$isHighlighted={highlightedIndex === index}
{...getItemProps({ item, index })}
key={item.id}
>
{item.name}
</SearchResultsItem>
))}
</SearchResults>
</SearchWrapper>
</SearchBarWrapper>
);
};
The application itself works correctly - when entering the string 'el' in the input, the dropdown list appears with the item 'element'. When the input is empty or I click outside the input, the list disappears. Clicking again on the input with the mentioned string causes the list to reappear. There are no errors in the browser console (F12).
The test seems to give no results after execution fireEvent.change(input, { target: { value: 'el' } });, as if there were no elements of SearchResultsItem (li) in SearchResults (ul), only the input receives the value 'el', and the list does not "expand" at all.
I have tried various tricks such as using functions like expect(), toBeInTheDocument(), toBeVisible(), toBeTruthy(), waitFor(), assigning labels to SearchResultsItem, etc., but none of it works.