Мышь события: hover, unhover, move

React Testing Library (RTL) предоставляет мощные инструменты для тестирования пользовательских взаимодействий. Одним из ключевых аспектов является эмуляция событий мыши: наведение (hover), уход курсора (unhover) и перемещение (move). Эти события позволяют тестировать динамическое поведение интерфейса, например появление всплывающих подсказок, изменение стилей, анимации и реакции на drag-and-drop.


Эмуляция наведения курсора (hover)

Событие hover используется для проверки реакций компонента на наведение мыши. В RTL оно реализуется через функцию userEvent.hover(element).

Пример использования:

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Tooltip from './Tooltip';

test('показывает подсказку при наведении', async () => {
  render(<Tooltip text="Подсказка">Наведи на меня</Tooltip>);

  const target = screen.getByText('Наведи на меня');

  await userEvent.hover(target);

  const tooltip = screen.getByText('Подсказка');
  expect(tooltip).toBeVisible();
});

Ключевые моменты:

  • hover автоматически вызывает событие mouseover и mouseenter.
  • Подходит для тестирования появления элементов, изменения стилей, добавления классов.
  • Если компонент использует анимацию появления, может потребоваться асинхронная проверка (await waitFor(...)).

Эмуляция ухода курсора (unhover)

Событие unhover проверяет, что компонент корректно реагирует на уход курсора. В RTL это делается с помощью userEvent.unhover(element).

Пример использования:

test('скрывает подсказку после ухода курсора', async () => {
  render(<Tooltip text="Подсказка">Наведи на меня</Tooltip>);

  const target = screen.getByText('Наведи на меня');
  
  await userEvent.hover(target);
  expect(screen.getByText('Подсказка')).toBeVisible();

  await userEvent.unhover(target);
  expect(screen.queryByText('Подсказка')).not.toBeInTheDocument();
});

Особенности unhover:

  • Вызывает события mouseout и mouseleave.
  • Используется для проверки скрытия элементов, отмены эффектов наведения.
  • При асинхронных эффектах также может потребоваться waitFor.

Перемещение мыши (move)

Событие move позволяет симулировать движение мыши над элементом или документом. В RTL это достигается через userEvent.pointer({ target: element, keys: [], pointerName: 'mouse', type: 'pointerMove' }) либо через последовательность hover/unhover для упрощённых сценариев.

Пример использования для drag-and-drop:

import DraggableBox from './DraggableBox';

test('перетаскивание элемента мышью', async () => {
  render(<DraggableBox />);

  const box = screen.getByRole('box');

  await userEvent.pointer({ keys: '[MouseLeft]', target: box, type: 'pointerDown' });
  await userEvent.pointer({ target: box, coords: { x: 100, y: 50 }, type: 'pointerMove' });
  await userEvent.pointer({ keys: '[/MouseLeft]', target: box, type: 'pointerUp' });

  expect(box).toHaveStyle({ left: '100px', top: '50px' });
});

Особенности работы с move:

  • Позволяет тестировать сложные взаимодействия: drag-and-drop, прокрутку, динамические подсказки.
  • Требует точного указания координат и состояния кнопок мыши.
  • В комбинации с hover и unhover можно эмулировать полный жизненный цикл взаимодействия.

Важные советы по тестированию событий мыши

  1. Асинхронность: многие эффекты при hover/unhover или move могут быть асинхронными, поэтому стоит использовать await и waitFor.
  2. Проверка видимости: проверка через toBeVisible() предпочтительнее, чем проверка наличия в DOM (toBeInTheDocument()), если элемент остается в DOM, но скрыт стилями.
  3. Комбинации событий: hover часто сопровождается pointerMove, а unhover — pointerOut; точное воспроизведение последовательности событий важно для корректного теста.
  4. Стили и классы: при hover/unhover можно проверять изменения классов (classList) или inline-стилей, если визуальные изменения критичны.

Эффективное использование hover, unhover и move в тестах позволяет эмулировать реальные пользовательские сценарии, делая тесты максимально близкими к поведению в браузере. Правильная комбинация этих событий помогает проверять как визуальные эффекты, так и логику управления состоянием компонентов при взаимодействии с мышью.