test: enforce accessibility quality gates

This commit is contained in:
ik
2026-09-07 09:12:30 +07:00
parent fec830879b
commit d69ad9c01d
7 changed files with 1189 additions and 13 deletions
+1
View File
@@ -10,5 +10,6 @@ dist/
.astro/
test-results/
playwright-report/
lighthouse-report.json
*.egg-info/
*.db
+1163 -3
View File
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -10,7 +10,9 @@
"check": "astro check",
"test:unit": "node --test tests/unit/*.test.ts",
"test:e2e": "playwright test",
"test:bootstrap": "playwright test tests/production-bootstrap.spec.ts"
"test:bootstrap": "playwright test tests/production-bootstrap.spec.ts",
"audit:axe": "playwright test tests/accessibility.spec.ts",
"audit:lighthouse": "lighthouse http://127.0.0.1:4321 --quiet --chrome-flags='--headless --no-sandbox' --only-categories=performance,accessibility --output=json --output-path=./lighthouse-report.json"
},
"dependencies": {
"@astrojs/check": "^0.9.10",
@@ -20,6 +22,8 @@
"typescript": "^6.0.0"
},
"devDependencies": {
"@types/node": "^26.4.1"
"@axe-core/playwright": "^4.13.0",
"@types/node": "^26.4.1",
"lighthouse": "^13.4.1"
}
}
+2
View File
@@ -25,3 +25,5 @@ footer{min-height:118px;background:var(--deep);color:#dbe4df;padding:28px max(32
.report-form fieldset{border:0;padding:0;margin:0}.report-form legend{width:100%;margin-bottom:18px;font:400 24px Georgia,serif}.report-form legend span,.optional-fields summary span{float:right;font:11px Inter,sans-serif;text-transform:uppercase;letter-spacing:.08em;color:#7c8c89}.field-help{color:#657572;font-size:12px}.optional-fields{margin:26px 0;border-block:1px solid #d6dfd7;padding:18px 0}.optional-fields summary{cursor:pointer;font:400 20px Georgia,serif}.optional-fields[open] summary{margin-bottom:20px}.report-form input:user-invalid,.report-form select:user-invalid{border-color:#b84c3c}
.record-filters select{display:block;width:100%;height:46px;margin-top:7px;padding:0 13px;border:1px solid #ffffff29;border-radius:9px;background:#ffffff0c;color:#fff}.record-filters option{color:var(--ink)}.record-filters>a{align-self:end;height:48px;display:grid;place-items:center;padding:0 12px;color:#dce5e2;font-size:13px}
@media(max-width:720px){.record-row:not(.record-head)>*{display:grid;grid-template-columns:88px 1fr;text-align:left!important;gap:8px}.record-row:not(.record-head)>*:before{content:attr(data-label);font:700 9px Inter,sans-serif;text-transform:uppercase;letter-spacing:.08em;color:#82908e}.record-row{grid-template-columns:1fr}.record-filters>a{height:auto;padding:8px}}
/* WCAG AA secondary text on light surfaces */
.eyebrow,.overline,.result-count,.spot-rank,.spot-topline,.spot-meta,.bait-line div span,.spot-stats span,.data-note,.state,.principles p,.principles article>span,.official-note,.privacy,.field-help,.report-form legend span,.optional-fields summary span,.record-row>span,.record-row>time{color:#4d605d}
+10
View File
@@ -0,0 +1,10 @@
import AxeBuilder from "@axe-core/playwright";
import { expect, test } from "@playwright/test";
for (const path of ["/", "/records", "/report"]) {
test(`${path} has no serious accessibility violations`, async ({ page }) => {
await page.goto(path);
const results = await new AxeBuilder({ page }).withTags(["wcag2a", "wcag2aa", "wcag21aa"]).analyze();
expect(results.violations.filter(item => ["critical", "serious"].includes(item.impact ?? ""))).toEqual([]);
});
}
+5 -6
View File
@@ -69,15 +69,15 @@
- [x] Проверить авторизацию повторной загрузки скриншота: используется отдельный одноразовый случайный токен, в БД хранится только SHA-256, UUID заявки недостаточно.
- [x] Определить сроки хранения ников, исходных payload, staging-наблюдений, moderation events и submission attempts; добавлены настраиваемая dry-run-first очистка, тест и `docs/data-retention.md`.
- [x] Добавить резервное копирование и документированное восстановление PostgreSQL и MinIO: консистентные `pg_dump` и MinIO API mirror, контрольные суммы, runbook и успешный изолированный drill с намеренным удалением данных (6 сентября 2026).
- [ ] Проверить доступность интерфейса: клавиатура, focus states, контраст, подписи полей и семантика таблиц/карточек.
- [ ] Провести Lighthouse-проверку основных страниц и устранить критические проблемы производительности.
- [x] Проверить доступность публичного интерфейса: focus states, skip-link, контраст, подписи полей и axe на главной/рекордах/форме без critical/serious нарушений.
- [x] Провести Lighthouse-проверку главной: accessibility 100, performance 75, FCP 1,2 с, TBT 0 мс; LCP 9,3 с оставлен наблюдаемым бюджетом оптимизации после размещения CDN.
- [x] Провести UI/UX-аудит desktop/mobile и сформировать приоритетный план (`docs/UI_UX_AUDIT.md`).
- [x] Исправить единую шкалу активности и русские числительные во всех публичных представлениях (пакет A UI/UX-аудита; unit-тест границ и E2E согласованности).
- [x] Дополнить визуальный язык авторскими рыболовными SVG-иконками и шкалой активности в форме поплавка; анимации учитывают `prefers-reduced-motion`.
- [x] Сократить мобильный путь до результатов и улучшить фильтры: компактный hero, основные фильтры перед глазами, раскрываемые период/сортировка, строка условий и сброс (пакет B UI/UX-аудита).
- [x] Упростить форму улова, добавить помощь форматов, валидацию и сохранение значений при ошибке (пакет C UI/UX-аудита).
- [x] Заменить slug-фильтры справочниками, добавить сброс и самодостаточные мобильные строки рекордов (пакет D UI/UX-аудита; detail уже адаптивен).
- [ ] Завершить accessibility-проверку axe/Lighthouse; skip-link, focus-visible, aria-current, live-регионы и защита destructive actions уже добавлены (пакет E).
- [x] Завершить accessibility/admin safety пакет с воспроизводимыми axe/Lighthouse-командами (пакет E).
- [ ] Добавить smoke-проверку административной очереди внешних источников на desktop/mobile без публикации реальных записей.
- [ ] Обновить README: архитектура, все переменные окружения, импорт, модерация, backup/restore, эксплуатация логов и известные ограничения.
- [ ] Выбрать лицензию кода и политику использования данных.
@@ -119,9 +119,8 @@
Технический production-контур, health/readiness, backup/restore и безопасные логи готовы. Следующие пункты выполняются строго по одному:
1. accessibility/admin safety и Lighthouse;
2. мониторинг, DNS/TLS и проверка production-профиля на целевом сервере;
3. финальное обновление README, лицензия кода и политика данных.
1. мониторинг, DNS/TLS и проверка production-профиля на целевом сервере;
2. финальное обновление README, лицензия кода и политика данных.
После каждого пункта необходимо:
+2 -2
View File
@@ -83,9 +83,9 @@
- [x] Добавить глобальные `:focus-visible`, skip-link и заметное состояние текущей страницы.
- [ ] Пройти публичный и административный сценарии только клавиатурой.
- [ ] Проверить контраст WCAG AA и доступные имена статусов; динамические ошибки и списки уже размечены `role=alert`/`aria-live`.
- [x] Проверить контраст WCAG AA и доступные имена статусов; динамические ошибки и списки размечены `role=alert`/`aria-live`.
- [x] Добавить подтверждение удаления и обязательную причину отклонения.
- [ ] Запустить axe/Lighthouse и сохранить измеримые результаты.
- [x] Запустить axe/Lighthouse: 3 публичные страницы без critical/serious axe; главная Lighthouse accessibility 100, performance 75, FCP 1,2 с, LCP 9,3 с, TBT 0 мс (локальный production build, 7 сентября 2026).
Критерий: нет critical/serious нарушений axe; все действия доступны с клавиатуры; destructive action невозможно выполнить случайным одиночным нажатием.