Как протестировать свободное раскрывающееся меню пользовательского интерфейса с помощью библиотеки тестирования реакции?
Я новичок в библиотеке тестирования реакции, так что это может быть легко, но в настоящее время у меня есть раскрывающийся список, который я импортирую из свободного пользовательского интерфейса, и в настоящее время получаю ошибку "Элемент не имеет установщика значения", когда я пытаюсь его протестировать. используя библиотеку React Testing. Вот моя функция рендеринга.
import { Dropdown, IDropdownStyles, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import { Stack } from 'office-ui-fabric-react/lib/Stack';
render()
{
return (
<div className="LandingPage">
<h3>Here are some options</h3>
<form onSubmit={this.handleSubmit}>
<Stack>
<Stack.Item align="center">
<Dropdown
placeholder="Select an option"
label="Select an option"
options={this.options}
styles={this.dropdownStyles}
onChange={this.handleChange}
data-testid="myId"
/>
</Stack.Item>
</Stack>
</form>
</div>
);
}
}
Вот строка, которая терпит неудачу:
const dropdownOption: IDropdownOption = {
key: "0",
text: "dropdownOption"
}
fireEvent.click(queryByTestId("myId"), { target: { value: 'B' }, option: dropdownOption })
The given element does not have a value setter
> 44 | fireEvent.click(queryByTestId("myId"), { target: { value: 'B' }, option: dropdownOption })
| ^
3 ответа
Проблема заключается в реализации FluentUI компонента Dropdown. Если вы проверите сгенерированный HTML, вы обнаружите, что он просто стилизован
<div>
и что нет никаких элементов в качестве дочерних узлов.
Чтобы проверить, что в данный момент отображается при тестировании, вы можете добавить эту строку в свой тест, и он будет отображать «целый» HTML (если он достаточно мал, в противном случае увеличьте второй параметр на несколько нулей).
screen.debug(undefined, 10000000);
Чтобы иметь возможность видеть эти
<option>
элементы, которые вы должны сначала нажать на
<Dropdown>
составная часть. После нажатия нового
span
элементы с ролью
option
будут отображаться, и вы можете получить к ним доступ.
Чтобы щелкнуть раскрывающийся список, вы можете использовать или из
react-testing-library
.
Чтобы выбрать один из вариантов, вы также должны нажать на него. Там я узнал, что почему-то
userEvent
не работает, и вы должны использовать
fireEvent
.
Таким образом, весь пример может выглядеть так:
import { act, fireEvent, render, screen } from '@testing-library/react';
test('select value from FluentUI Dropdown', async () => {
render(<YourComponentWithDropdown/>);
// Get the dropdown HTML element
const dropdown = await screen.findByRole('combobox');
expect(dropdown).toBeDefined();
// Click on the dropdown
userEvent.click(dropdown);
// Find the option you want to select
const option = (await screen.findByRole('option', { name: 'Bannana bread' })) as HTMLButtonElement;
expect(option).toBeDefined();
// Click on the option
await act(async () => {
fireEvent.click(option);
});
// Test what should follow after selection
});
Вы можете сослаться на этот ответ: как проверить реакцию-выбор с помощью библиотеки-тестирования-реакции, а не с плавным пользовательским интерфейсом, но очень похожим. не используйте щелчок или изменение, используйте keyDown + щелчок
const DOWN_ARROW = { keyCode: 40 };
fireEvent.keyDown(screen.getByLabelText('myId'), DOWN_ARROW);
fireEvent.click(screen.getByText('...your text'));
и не используйте data-testid, вместо этого используйте aria-label.
Я обнаружил, что вам даже не нужно использовать fireEvent.keyDown, как если бы вы смотрели в шутливом снимке раскрывающегося компонента Fluent UI, все параметры раскрывающегося списка представляют собой выбираемые кнопки, которые доступны напрямую.
Вот что сработало для меня:
const option = screen.getAllByText("myDropdownOption")[0];
fireEvent.click(option);
Я не мог понять, какой селектор использовать здесь, так как выбор по тексту возвращает несколько элементов, а селектор «кнопка» тоже не работал, поэтому я решил использовать
getAllByText()[0]
чтобы захватить первый элемент и щелкнуть по нему. Это не очень красивое решение, поэтому я отвел его в вспомогательную функцию, пока не будет найден правильный селектор.