Accessibility и видимость

Accessibility (доступность) и корректная видимость компонентов — критические аспекты при тестировании Vue-приложений. Они позволяют не только проверять функциональность, но и гарантировать соответствие стандартам доступности, а также корректное поведение компонентов в DOM.


Проверка видимости элементов

Vue Test Utils предоставляет методы для работы с DOM-элементами компонентов. Наиболее часто используется метод isVisible(), который возвращает true, если элемент реально отображается на странице.

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

test('проверка видимости кнопки', () => {
  const wrapper = mount(MyComponent)
  const button = wrapper.find('button')
  expect(button.isVisible()).toBe(true)
})

Особенности метода isVisible():

  • Возвращает false, если элемент скрыт через CSS (display: none или visibility: hidden).
  • Не учитывает элементы, находящиеся вне DOM.
  • Работает только с одним элементом — для проверки группы элементов необходимо итерировать их с помощью findAll.
const items = wrapper.findAll('.list-item')
items.forEach(item => {
  expect(item.isVisible()).toBe(true)
})

Тестирование доступности (Accessibility)

Vue Test Utils не содержит встроенных средств для проверки ARIA-атрибутов и семантической разметки, но позволяет легко получать доступ к элементам и их атрибутам. Для проверки доступности используются методы attributes() и element.

const input = wrapper.find('input')
expect(input.attributes('aria-label')).toBe('Имя пользователя')
expect(input.element.getAttribute('required')).toBeDefined()

Рекомендации по проверке доступности:

  • Проверка ARIA-атрибутов (aria-label, aria-labelledby, aria-hidden, aria-expanded).
  • Проверка семантических тегов (<button>, <header>, <main>).
  • Проверка состояния элементов, доступных для клавиатуры (tabindex, disabled).

Симуляция условий видимости

Для комплексных компонентов часто необходимо проверять видимость элементов при изменении состояния или пропсов. Использование реактивности Vue позволяет эмулировать изменения состояния:

const wrapper = mount(MyComponent, {
  props: { showModal: false }
})
expect(wrapper.find('.modal').isVisible()).toBe(false)

await wrapper.setProps({ showModal: true })
expect(wrapper.find('.modal').isVisible()).toBe(true)

Особенности работы с реактивностью:

  • Методы setProps, setData и setValue автоматически инициируют обновление DOM.
  • После изменения состояния рекомендуется использовать await nextTick(), чтобы убедиться в обновлении видимости элементов.
import { nextTick } from 'vue'

wrapper.setData({ isOpen: true })
await nextTick()
expect(wrapper.find('.dropdown').isVisible()).toBe(true)

Комбинация с сторонними библиотеками доступности

Для более глубокой проверки Accessibility можно интегрировать Vue Test Utils с библиотеками типа axe-core:

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

test('проверка доступности через axe', async () => {
  const wrapper = mount(MyComponent)
  const results = await axe.run(wrapper.element)
  expect(results.violations.length).toBe(0)
})

Это позволяет автоматически выявлять нарушения стандартов WCAG, проверять цветовой контраст, правильность ARIA-атрибутов и семантики.


Локаторы и селекторы для видимости

Выбор корректного локатора критичен для тестирования видимости:

  • find() и findAll() работают с CSS-селекторами.
  • findComponent() позволяет работать с компонентами Vue напрямую.
  • get() — альтернатива find(), которая бросает ошибку, если элемент не найден, что удобно для строгой проверки видимости.
const modal = wrapper.get('.modal') // выбросит ошибку, если модальное окно отсутствует
expect(modal.isVisible()).toBe(true)

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

Vue-компоненты часто рендерят элементы условно через v-if или v-show. В тестах необходимо различать:

  • v-if: элемент отсутствует в DOM, isVisible() вернёт false.
  • v-show: элемент присутствует, но может быть скрыт через CSS.
expect(wrapper.find('.hidden-by-if').exists()).toBe(false)
expect(wrapper.find('.hidden-by-show').isVisible()).toBe(false)

Эти различия важны при тестировании модальных окон, всплывающих подсказок и выпадающих списков.


Проверка доступности интерактивных элементов

Для кнопок, ссылок и полей ввода важно не только, что они видимы, но и что они доступны для взаимодействия:

const button = wrapper.find('button')
expect(button.attributes('disabled')).toBeUndefined() // элемент активен
await button.trigger('click') // эмулируем клик
expect(wrapper.emitted()).toHaveProperty('submit')

Тестирование таких элементов гарантирует, что пользователи смогут использовать интерфейс полностью, независимо от устройства или вспомогательных технологий.


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

  • Группировать тесты по компоненту и состоянию видимости.
  • Проверять как наличие элемента в DOM (exists()), так и его видимость (isVisible()).
  • Отдельно проверять ARIA-атрибуты и интерактивность.
  • Использовать nextTick() после изменения данных или пропсов для корректного отображения изменений.

Эффективное сочетание методов Vue Test Utils для работы с видимостью и проверкой доступности позволяет создавать надежные, семантически корректные тесты, обеспечивающие качественный и доступный интерфейс.