Проверка CSS display свойства

Vue Test Utils предоставляет мощный инструментарий для юнит-тестирования компонентов Vue, включая возможность проверки стилей элементов, таких как свойство display. Контроль отображения элементов часто необходим при тестировании условий рендеринга, динамических классов и стилей, а также при работе с компонентами, которые скрывают или показывают содержимое на основе пропсов или состояния.

Монтирование компонента и получение элемента

Первый шаг при проверке свойства display — это монтирование компонента с помощью mount или shallowMount из Vue Test Utils:

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

const wrapper = mount(MyComponent);
const element = wrapper.find('.target-element');

wrapper.find() возвращает объект Wrapper, который содержит ссылку на DOM-элемент. Для проверки стилей необходимо работать с реальным элементом через свойство .element.

Проверка inline-стилей

Если свойство display задано напрямую через атрибут style, его можно проверить с использованием element.style:

expect(element.element.style.display).toBe('none');

Важно помнить, что element.style.display работает только с inline-стилями. Стили, определённые в CSS-файлах или через классы, таким способом не считываются.

Проверка computed-стилей через getComputedStyle

Для проверки свойств, заданных через CSS-классы, необходимо использовать window.getComputedStyle:

const displayValue = window.getComputedStyle(element.element).display;
expect(displayValue).toBe('block');

getComputedStyle возвращает итоговое значение свойства после применения всех CSS-правил, включая наследование и специфичность. Этот метод позволяет точно определить, как элемент отображается в браузере.

Динамическое управление display

Компоненты часто изменяют display на основе пропсов или состояния. Например:

<template>
  <div :style="{ display: isVisible ? 'block' : 'none' }" class="toggle-element">
    Содержимое
  </div>
</template>

<script>
export default {
  props: {
    isVisible: Boolean
  }
}
</script>

Для тестирования динамического изменения состояния используется изменение пропсов и проверка обновленного DOM:

const wrapper = mount(MyComponent, {
  props: { isVisible: false }
});

let display = window.getComputedStyle(wrapper.find('.toggle-element').element).display;
expect(display).toBe('none');

await wrapper.setProps({ isVisible: true });

display = window.getComputedStyle(wrapper.find('.toggle-element').element).display;
expect(display).toBe('block');

Использование await wrapper.setProps() гарантирует, что Vue завершит реактивное обновление перед проверкой.

Тестирование классов, влияющих на display

Иногда display задаётся через классы CSS, например, при использовании утилит вроде Tailwind или Bootstrap:

<div :class="{ hidden: !isVisible }" class="toggle-class">Контент</div>

В этом случае element.classList позволяет проверить наличие или отсутствие класса:

expect(wrapper.find('.toggle-class').classes()).toContain('hidden');

Однако для точной проверки отображения следует комбинировать с getComputedStyle, чтобы убедиться, что класс действительно меняет display:

const display = window.getComputedStyle(wrapper.find('.toggle-class').element).display;
expect(display).toBe('none'); // когда hidden

Рекомендации по тестированию display

  • Всегда использовать window.getComputedStyle для стилей, заданных через CSS-классы.
  • Для inline-стилей достаточно проверки element.style.display.
  • При динамическом изменении пропсов или состояния необходимо использовать await wrapper.setProps() или await wrapper.setData().
  • Проверка классов полезна для тестирования логики, но не заменяет проверку фактического отображения.
  • Избегать прямого сравнения element.style.cssText, так как порядок и форматирование стилей могут отличаться между браузерами.

Примеры сложных сценариев

  1. Компонент с несколькими состояниями:
<div :style="{ display: isVisible ? 'flex' : 'none' }" class="multi-state">
  Контент
</div>
await wrapper.setProps({ isVisible: true });
expect(window.getComputedStyle(wrapper.find('.multi-state').element).display).toBe('flex');

await wrapper.setProps({ isVisible: false });
expect(window.getComputedStyle(wrapper.find('.multi-state').element).display).toBe('none');
  1. Комбинация классов и inline-стилей:
<div :class="{ hidden: !isVisible }" :style="{ display: customDisplay }">Контент</div>
wrapper.setProps({ isVisible: false, customDisplay: 'grid' });
const el = wrapper.find('div').element;
expect(window.getComputedStyle(el).display).toBe('grid');

Такая проверка учитывает, что inline-стиль имеет приоритет над классом CSS.

Интеграция с Jest

Для Jest достаточно использовать стандартные методы expect и toBe. При необходимости можно использовать toHaveStyle из дополнительных библиотек вроде @testing-library/jest-dom для более читабельных утверждений:

import '@testing-library/jest-dom';

expect(wrapper.find('.toggle-element').element).toHaveStyle('display: none');

Это позволяет писать более декларативные тесты, избегая прямого обращения к getComputedStyle.