Color contrast проверки

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('Обнаружены нарушения цветового контраста');
      }
    });
  });
});

Прямое тестирование контраста с помощью Cypress

После подключения 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() запускает проверку доступности и фильтрует ошибки по контрасту.
  • Можно проверять весь документ или конкретные элементы, передавая их в функцию.

Проверка контраста через CSS-свойства

В некоторых случаях может потребоваться более низкоуровневая проверка контраста, без 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.

Интеграция с CI/CD

Проверки контраста можно запускать в автоматизированных пайплайнах. Важно, чтобы тесты выдавали явные ошибки при нарушении контраста:

# Пример для 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 пайплайн завершится с ошибкой.


Советы по эффективной проверке контраста

  • Проверять не только видимый текст, но и элементы интерфейса, содержащие текст поверх картинок или градиентов.
  • Использовать комбинацию axe-core и собственного скрипта для точного контроля.
  • Автоматизировать тестирование при каждом изменении UI, чтобы своевременно выявлять нарушения доступности.
  • Для динамически меняющихся цветов применять проверку сразу после рендера компонентов.

Эти подходы позволяют обеспечить соответствие сайта стандартам доступности, повысить читаемость интерфейса и предотвратить потенциальные UX-проблемы.