Display: none и visibility: hidden

При тестировании компонентов с помощью React Testing Library (RTL) необходимо учитывать, как различные стили влияют на поведение элементов. Одним из ключевых аспектов является использование CSS-свойств, таких как display: none и visibility: hidden. Эти два свойства часто используются для скрытия элементов на странице, но они ведут себя по-разному и могут существенно изменять результаты тестов.

Различия между display: none и visibility: hidden

  • display: none: Элемент с таким стилем полностью исчезает с страницы. Он не занимает места в потоке документа, его размеры не учитываются, и он не взаимодействует с пользователем (не реагирует на события). Для тестов это означает, что такие элементы нельзя будет найти через методы поиска, такие как getByText или getByRole, поскольку они физически не присутствуют в DOM.

  • visibility: hidden: Элемент остаётся в потоке документа, но становится невидимым. Он по-прежнему занимает место на странице, и его размеры учитываются. Однако он не реагирует на события ввода, такие как клики или фокусировка. В тестах это может привести к ситуации, когда элемент доступен для поиска, но не взаимодействует с пользователем.

Влияние на тесты

React Testing Library ориентирована на поведение компонентов с точки зрения пользователя, а не внутренней реализации. Это означает, что тесты должны проверять, что происходит в реальном пользовательском интерфейсе, а не только в DOM-структуре.

  • Элементы с display: none: Эти элементы не будут доступны для поиска, что делает их трудными для взаимодействия в тестах. При попытке найти такой элемент методами RTL, например, getByText, произойдёт ошибка. Если тест требует взаимодействия с элементом, скрытым с помощью display: none, нужно будет либо изменить тест, либо перед его запуском убедиться, что элемент не скрыт этим свойством.

  • Элементы с visibility: hidden: Элементы, скрытые таким образом, всё ещё могут быть найдены в DOM и взаимодействовать с ними можно с помощью методов поиска. Однако они не смогут принимать пользовательский ввод, что может быть важно для функциональных тестов. Например, если элемент скрыт через visibility: hidden и тест пытается симулировать клик, он не будет выполнен.

Как тестировать элементы с display: none и visibility: hidden

Для тестирования компонентов, скрытых с помощью этих стилей, можно использовать несколько подходов:

  1. Проверка наличия элемента в DOM: Для элементов с display: none можно использовать методы RTL, такие как queryBy*, чтобы проверить, что элемент не присутствует в DOM. Элементы с visibility: hidden могут быть найдены, но для взаимодействия с ними необходимо учитывать, что они невидимы и не могут быть активными.

    test('не отображается элемент с display: none', () => {
      const { queryByTestId } = render(<MyComponent />);
      const element = queryByTestId('hidden-element');
      expect(element).not.toBeInTheDocument(); // Элемент не должен быть в документе
    });
  2. Тестирование видимости с visibility: hidden: Для элементов с этим стилем можно проверить, что они присутствуют в DOM, но не видны на экране. Это можно сделать с помощью методов проверки стилей, например, через getComputedStyle.

    test('элемент с visibility: hidden остаётся в DOM, но невидим', () => {
      const { getByTestId } = render(<MyComponent />);
      const element = getByTestId('hidden-element');
      expect(element).toBeInTheDocument(); // Элемент должен быть в документе
      expect(getComputedStyle(element).visibility).toBe('hidden'); // Элемент скрыт
    });
  3. Тестирование изменения состояния видимости: Важно также тестировать, как элементы с display: none или visibility: hidden изменяются при взаимодействии с компонентом. Например, при нажатии на кнопку элемент может стать видимым. В этом случае можно протестировать изменение классов или стилей компонента, а также его видимость:

    test('элемент становится видимым после клика', () => {
      const { getByTestId, getByText } = render(<MyComponent />);
      const toggleButton = getByText('Показать элемент');
      const element = getByTestId('hidden-element');
    
      // Проверка начальной невидимости
      expect(element).toHaveStyle('visibility: hidden');
    
      fireEvent.click(toggleButton);
    
      // Проверка видимости после клика
      expect(element).toHaveStyle('visibility: visible');
    });

Практическое применение в реальных проектах

В реальных проектах часто используются стили display: none и visibility: hidden для управления видимостью элементов в зависимости от состояния компонента (например, модальные окна, выпадающие меню). Для правильного тестирования таких компонентов следует:

  • Использовать методы, которые проверяют, что элемент действительно отсутствует или скрыт. toBeInTheDocument и toHaveStyle — полезные инструменты для таких проверок.
  • Учитывать, что элементы с display: none не будут доступны для поиска в DOM. Если элемент должен быть доступен для поиска, можно использовать visibility: hidden, а также проверять, что его размеры и местоположение не изменились.
  • Понимать, что элементы, скрытые через display: none, могут не быть полезными для тестирования пользовательского взаимодействия, так как они не будут реагировать на события.

Таким образом, правильное использование стилей и грамотное тестирование поведения скрытых элементов с помощью React Testing Library позволяет создавать более стабильные и надежные тесты, отражающие реальные сценарии взаимодействия с интерфейсом.