Доступность компонентов календаря Pikaday проверяется через сочетание автоматизированных и ручных подходов, охватывающих семантику разметки, работу с клавиатурой, взаимодействие со скринридерами и корректность ARIA-атрибутов в различных сценариях использования.
Основой доступности календаря выступает корректная HTML-структура, на
которую опираются вспомогательные технологии. В Pikaday важно, чтобы
интерактивные элементы календарной сетки не представлялись как
произвольные div без семантического контекста.
Ключевые аспекты:
<button>) для дней месяца
вместо кликабельных блоковАвтоматизированная проверка часто начинается с анализа DOM через тестовые утилиты, которые проверяют наличие кнопок и отсутствие запрещённых паттернов:
import { render } from '@testing-library/dom';
test('days are rendered as buttons', () => {
document.body.innerHTML = `
<div class="pika-single">
<button class="pika-day">1</button>
<button class="pika-day">2</button>
</div>
`;
const days = document.querySelectorAll('.pika-day');
days.forEach(day => {
expect(day.tagName.toLowerCase()).toBe('button');
});
});
ARIA-атрибуты в Pikaday обеспечивают связь между визуальной и семантической моделью календаря. Проверка доступности включает в себя контроль правильности ролей и состояний.
Основные элементы проверки:
aria-label у кнопок днейaria-selected для выбранной датыaria-disabled для недоступных датrole="grid" или аналогичная структура для контейнера
календаряТипичная ошибка — отсутствие описания текущего состояния фокуса или выбранной даты, что приводит к потере контекста для скринридеров.
Пример теста на ARIA:
test('selected date has aria-selected true', () => {
const selected = document.querySelector('.is-selected');
expect(selected.getAttribute('aria-selected')).toBe('true');
});
Особое внимание уделяется динамическому обновлению ARIA-состояний при смене месяца и выборе даты, поскольку именно здесь часто возникают рассинхронизации между визуальным и доступным состоянием.
Календарь Pikaday должен полноценно управляться клавиатурой без использования мыши. Проверка включает сценарии перемещения по сетке дат и управление фокусом.
Основные клавиши:
Автоматизированное тестирование клавиатуры часто реализуется через имитацию событий:
test('arrow right moves focus to next day', () => {
const firstDay = document.querySelector('.pika-day');
firstDay.focus();
firstDay.dispatchEvent(new KeyboardEvent('keydown', {
key: 'ArrowRight',
bubbles: true
}));
const focused = document.activeElement;
expect(focused.textContent).toBe('2');
});
Особое внимание уделяется сохранению логики фокуса при смене месяца: фокус не должен теряться или сбрасываться в начало документа.
Тестирование с помощью скринридеров выявляет проблемы, которые невозможно обнаружить только через DOM или автоматические проверки.
Ключевые сценарии:
Типичная ошибка — отсутствие контекстной информации при переходе между месяцами. Например, скринридер должен озвучивать «Март 2026», а не просто набор чисел.
Для ручной проверки используется последовательное прохождение календаря в режиме:
Проблемные зоны фиксируются при потере контекста или повторяющихся неинформативных объявлениях.
Инструменты вроде axe-core позволяют выявлять базовые нарушения доступности без ручного анализа.
Типичные проверки:
Пример интеграции axe-core в тесты:
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('no accessibility violations in calendar', async () => {
document.body.innerHTML = `<div class="pika-single"></div>`;
const results = await axe(document.body);
expect(results).toHaveNoViolations();
});
Однако такие инструменты не покрывают поведенческую доступность, особенно связанную с клавиатурной навигацией и логикой фокуса.
Фокус в Pikaday является критическим элементом доступности. Проверка включает:
Типичная модель поведения:
test('focus returns to input after close', () => {
const input = document.querySelector('input');
const calendar = document.querySelector('.pika-single');
input.focus();
// открытие календаря
calendar.classList.add('is-open');
// закрытие календаря
calendar.classList.remove('is-open');
expect(document.activeElement).toBe(input);
});
Ошибки в управлении фокусом особенно критичны для пользователей скринридеров, так как приводят к «зависанию» навигации.
Pikaday активно изменяет DOM при переключении месяцев, выборе дат и применении ограничений. Тестирование должно учитывать:
Особое внимание уделяется производительности обновлений, так как чрезмерный ре-рендер может приводить к сбросу фокуса.
Интеграционные тесты через Cypress или Playwright позволяют проверить поведение календаря в реальной среде.
Пример сценария:
it('selects date via keyboard', () => {
cy.get('input').focus();
cy.get('.pika-single').should('be.visible');
cy.get('.pika-day').first().focus();
cy.focused().type('{rightarrow}{enter}');
cy.get('input').should('have.value');
});
Такие тесты выявляют расхождения между эмуляцией DOM-событий и реальным поведением браузера.
Хотя Pikaday является функциональным компонентом, визуальная доступность напрямую влияет на восприятие интерфейса.
Проверяются:
Инструменты автоматизации (Lighthouse, axe) дают первичную оценку, но визуальные регрессии часто требуют ручной проверки или snapshot-тестов.
При изменениях в логике календаря важно отслеживать, не нарушается ли доступность.
Подходы:
Особенно чувствительны изменения, связанные с:
div вместо кнопок для днейaria-label у датЭти ошибки часто проявляются только при комбинированном тестировании, когда автоматические и ручные методы используются совместно.
Полноценное тестирование доступности Pikaday строится слоями:
Каждый слой закрывает отдельный класс проблем, и только их совокупность обеспечивает стабильную доступность компонента в различных условиях использования.