Files
novalon-website/docs/acceptance/2026-09-21-gates/extract-skipped-from-allure.mjs
T
zhangxiang a0328a623f chore(qa): 验收台账与证据入库 + 构建/部署配置同步
- docs/acceptance/qa-tracker.md:跨周期缺陷单一真源台账(§7=第五轮)。
- 周期 1/2 + iPhone SE/axe 验收证据目录、ACCEPTANCE_REVIEW 快照入库。
- 同步 README/CONTEXT/CLAUDE/DESIGN/testing/deployment/lessons-learned 口径;
  next.config/Dockerfile/nginx/Jenkinsfile/docker-compose/sentry/prisma 对齐
  standalone 产物装配与部署形态。
2026-09-28 10:48:09 +08:00

69 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 从 chain6 的 allure-results 里取出「本轮真正跑过的用例」按状态分组,
// 目的:给 ② 的 28 skipped 一份**具名**证据(哪些用例、在哪个 project、以什么理由跳过),
// 而不是只引用汇总行里的计数。汇总计数只能证明「数量」,证明不了「没有把失败洗成跳过」。
import { readdirSync, statSync, readFileSync, writeFileSync } from 'fs';
import { resolve } from 'path';
const DIR = resolve(process.cwd() ?? '.', 'e2e/allure-results');
// chain6 功能阶段:03:52:08Z → 04:20:43Z;视觉阶段紧接其后。留出余量按 UTC 当日 03:50–04:25 过滤。
const FROM = Date.parse('2026-09-22T03:50:00Z');
const TO = Date.parse('2026-09-22T04:25:00Z');
const files = readdirSync(DIR).filter((f) => f.endsWith('-result.json'));
const rows = [];
for (const f of files) {
const p = resolve(DIR, f);
const m = statSync(p).mtimeMs;
if (m < FROM || m > TO) continue;
let j;
try {
j = JSON.parse(readFileSync(p, 'utf8'));
} catch {
continue;
}
const labels = {};
for (const l of j.labels || []) labels[l.name] = l.value;
rows.push({
file: f,
mtime: new Date(m).toISOString(),
status: j.status,
reason: j.statusDetails?.message || j.statusDetails?.trace || '',
project: labels.device || labels.suiteParent || '',
suite: labels.suite || '',
fullName: j.fullName || '',
name: j.name || '',
});
}
const byStatus = {};
for (const r of rows) byStatus[r.status] = (byStatus[r.status] || 0) + 1;
const skipped = rows.filter((r) => r.status === 'skipped').sort((a, b) => (a.fullName + a.project).localeCompare(b.fullName + b.project));
const out = {
generatedAt: new Date().toISOString(),
source: 'e2e/allure-results(chain6 最终代码树 `npm run test` 功能+视觉两阶段的 allure 落盘)',
window: { from: new Date(FROM).toISOString(), to: new Date(TO).toISOString() },
totalResults: rows.length,
byStatus,
skippedCount: skipped.length,
// 按 (suite, reason) 聚合,便于核对「每处 test.skip 条件命中了多少条」
skipTally: Object.entries(
skipped.reduce((acc, r) => {
const k = `${r.suite} :: ${r.reason.slice(0, 80)}`;
acc[k] = (acc[k] || 0) + 1;
return acc;
}, {}),
).map(([k, n]) => ({ group: k, count: n })),
skipped,
};
writeFileSync(
resolve(process.cwd() ?? '.', 'docs/acceptance/2026-09-21-gates/skipped-tests-final-tree.json'),
JSON.stringify(out, null, 2),
);
console.log(`window results=${rows.length} byStatus=${JSON.stringify(byStatus)}`);
console.log(`skipped=${skipped.length}`);
for (const t of out.skipTally) console.log(` x${t.count} ${t.group}`);
const nonPass = rows.filter((r) => r.status !== 'passed' && r.status !== 'skipped');
console.log(`otherNonPassed=${nonPass.length}`);
for (const r of nonPass.slice(0, 10)) console.log(` ${r.status} ${r.project} ${r.fullName} :: ${r.reason.slice(0, 120)}`);