feat(web-test): auto-suite + severity-резолвер для Allure

run.mjs:
- buildSeverityIndex(config) — валидация config.severity (inverted map
  «уровень → [теги]») при загрузке: ключи только из blocker|critical|
  normal|minor|trivial, теги не дублируются между bucket'ами,
  defaultSeverity тоже валидируется. fail-fast через die.
- resolveSeverity(t, severityIndex):
  1. mod.severity если задан и валидный — выигрывает.
  2. max-rank среди тегов (стандартные имена severity или маппинг).
  3. config.defaultSeverity или 'normal'.
  Rank: blocker(5) > critical(4) > normal(3) > minor(2) > trivial(1).
  Max-wins инвариантен к порядку тегов.
- writeAllure: добавлены labels suite (= dirname(t.file) или 'root') +
  severity. Тег `tag` остался как раньше.
- testResult пробрасывает t.severity (для passed/failed веток).
- SEVERITY_RANK/LEVELS объявлены в модульной шапке (top-level await на
  cmdTest начинается до конца тела модуля, TDZ-аккуратность).

webtest.config.mjs: severity policy для нашего сьюта (smoke +
multi-context → critical, recording → minor, defaultSeverity = normal).

spec.md §7: раздел про severity-policy в конфиге с валидацией.
spec.md §9: «Авто-эмиссия label-ов» — tag/suite/severity + правила резолва.

Регресс 19/19 ✓ (9m 7.6s). Распределение по уровням после исправления
'record' → 'recording' в маппинге: 13 critical / 5 normal / 1 minor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-13 18:37:58 +03:00
parent a55195ab66
commit fc76407877
3 changed files with 133 additions and 5 deletions
+13
View File
@@ -20,4 +20,17 @@ export default {
// isolation: 'window' — separate BrowserContext per slot, full cookie isolation,
// extension may not load (Playwright limitation). Use only when really needed.
timeout: 60000,
// Allure severity policy: inverted map "уровень → теги, попадающие в этот уровень".
// Резолв (run.mjs:resolveSeverity):
// 1. explicit `export const severity` в тесте — выигрывает всегда;
// 2. иначе max-rank среди тегов теста (стандартное имя severity или маппинг ниже);
// 3. иначе `defaultSeverity`.
// Тег не может быть в двух bucket'ах одновременно — валидация при загрузке конфига.
severity: {
critical: ['smoke', 'multi-context'],
minor: ['recording'],
// blocker / trivial — пустые, не используем
},
defaultSeverity: 'normal',
};