Проверка видимости с isVisible()

isVisible() — это метод, предоставляемый библиотекой Vue Test Utils, который позволяет проверять, видим ли компонент или его элемент в DOM. Он играет ключевую роль в тестировании пользовательских интерфейсов, где важно убедиться, что элементы отображаются корректно в зависимости от состояния приложения или условий рендеринга.

Основные принципы работы isVisible()

Метод возвращает булево значение:

  • true — элемент видим для пользователя;
  • false — элемент скрыт.

Под видимостью понимается, что элемент:

  1. Существует в DOM;
  2. Имеет ненулевые размеры (offsetWidth > 0 && offsetHeight > 0);
  3. Не скрыт через CSS-свойства display: none или visibility: hidden;
  4. Не скрыт через родительские элементы с display: none.

Таким образом, isVisible() проверяет не только сам элемент, но и его контекст в DOM.

Применение в тестах

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

import { mount } from '@vue/test-utils';
import MyComponent from '@/components/MyComponent.vue';

describe('MyComponent', () => {
  it('отображает элемент при visible=true', () => {
    const wrapper = mount(MyComponent, {
      props: { visible: true }
    });
    const element = wrapper.find('.my-element');
    expect(element.isVisible()).toBe(true);
  });

  it('скрывает элемент при visible=false', () => {
    const wrapper = mount(MyComponent, {
      props: { visible: false }
    });
    const element = wrapper.find('.my-element');
    expect(element.isVisible()).toBe(false);
  });
});

В этом примере метод isVisible() позволяет проверить реактивное поведение компонента на изменение пропсов.

Проверка динамического состояния

Vue Test Utils интегрируется с реактивностью Vue, поэтому isVisible() корректно работает с динамическими изменениями состояния:

it('динамически скрывает и отображает элемент', async () => {
  const wrapper = mount(MyComponent, { props: { visible: true } });
  const element = wrapper.find('.my-element');
  
  expect(element.isVisible()).toBe(true);

  await wrapper.setProps({ visible: false });
  expect(element.isVisible()).toBe(false);

  await wrapper.setProps({ visible: true });
  expect(element.isVisible()).toBe(true);
});

Метод учитывает асинхронные обновления DOM после изменения состояния компонента.

Особенности работы с условным рендерингом

Элементы, рендер которых управляется директивой v-if, полностью удаляются из DOM, когда условие ложно. В таких случаях isVisible() возвращает false для отсутствующих элементов:

const wrapper = mount(MyComponent, { props: { show: false } });
const element = wrapper.find('.conditional');
expect(element.exists()).toBe(false);
// isVisible() для несуществующего элемента вызовет ошибку

Важно: перед вызовом isVisible() необходимо убедиться, что элемент существует через exists(), чтобы избежать ошибок.

В отличие от v-if, элементы с v-show остаются в DOM, но скрываются через CSS. В этом случае isVisible() корректно возвращает false:

const wrapper = mount(MyComponent, { props: { visible: false } });
const element = wrapper.find('.toggled');
expect(element.exists()).toBe(true);
expect(element.isVisible()).toBe(false);

Сложные случаи видимости

  1. Элементы с opacity: 0isVisible() вернёт true, так как элемент физически присутствует в DOM и имеет размеры. Этот момент важно учитывать при тестировании анимаций или прозрачных элементов.
  2. Элементы за пределами области видимости (overflow: hidden) — isVisible() также вернёт true, так как метод не проверяет положение на экране, только рендеринг в DOM.
  3. Элементы, скрытые через position: absolute и clip — аналогично, метод не детектирует визуальное перекрытие или обрезку.

Комбинирование с другими методами

isVisible() часто используется вместе с:

  • exists() — для проверки существования элемента;
  • classes() — для проверки классов, управляющих видимостью;
  • text() — чтобы убедиться, что видимый элемент содержит ожидаемый текст.

Пример:

const wrapper = mount(MyComponent, { props: { visible: true } });
const element = wrapper.find('.message');

expect(element.exists()).toBe(true);
expect(element.isVisible()).toBe(true);
expect(element.classes()).toContain('active');
expect(element.text()).toBe('Привет, мир!');

Практические рекомендации

  • Всегда проверять exists() перед isVisible().
  • Для v-if использование isVisible() напрямую может быть опасным, так как элемент может отсутствовать.
  • Для тестирования CSS-анимаций или прозрачности не полагаться исключительно на isVisible().
  • Использовать метод для логических проверок отображения элементов, а не для визуальных тестов положения на экране.

isVisible() является универсальным инструментом для тестирования логики отображения компонентов Vue, обеспечивая ясные и предсказуемые проверки в сочетании с реактивностью и условным рендерингом.