3 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9588d03bf4 |
test(s15): axe a11y + focus traps + unit coverage 80% + property tests + backup drill
Sprint 15 финальный — реальные axe + coverage + pg_restore numbers.
Ключевые цифры:
- axe-core: critical=0 on 10 страниц stage'а; serious 12→9
после фиксов (sidebar contrast + 8 icon-only back-arrow aria-labels).
- Unit coverage: Application 56%→83%, Domain 11%→79%, combined
60%→80%. Тестов 68→147 (+79).
- Backup recovery drill: RTO ~25 секунд end-to-end
(pg_dump 2s + pg_restore 4s + dotnet startup 19s).
Что сделано:
1. @axe-core/playwright + stage-ui-15 (10 страниц) + stage-ui-16
(SR smoke на login: getByLabel, role=alert, aria-describedby,
keyboard nav).
2. useFocusTrap hook (WCAG 2.4.3 + 2.1.2): return-focus, mount-focus,
Tab cycle. Подключён к Modal + ConfirmDialog с opt-in
defaultFocus='cancel'|'confirm'. ConfirmDialog по дефолту фокусит
Cancel для destructive actions (safer чем Enter→Delete).
3. A11y фиксы:
• text-slate-400→text-slate-500 в sidebar (contrast 2.63→4.61).
• 8 страниц edit с back-arrow Link — aria-label + aria-hidden
на иконке + текст-slate-500 цвет.
• Modal close button — то же.
• LoginPage — aria-invalid/aria-describedby/role=alert на
ошибках валидации.
• Field component — role="alert" на error span (announce'ит SR).
4. 8 файлов unit-тестов: PhoneNormalization, PagedRequest,
RequiredGuid, RolePermissions (Domain), DomainPocoSmoke,
DomainFullPropertyTouch, CatalogDtosSmoke, StockServiceProperty
(4 seeds × 4 size + batch + 2-product isolation).
5. Backup-drill: pg_dump со stage'а → fresh postgres:16-alpine →
pg_restore → dotnet run против восстановленной БД → /health/ready
Healthy. Команды и timing в RUNBOOK.md.
6. Docs review:
• MULTI-TENANCY чеклист «добавить tenant-сущность» расширен с 6
до 19 шагов (Domain → EF Config → Migration с Xmin →
RolePermissions → Validation → Controller + RequiresPermission →
Audit + SensitiveOpsAudit → property tests).
• ARCHITECTURE.md — Sprint 13-15 changes таблица.
• DEVELOPER-GUIDE.md — «что добавилось после первого guide'а» +
a11y pitfalls в «что НЕ делать».
Stage smoke ✓. Это финальный автономно-безопасный спринт. Дальше
нужен вход от user'а (ОФД keys, MoySklad tokens, Windows для POS,
прод-деплой план, kz-перевод, реальный SMTP).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
eb867697d0 |
test(ui-deep): setup + Item 1 — signup flow (5 specs)
Some checks are pending
Sprint UI-deep, пункт 1: реальный Chromium через Playwright Test.
Установлены @playwright/test 1.60.0 и otplib (для item 11).
Конфиг tests/e2e/playwright.config.ts — workers=1, traces+screenshots
on-failure, screenshot dir reports/playwright-artifacts/.
Хелперы tests/e2e/lib/ui.ts:
- apiSignup() — быстрый signup через API + login
- attachSession() — кладёт access_token в localStorage, грузит путь
- watchPage() — listener console-errors и network 4xx/5xx
- expectNoErrors() — assert после flow'a
Item 1 (5 specs, все ✓ на стейдже):
- 1.1 attach session → /dashboard, без console-ошибок
- 1.2 создание товара через UI (Empty CTA → форма → Сохранить)
- 1.3 первый контрагент через Modal
- 1.4 создать товар + контрагент через API, открыть форму приёмки,
smoke на компоненты страницы
- 1.5 OnboardingPage (/) рендерится
Найден 1 реальный баг → починен:
- ProductEditPage: race на currencies.data — если быстро Сохранить,
цена-MoneyInput добавляет строку с currencyId='' → server 400 с
криптичным JSON validation. Фикс: MoneyInput disabled пока
!currencies.data + canSave проверяет row.currencyId.
- Form error display показывал "Request failed with status code 400";
теперь использует общий humanizeError() (exporting из @/lib/api).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
7bb941259a |
feat(e2e): infrastructure + first full-cycle scenario + baseline report
Декларативные end-to-end сценарии в tests/e2e/. YAML описывает шаги, TypeScript-handler — конкретные API/UI/DB-проверки. Отчёт в Markdown. Структура: - runner.ts : entry, парсит YAML, прогоняет steps, пишет report - run.sh : pnpm install + tsx - lib/api.ts : axios + login() (через /connect/token + /api/me) - lib/db.ts : docker exec psql, resetTenantData(), countRows() - lib/report.ts : Markdown-аккумулятор (steps + bugs + ux + gap + perf) - scenarios/full-cycle.yml : 12 шагов - scenarios/full-cycle.steps.ts : handlers (один на шаг) - README.md : как добавить новый сценарий reset_db в preconditions: - TRUNCATE tenant-таблиц CASCADE - AspNet*/users — оставляем только admin@food-market.local - OpenIddict tokens — все valid → revoked - Реестр products + системные справочники + миграции + platform_settings — НЕ трогаем Запуск: tests/e2e/run.sh full-cycle [--api-only] Первый прогон (--api-only, baseline в reports/full-cycle-2026-05-07-baseline.md): - 8 ✓ / 1 ✗ / 3 ◯ из 12. - Critical bug: Cashier видит /api/organization/employees через API (нет [Authorize(Roles="Admin")] на List endpoint). - High: при CreateOrg через SuperAdmin не сидируются tenant-units — пустой каталог измерений у новой org (DevDataSeeder.SeedTenantReferencesAsync должен вызываться, но не вызывается). - Logic gaps: реестр products tenant-scoped и новая org стартует с пустым каталогом; SuperAdmin /organizations не валидирует ФЛК телефона; Cashier не получает Identity-роль "Cashier" при создании через /employees. UI-шаги (Playwright) в этом коммите не покрыты — runner работает в --api-only режиме. UI-extension добавим следующим коммитом, не блокирует получение полезного отчёта. |