Работа с CSS селекторами и атрибутами

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


Выбор элементов по CSS селекторам

Методы mount и shallowMount возвращают объект Wrapper, через который осуществляется доступ к элементам компонента. Основными способами поиска элементов являются методы find и findAll.

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

const wrapper = mount(MyComponent)

// Поиск одного элемента по CSS классу
const button = wrapper.find('.submit-button')

// Поиск всех элементов по тегу
const listItems = wrapper.findAll('li')

// Поиск элемента по ID
const header = wrapper.find('#main-header')

Особенности использования CSS селекторов:

  • Поддерживаются сложные селекторы: комбинированные классы, псевдоклассы, атрибутные селекторы (input[type="text"]).
  • Метод find возвращает первый найденный элемент, а findAll — коллекцию WrapperArray.
  • Можно использовать селекторы через вложенные элементы: wrapper.find('.parent .child').

Проверка наличия и значения атрибутов

Vue Test Utils позволяет проверять как стандартные, так и пользовательские атрибуты DOM-элементов с помощью метода attributes().

const input = wrapper.find('input[type="text"]')

// Проверка наличия атрибута
expect(input.attributes('placeholder')).toBe('Введите текст')

// Проверка boolean-атрибутов
const checkbox = wrapper.find('input[type="checkbox"]')
expect(checkbox.attributes('checked')).toBeDefined()

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

  • Метод attributes() возвращает объект со всеми атрибутами элемента.
  • Для boolean-атрибутов проверка производится через toBeDefined() или toBe('') в зависимости от того, как браузер обрабатывает атрибут.
  • Метод можно использовать для проверки динамически задаваемых атрибутов через v-bind.

Работа с классами и стилями

Vue Test Utils предоставляет методы classes() и element.style, позволяющие проверять CSS-классы и inline-стили.

const button = wrapper.find('button')

// Проверка наличия класса
expect(button.classes()).toContain('active')

// Проверка нескольких классов
expect(button.classes()).toEqual(expect.arrayContaining(['btn', 'btn-primary']))

// Проверка inline-стиля
expect(button.element.style.backgroundColor).toBe('red')

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

  • classes() возвращает массив всех классов элемента.
  • Можно проверять как динамически добавляемые, так и статические классы.
  • Inline-стили доступны через объект element.style, но стили из CSS-файлов нужно проверять через window.getComputedStyle при интеграционных тестах.

Использование атрибутных селекторов

Vue Test Utils поддерживает CSS-селекторы по атрибутам, что особенно полезно для тестирования компонентов с динамическими данными.

// Поиск кнопки с определённым data-атрибутом
const specialButton = wrapper.find('[data-test="special-button"]')
expect(specialButton.exists()).toBe(true)

// Проверка элементов с определённым состоянием
const disabledInput = wrapper.find('input[disabled]')
expect(disabledInput.exists()).toBe(true)

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

  • Для элементов, которые участвуют только в тестах, используют data-test атрибуты, чтобы отделить тестовую логику от визуальной.
  • Атрибутные селекторы позволяют обходить ограничения по динамическим классам, которые могут изменяться при рендере.

Поиск вложенных элементов

Иногда необходимо искать элементы внутри дочерних компонентов. Для этого методы find и findAll поддерживают цепочки вызовов и поиск внутри Wrapper дочернего компонента.

const parentWrapper = wrapper.find('.parent-component')
const childButton = parentWrapper.find('button.child-action')
expect(childButton.exists()).toBe(true)

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

  • Вложенный поиск не требует знания внутренней структуры компонента за пределами тестируемого DOM.
  • Можно комбинировать классы, теги и атрибуты для точного выбора.

Советы по надёжному тестированию селекторов

  1. Использовать data-test атрибуты для критических элементов, чтобы селекторы не ломались при изменении стилей.
  2. Избегать селекторов по порядку (nth-child), если нет строгой необходимости, так как это делает тесты хрупкими.
  3. Проверять существование элемента через exists(), прежде чем проверять его атрибуты или классы.
  4. Комбинировать селекторы для повышения точности, например, .modal .close-button[data-action="close"].

Пример комплексного теста

test('кнопка submit активна только при заполненном поле', async () => {
  const wrapper = mount(MyComponent)
  const input = wrapper.find('input[name="username"]')
  const button = wrapper.find('button.submit')

  expect(button.attributes('disabled')).toBeDefined()

  await input.setValue('user123')
  expect(button.attributes('disabled')).toBeUndefined()
  expect(button.classes()).toContain('active')
})

В этом примере проверяется не только наличие атрибутов и классов, но и реакция компонента на пользовательский ввод, что демонстрирует синергетическое использование селекторов и атрибутов.


Работа с CSS-селекторами и атрибутами в Vue Test Utils позволяет создавать точные, надёжные и гибкие тесты компонентов, обеспечивая глубокий контроль над DOM-структурой и состоянием элементов.