В веб-приложениях часто встречаются формы с полями, которые появляются или исчезают в зависимости от состояния приложения или выбора пользователя. Тестирование таких форм требует особого подхода, чтобы убедиться, что условная логика отображения работает корректно и взаимодействие с пользователем не вызывает ошибок.
Проверка начального состояния Перед
взаимодействием с формой важно убедиться, что поля, которые должны быть
скрыты, действительно отсутствуют в DOM. Для этого используется метод
queryBy* из React Testing Library, который возвращает
null, если элемент не найден.
import { render, screen } from '@testing-library/react';
import FormComponent from './FormComponent';
test('скрытое поле не отображается изначально', () => {
render(<FormComponent />);
const conditionalField = screen.queryByLabelText(/Дополнительная информация/i);
expect(conditionalField).toBeNull();
});Симуляция взаимодействия пользователя Для
проверки условного отображения необходимо смоделировать действия
пользователя, которые активируют показ скрытых полей. В React Testing
Library для этого используют fireEvent или
userEvent.
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import FormComponent from './FormComponent';
test('появление поля после выбора опции', async () => {
render(<FormComponent />);
const toggleCheckbox = screen.getByLabelText(/Показать дополнительное поле/i);
await userEvent.click(toggleCheckbox);
const conditionalField = screen.getByLabelText(/Дополнительная информация/i);
expect(conditionalField).toBeInTheDocument();
});Проверка правильной работы при обратном действии Важно тестировать не только появление поля, но и его скрытие, если пользователь отменяет действие. Это предотвращает баги с некорректным состоянием DOM.
test('скрытие поля при снятии галочки', async () => {
render(<FormComponent />);
const toggleCheckbox = screen.getByLabelText(/Показать дополнительное поле/i);
await userEvent.click(toggleCheckbox);
await userEvent.click(toggleCheckbox); // снимаем галочку
const conditionalField = screen.queryByLabelText(/Дополнительная информация/i);
expect(conditionalField).toBeNull();
});getBy* — выбрасывает ошибку, если
элемент отсутствует, подходит для проверки обязательных элементов.queryBy* — возвращает
null, если элемент отсутствует, идеально для тестирования
скрытых полей.findBy* — возвращает промис, подходит
для асинхронного появления элементов после действия пользователя.Использование правильного метода селектора гарантирует, что тесты не будут ложноположительными или ломаться при условной логике отображения.
Если форма загружает поля динамически, например, после API-запроса
или таймера, необходимо использовать асинхронные методы и
waitFor:
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import FormComponent from './FormComponent';
test('появление поля после асинхронного действия', async () => {
render(<FormComponent />);
const loadButton = screen.getByText(/Загрузить поле/i);
await userEvent.click(loadButton);
await waitFor(() => {
const conditionalField = screen.getByLabelText(/Дополнительная информация/i);
expect(conditionalField).toBeInTheDocument();
});
});
waitFor обеспечивает проверку DOM через промежутки
времени до появления нужного элемента, предотвращая ошибки в асинхронной
логике.
После появления условного поля важно убедиться, что с ним можно корректно взаимодействовать:
test('ввод текста в условное поле', async () => {
render(<FormComponent />);
const toggleCheckbox = screen.getByLabelText(/Показать дополнительное поле/i);
await userEvent.click(toggleCheckbox);
const conditionalField = screen.getByLabelText(/Дополнительная информация/i);
await userEvent.type(conditionalField, 'Тестовый текст');
expect(conditionalField).toHaveValue('Тестовый текст');
});
Это проверяет не только отображение поля, но и его функциональность в реальном сценарии использования.
describe для логической группировки тестов
одного блока формы.beforeEach для рендеринга компонента, если
тестов много, чтобы избежать дублирования кода.describe('Условное отображение дополнительного поля', () => {
beforeEach(() => render(<FormComponent />));
test('поле скрыто по умолчанию', () => { /* ... */ });
test('поле появляется при выборе опции', () => { /* ... */ });
test('поле исчезает при отмене выбора', () => { /* ... */ });
});
Такой подход повышает читаемость тестов и упрощает поддержку при изменении логики формы.
Тестирование условного отображения полей форм требует внимательного
подхода к селекторам и имитации действий пользователя. Комбинация
queryBy*, getBy*, асинхронных методов и
симуляции событий позволяет создавать стабильные тесты, которые точно
отражают поведение формы в реальном приложении.