Логирование работы с библиотекой

Для работы с aria-query необходимо установить библиотеку через npm:

npm install aria-query

Подключение в проекте выглядит следующим образом:

const ariaQuery = require('aria-query');

или при использовании современных модулей ES:

import { roles, elements } from 'aria-query';

aria-query предоставляет два основных объекта: roles и elements. roles содержит информацию о ролях ARIA и их свойствах, а elements — соответствие между HTML-элементами и ролями ARIA.


Основные структуры данных

Roles

Объект roles представляет собой карту, где ключ — название ARIA-роли, а значение — объект с детальной информацией о свойствах роли:

console.log(roles.get('button'));

Вывод будет содержать:

  • abstract — указывает, является ли роль абстрактной (не предназначена для прямого использования в HTML).
  • nameFrom — список источников имени для роли (author, contents, label, placeholder).
  • props — свойства роли и их поддерживаемые значения.
  • requiredContextRole — роли, которые должны присутствовать в родительском элементе.

Пример доступа к свойствам роли:

const buttonRole = roles.get('button');
console.log(buttonRole.props['aria-pressed']); // true, false или undefined

Elements

elements представляет собой карту соответствий HTML-тегов и их возможных ARIA-ролей:

console.log(elements.get('a'));

Каждое значение содержит:

  • roles — список ролей, назначаемых элементу по умолчанию.
  • attributes — список ARIA-атрибутов, допустимых для данного элемента.
  • name — способ определения имени элемента (author или contents).

Пример фильтрации элементов по роли:

const buttonElements = Array.from(elements.entries())
  .filter(([tag, data]) => data.roles.has('button'))
  .map(([tag]) => tag);

console.log(buttonElements); // ['button', 'input', 'a', ...]

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

Использование aria-query позволяет проверять, допустим ли определённый ARIA-атрибут для конкретной роли:

const role = roles.get('checkbox');
console.log(role.props['aria-checked']); // true
console.log(role.props['aria-expanded']); // undefined

Это особенно полезно при валидации динамически генерируемых интерфейсов.


Логирование информации о ролях

Для целей отладки и ведения логов можно формировать структурированные сообщения:

function logRoleInfo(roleName) {
  const role = roles.get(roleName);
  if (!role) {
    console.warn(`Роль ${roleName} не найдена`);
    return;
  }

  console.group(`Информация о роли: ${roleName}`);
  console.log('Абстрактная:', role.abstract);
  console.log('Источник имени:', role.nameFrom);
  console.log('Допустимые свойства:', Object.keys(role.props));
  console.log('Необходимые родительские роли:', role.requiredContextRole || 'нет');
  console.groupEnd();
}

logRoleInfo('button');
logRoleInfo('checkbox');

Использование console.group и console.groupEnd позволяет структурировать лог, делая его более читаемым при больших объёмах данных.


Логирование информации о элементах

Для элементов HTML полезно вывести все роли и доступные атрибуты:

function logElementInfo(tagName) {
  const element = elements.get(tagName);
  if (!element) {
    console.warn(`Элемент ${tagName} не найден`);
    return;
  }

  console.group(`Информация о элементе: <${tagName}>`);
  console.log('Роли по умолчанию:', Array.from(element.roles));
  console.log('Поддерживаемые ARIA-атрибуты:', Array.from(element.attributes));
  console.log('Источник имени:', element.name);
  console.groupEnd();
}

logElementInfo('button');
logElementInfo('a');

Такое логирование помогает выявлять несоответствия между ожидаемыми и фактическими ролями.


Пример интеграции с системой логирования

Для больших приложений удобно подключить логирование к внешней системе, например winston или pino:

import winston from 'winston';

const logger = winston.createLogger({
  level: 'info',
  transports: [
    new winston.transports.Console({ format: winston.format.simple() }),
  ],
});

function logRoleWithLogger(roleName) {
  const role = roles.get(roleName);
  if (!role) return logger.warn(`Роль ${roleName} не найдена`);
  
  logger.info(`Роль: ${roleName}`);
  logger.info(`Абстрактная: ${role.abstract}`);
  logger.info(`Источник имени: ${role.nameFrom}`);
  logger.info(`Допустимые свойства: ${Object.keys(role.props).join(', ')}`);
}

Фильтрация и проверка доступных ролей

aria-query позволяет программно проверять, какие роли поддерживаются в проекте:

const interactiveRoles = Array.from(roles.entries())
  .filter(([name, data]) => !data.abstract && data.props['aria-pressed'] !== undefined)
  .map(([name]) => name);

console.log(interactiveRoles); // ['button', 'menuitem', 'switch', ...]

Это упрощает автоматическую генерацию ARIA-компонентов и проверку их корректности.


Использование в тестах

Для юнит-тестов или интеграционных тестов можно использовать aria-query для проверки соответствия ролей и атрибутов:

import { expect } from 'chai';

const button = roles.get('button');

expect(button.props['aria-pressed']).to.not.be.undefined;
expect(button.abstract).to.equal(false);

Такой подход повышает надежность интерфейсов с точки зрения доступности.


Динамическое логирование при рендере

В приложениях на React или Vue можно добавлять логирование ролей при рендере компонентов:

function logElementRoles(element) {
  const data = elements.get(element.tagName.toLowerCase());
  if (!data) return;
  console.info(`Элемент <${element.tagName.toLowerCase()}> использует роли: ${Array.from(data.roles).join(', ')}`);
}

// Пример использования в React
useEffect(() => {
  const button = document.querySelector('button');
  logElementRoles(button);
}, []);

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


Расширение функционала

Библиотеку можно использовать для построения собственных утилит:

  • Автоматическая генерация документации по ролям.
  • Валидация DOM-структуры на предмет доступности.
  • Инструменты анализа компонентов и их ARIA-совместимости.

aria-query предоставляет фундамент для создания сложных систем, где доступность интерфейса контролируется программно и централизованно.