Библиотека Aria-query предназначена для работы с ARIA-ролями, их свойствами и отношениями в контексте веб-разработки и тестирования. Она предоставляет структурированные данные о доступности элементов, что позволяет проверять правильность использования ARIA-атрибутов и предсказывать поведение пользовательских интерфейсов.
Основной экспорт библиотеки — объекты roles и elementRoles:
Пример структуры роли:
import { roles } from 'aria-query';
console.log(roles.get('button'));
/*
{
abstract: false,
accessibleNameRequired: true,
baseConcepts: [{ name: 'button', attributes: [] }],
props: { disabled: null, expanded: null },
childrenPresentational: false
}
*/
Интеграция Aria-query с @testing-library/dom или React Testing Library позволяет создавать тесты, которые проверяют семантическую корректность компонентов. Вместо ручной проверки ARIA-атрибутов можно использовать данные Aria-query для автоматизации.
Функция elementRoles.get(element) возвращает массив
ролей, которые могут быть назначены конкретному DOM-элементу. Это
полезно при тестах, чтобы убедиться, что компонент соответствует
спецификации:
import { elementRoles } from 'aria-query';
import { render } from '@testing-library/react';
const { container } = render();
const button = container.querySelector('button');
console.log(elementRoles.get(button)); // Set { 'button' }
Можно проверять, назначена ли элементу правильная ARIA-роль, основываясь на его типе и свойствах:
import { roles } from 'aria-query';
const expectedRole = 'button';
const actualRoles = elementRoles.get(button);
if (actualRoles.has(expectedRole)) {
console.log('Роль корректна');
} else {
console.warn('Неверная ARIA-роль');
}
Каждая роль содержит список допустимых свойств. Это позволяет написать тесты на корректное использование:
import { roles } from 'aria-query';
const buttonRole = roles.get('button');
console.log(Object.keys(buttonRole.props)); // ['disabled', 'expanded']
Можно сравнивать реальные атрибуты элемента с допустимыми свойствами и выдавать предупреждения, если встречаются невалидные атрибуты:
const invalidProps = Object.keys(button.attributes).filter(attr => !(attr in buttonRole.props));
if (invalidProps.length > 0) {
console.warn('Найдены недопустимые ARIA-атрибуты:', invalidProps);
}
На базе Aria-query можно создавать собственные утилиты для testing-library, которые упрощают проверку доступности:
toHaveValidRole(element) — проверяет, назначена ли
элементу корректная ARIA-роль.toHaveValidAriaProps(element) — проверяет, что атрибуты
соответствуют роли.getRolesForElement(element) — возвращает возможные роли
элемента.Пример кастомного matcher для Jest:
import { elementRoles } from 'aria-query';
expect.extend({
toHaveValidRole(received) {
const rolesSet = elementRoles.get(received);
const pass = rolesSet.size > 0;
return {
pass,
message: () => pass ? 'Элемент имеет корректную роль' : 'Элемент не имеет допустимой роли'
};
}
});
Использование в тесте:
import { render } from '@testing-library/react';
const { container } = render();
const button = container.querySelector('button');
expect(button).toHaveValidRole();
Для компонентов, созданных на React или других библиотеках,
Aria-query позволяет сопоставлять абстрактные роли с реальными
элементами. Это важно для компонентов типа
:
const role = elementRoles.get(customButtonRef.current);
if (role.has('button')) {
// элемент соответствует семантике кнопки
}
Можно автоматически проверять все дочерние элементы на соответствие
ARIA-спецификации, используя roles и
elementRoles.
Aria-query также может применяться для анализа вложенных структур, например, списков, таблиц и композитных виджетов:
childrenPresentational указывает, что дочерние элементы
не влияют на ARIA-контекст.baseConcepts позволяют связывать DOM-элементы с их
семантическими ролями.aria-labelledby и
aria-describedby может быть автоматизирована с помощью
сопоставления с ролями.import { roles, elementRoles } from 'aria-query';
import { render } from '@testing-library/react';
const { container } = render(
- Item 1
- Item 2
);
container.querySelectorAll('li').forEach(li => {
const liRoles = elementRoles.get(li);
const allowedProps = roles.get('listitem').props;
Object.keys(li.attributes).forEach(attr => {
if (!(attr in allowedProps)) {
console.warn(`Недопустимый ARIA-атрибут: ${attr}`);
}
});
});
Такой подход гарантирует, что элементы списка не только имеют корректную роль, но и атрибуты соответствуют спецификации, что повышает доступность интерфейса.