Color contrast проверки являются важной частью тестирования доступности веб-приложений. Низкая контрастность текста относительно фона снижает читаемость и может нарушать стандарты WCAG (Web Content Accessibility Guidelines). Cypress позволяет автоматизировать эти проверки, интегрируя проверку контраста в E2E-тесты.
Для проверки цветового контраста обычно используются библиотеки
cypress-axe и axe-core. axe-core
предоставляет мощные API для анализа доступности страницы, включая
проверку контраста текста. Установка осуществляется через npm:
npm install cypress-axe --save-dev
Подключение в файле cypress/support/commands.js:
import 'cypress-axe';
Cypress.Commands.add('injectAxe', () => {
cy.window({ log: false }).then((win) => {
const script = win.document.createElement('script');
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.7.2/axe.min.js';
win.document.head.appendChild(script);
});
});
Cypress.Commands.add('checkA11y', (context = null, options = null) => {
cy.window({ log: false }).then((win) => {
win.axe.run(context || win.document, options || {}, (err, results) => {
if (err) throw err;
const violations = results.violations.filter(v => v.id === 'color-contrast');
if (violations.length > 0) {
violations.forEach(v => {
console.error(`Нарушение контраста: ${v.description}`, v.nodes);
});
throw new Error('Обнаружены нарушения цветового контраста');
}
});
});
});
После подключения axe-core можно выполнять проверки в тестах. Пример:
describe('Color contrast accessibility tests', () => {
beforeEach(() => {
cy.visit('/home');
cy.injectAxe();
});
it('Проверка контраста текста на главной странице', () => {
cy.checkA11y();
});
it('Проверка контраста для конкретного блока', () => {
cy.get('.main-content').then(($el) => {
cy.checkA11y($el[0]);
});
});
});
Ключевые моменты:
cy.injectAxe() вставляет библиотеку axe-core в DOM
страницы.cy.checkA11y() запускает проверку доступности и
фильтрует ошибки по контрасту.В некоторых случаях может потребоваться более низкоуровневая проверка контраста, без axe-core, непосредственно анализируя цвета элементов:
function luminance(rgb) {
const a = rgb.map((v) => {
v /= 255;
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055)/1.055, 2.4);
});
return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];
}
function contrast(rgb1, rgb2) {
const lum1 = luminance(rgb1);
const lum2 = luminance(rgb2);
return (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05);
}
Cypress.Commands.add('checkContrast', (selector, minRatio = 4.5) => {
cy.get(selector).then($el => {
const el = $el[0];
const style = getComputedStyle(el);
const fg = style.color.match(/\d+/g).map(Number);
const bg = style.backgroundColor.match(/\d+/g).map(Number);
const ratio = contrast(fg, bg);
expect(ratio, `Контраст для ${selector}`).to.be.gte(minRatio);
});
});
Пример использования:
it('Проверка контраста кнопки', () => {
cy.visit('/home');
cy.checkContrast('.btn-primary');
});
Особенности:
minRatio соответствует минимальному коэффициенту
контраста WCAG 2.1 (4.5 для обычного текста, 3 для крупного
текста).luminance и contrast рассчитывают
восприятие цвета человеческим глазом по стандарту WCAG.Проверки контраста можно запускать в автоматизированных пайплайнах. Важно, чтобы тесты выдавали явные ошибки при нарушении контраста:
# Пример для GitHub Actions
name: Cypress Tests
on: [push, pull_request]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npx cypress run
Проверки контраста встроены в Cypress-тесты, поэтому при нарушении стандартов WCAG пайплайн завершится с ошибкой.
Эти подходы позволяют обеспечить соответствие сайта стандартам доступности, повысить читаемость интерфейса и предотвратить потенциальные UX-проблемы.