Проверяешь ли тестами видимость кнопки
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Проверка видимости кнопки в автоматизированных тестах
В современной практике Frontend разработки тестирование видимости элементов, особенно критических компонентов интерфейса, таких как кнопки, является обязательной частью обеспечения качества. Я рассматриваю проверку видимости не как отдельную операцию, а как комплексный процесс, охватывающий несколько уровней тестирования, каждый из которых имеет свою цель и инструментарий.
Уровни тестирования видимости кнопки
1. Unit-тестирование (Компонентный уровень)
На этом уровне я проверяю условия рендеринга компонента кнопки внутри его изолированной среды (например, в Jest + React Testing Library). Тестируется логика, управляющая видимостью: скрытие кнопки при отсутствии данных, изменение ее состояния в зависимости от пропсов или внутреннего состояния компонента.
// Пример unit-теста для React компонента
import { render, screen } from '@testing-library/react';
import ActionButton from './ActionButton';
describe('ActionButton visibility logic', () => {
it('should NOT render button when `isVisible` prop is false', () => {
render(<ActionButton isVisible={false} label="Submit" />);
const buttonElement = screen.queryByRole('button', { name: /Submit/i });
expect(buttonElement).toBeNull(); // Проверяем отсутствие в DOM
});
it('should render button when `isVisible` prop is true', () => {
render(<ActionButton isVisible={true} label="Submit" />);
const buttonElement = screen.getByRole('button', { name: /Submit/i });
expect(buttonElement).toBeInTheDocument(); // Проверяем наличие
expect(buttonElement).toBeVisible(); // Проверяем видимость (CSS не скрывает)
});
});
2. Integration-тестирование (Интеграционный уровень)
Здесь проверяется взаимодействие кнопки с другими компонентами или сервисами. Например, кнопка становится видимой только после успешной загрузки данных из API. Я использую тот же инструментарий, но с более сложными сценариями и моками зависимостей.
// Пример интеграционного теста с моком API
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import PaymentForm from './PaymentForm';
describe('PaymentForm button visibility', () => {
it('should show "Pay" button only after successful data fetch', async () => {
// Мокаем успешный ответ API
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: async () => ({ balance: 100 })
});
render(<PaymentForm />);
// Первоначально кнопка отсутствует
expect(screen.queryByRole('button', { name: /Pay/i })).toBeNull();
// После загрузки данных появляется
await waitFor(() => {
expect(screen.getByRole('button', { name: /Pay/i })).toBeVisible();
});
});
});
3. End-to-End (E2E) тестирование (Полный цикл)
Наиболее приближенный к реальному пользователю уровень. Я использую инструменты типа Cypress или Playwright для проверки видимости кнопки в реальном браузерном окружении, учитывая все факторы: CSS стили (display, visibility, opacity), layout влияния (перекрытие другими элементами, скрытие за родительским контейнером с overflow: hidden), влияние медиа-запросов (адаптивная видимость на разных размерах экрана).
// Пример E2E теста в Cypress
describe('Button visibility on main page', () => {
it('should display "Contact Us" button on desktop viewport', () => {
cy.viewport(1920, 1080); // Десктопный размер
cy.visit('/');
cy.get('[data-testid="contact-button"]')
.should('be.visible') // Проверка видимости в браузере
.and('have.css', 'display', 'block'); // Проверка конкретного CSS свойства
});
it('should hide "Contact Us" button on mobile viewport via CSS media query', () => {
cy.viewport(375, 667); // Мобильный размер
cy.visit('/');
cy.get('[data-testid="contact-button"]')
.should('not.be.visible'); // Cypress проверяет совокупность CSS свойств
});
it('should keep button visible despite dynamic content loading', () => {
cy.visit('/dashboard');
// Кнопка видна сразу
cy.get('button#submit').should('be.visible');
// И остается видимой после тяжелой операции
cy.get('.loader').should('not.exist'); // Ждем завершения загрузки
cy.get('button#submit').should('be.visible');
});
});
Ключевые аспекты и лучшие практики
В своей практике я уделяю особое внимание следующим моментам при тестировании видимости:
- Селекторы ролей (
role): Я предпочитаю использоватьgetByRole('button')с возможным указанием имени (name), что соответствует принципам доступности (a11y) и делает тесты устойчивыми к изменениям в структуре DOM. - Комплексность проверки: Видимость — это не просто
toBeInTheDocument(). Элемент может присутствовать в DOM, но быть скрытым черезdisplay: none,visibility: hidden,opacity: 0, иметь нулевые размеры или быть перекрытым другим элементом. В E2E тестах.should('be.visible')проверяет все эти условия. - Условия и состояния: Я обязательно тестирую видимость кнопки в различных контекстах и состояниях приложения:
- После успешных и неуспешных действий (submit формы).
- В условиях ошибок сети.
- При разных состояниях авторизации пользователя.
- На различных этапах многошаговых процессов.
- Время и асинхронность: Правильная обработка асинхронных операций (
waitFor,findBy) критична. Кнопка может появляться после загрузки данных, исчезать во время отправки формы и появляться снова по завершении. - Интеграция с CI/CD: Все тесты, проверяющие видимость, интегрируются в pipeline непрерывной интеграции. Особенно важны E2E тесты, которые выполняются на реальных браузерных средах, что гарантирует проверку в условиях, максимально близких к production.
Таким образом, проверка видимости кнопки — это не единичный断言, а стратегически важная часть тестового покрытия, которая обеспечивает корректность пользовательского интерфейса, предотвращает потерю критического функционала и напрямую влияет на пользовательский опыт. Я всегда включаю такие проверки в тестовые сценарии для ключевых элементов управления.