5 идей для accessibility-тестов, которые можно автоматизировать уже сегодня

от автора

Введение

В предыдущей статье рассмотрели, как быстро настроить Cypress и axe-core для запуска автоматических тестов доступности (подробнее здесь).

Теперь время перейти к практике. Какие именно проверки стоит автоматизировать в первую очередь? На каких ошибках доступности можно поймать проблемы ещё до выхода на продакшн?

В этой статье — 5 простых, но эффективных идей для автоматизированных accessibility-тестов, которые помогают системно повышать качество интерфейсов при минимальных затратах.

1. Автоматическая проверка A11y нарушений на странице

Базовая, но мощная проверка: подключить axe-core и запускать cy.checkA11y() на всех страницах.

Что выявляет axe-core:

  • Контрастность текста и фона на соответствие минимальным требованиям контраста по стандарту WCAG 2.1 (например, 4.5:1 для обычного текста).

  • Отсутствие альтернативного текста (alt) у изображений

  • Некорректное использование ARIA-атрибутов. Например: aria-labelledby, указывающий на несуществующий ID.

  • Ошибка семантической структуры. Например, используется div вместо кнопок без роли button

  • Проблемы фокусировки (tabindex, правильные фокусы).

  • Отсутствие описаний у интерактивных элементов ****для озвучки скринридерами.

  • Ошибки в использовании ролей (role).

  • Дублирование ID (мешает корректной навигации для скринридеров)

  • Недоступные элементы управления

describe('eBay - Home Page Accessibility', () => {   it('Check for accessibility errors', () => {     cy.visit('/');     cy.axeAndCheck();   }); }); 

2. Проверка доступности главной навигации

Навигационное меню должно быть доступным с клавиатуры, иметь корректные role, aria-label, и быть видимым скринридеру. Проверки могут включать:

  • наличие nav или role="navigation"

  • проверку фокусировки по Tab

  • aria-expanded на раскрывающихся списках

describe('eBay - Navigation Accessibility', () => {   it('Check that the main navigation is accessible', () => {     cy.visit('/');      // Проверяем наличие навигационного блока     cy.get('nav, [role="navigation"]').should('exist');      // Проверяем наличие aria-label у навигации     cy.get('nav, [role="navigation"]')       .should('have.attr', 'aria-label')       .and('not.be.empty');      // Проверяем фокусировку на первом элементе навигации через Tab     cy.get('body').tab();     cy.focused()       .should('exist')       .and(($el) => {         const role = $el.attr('role') || '';         expect(role === 'link' || role === 'button').to.be.true;       });      // Проверяем наличие aria-expanded на раскрывающихся элементах (если есть)     cy.get('[aria-haspopup="true"]').each(($el) => {       cy.wrap($el).should('have.attr', 'aria-expanded');     });   }); });

3. Проверка форм и валидации ошибок

Формы — один из самых частых источников A11y-багов. Автотесты могут проверить:

  • наличие aria-label / aria-labelledby на input’ах

  • aria-describedby на ошибках

  • role=»alert» или aria-live для динамического вывода ошибок

describe('eBay - Form Fields Accessibility', () => {   it('Check for accessibility attributes on the search input', () => {     cy.visit('/');      // Проверяем, что поле поиска имеет соответствующие атрибуты     cy.get('input[placeholder="Search for anything"]')       .should(($input) => {         expect(           $input.attr('aria-label') || $input.attr('aria-labelledby')         ).to.exist;       });   });    it('Check that error messages have aria-describedby or live regions', () => {     cy.visit('/');      // Имитируем неправильный поиск или некорректный ввод, если возможно     cy.get('input[placeholder="Search for anything"]').type('{enter}');      // Проверка ошибок (если есть ошибки поиска, сообщения, алерты)     cy.get('body').then(($body) => {       if ($body.find('[role="alert"], [aria-live]').length) {         cy.get('[role="alert"], [aria-live]')           .should('exist')           .and('not.be.empty');       } else {         cy.log('No live error messages found (may not trigger without bad input)');       }     });   }); });

4. Фокус по клавиатуре

Пользователь должен иметь возможность перемещаться по всем интерактивным элементам с помощью Tab / Shift + Tab. Проверки могут включать:

  • наличие видимого фокуса (outline)

  • правильный порядок фокусировки

  • отсутствие «ловушек», где фокус застревает.

Для этих проверок нам понадобится дополнительный плагин — cypress-plugin-tab

Cypress по умолчанию не поддерживает событие нажатия клавиши Tab как пользовательскую навигацию между элементами.

Плагин cypress-plugin-tab добавляет команду .tab(), которая эмулирует реальное нажатие клавиши Tab, обеспечивая правильную навигацию по фокусируемым элементам страницы.

import 'cypress-plugin-tab';  describe('Keyboard Focus - eBay homepage', () => { it('Check that keyboard focus moves correctly and visibly', () => { cy.visit('/'); // Начинаем с body cy.get('body').tab();  // Проверяем, что фокус на интерактивном элементе cy.focused()   .should('exist')   .and(($el) => {     // Проверяем, что это ссылка, кнопка или другое интерактивное     const tag = $el.prop('tagName').toLowerCase();     expect(['a', 'button', 'input', 'select', 'textarea']).to.include(tag);   });  // Проверяем, что фокус визуально виден (outline) cy.focused().should('have.css', 'outline-style').and('not.eq', 'none');  // Дополнительно: пройти Tab несколько раз и убедиться, что переход есть for (let i = 0; i < 5; i++) {   cy.focused().tab();   cy.focused().should('exist'); } }); });

5. Динамические компоненты: модальные окна, алерты, уведомления

Важно, чтобы модальные окна:

  • перехватывали фокус при открытии,

  • имели aria-modal, aria-labelledby,

  • корректно скрывались и возвращали фокус.

describe('eBay - Modal Accessibility', () => { it('Check modal accessibility and focus trapping', () => { cy.visit('/'); // Открываем модальное окно (например, вход в аккаунт или фильтры поиска) cy.get('[data-testid="open-modal"]').click();  // Проверяем, что модальное окно открыто и имеет aria-modal cy.get('[role="dialog"]')   .should('exist')   .and('have.attr', 'aria-modal', 'true');  // Проверяем наличие заголовка для модального окна cy.get('[role="dialog"]').should('have.attr', 'aria-labelledby');  // Проверяем, что фокус переходит внутрь модального окна cy.focused().should('exist'); cy.get('[role="dialog"]').then(($dialog) => {   expect($dialog[0].contains(document.activeElement)).to.be.true; }); }); });

Заключение

Автоматизация доступности — это не замена ручному тестированию, а надёжный фундамент. Даже 1–2 простых проверки, встроенные в CI, уже заметно повышают качество продукта.

В этой статье рассмотрели реальные сценарии автоматизированных проверок:

  • Структуры и семантики страниц

  • Наличия альтернативного текста и корректных aria-атрибутов

  • Проверку фокусировки клавиатурой

  • Доступность динамических компонентов, таких как модальные окна и уведомления

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

Начать стоит с базовых тестов для ключевых страниц, постепенно расширяя покрытие на новые фичи и сценарии. Даже один тест на доступность — вклад в создание инклюзивного интернета.


ссылка на оригинал статьи https://habr.com/ru/articles/905146/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *