feat: P2 分发 + P3 CI(含三个实测发现的缺陷修复)
执行 ROADMAP 的 S1-P2(npm 分发)与 S1-P3(CI 回归)。
P3 · CI 回归流水线
- .github/workflows/regression.yml:push/PR 自动跑回归,失败阻断
含 playwright 浏览器缓存、零依赖自检、服务就绪轮询、报告上传、
GitHub Step Summary 输出
- tools/run-regression.mjs 重构:
· 路径基于脚本位置(不再依赖 cwd,CI 更稳)
· 环境自检:服务未起退出码 2、playwright 缺失退出码 2
· 断言超时后重试一次(吸取 _collect.html 的偶发教训)
· 超时与断言失败分开统计(timedOut 字段)
· 失败时打印明细并 exit 1,全部通过 exit 0
P2 · npm 分发
- package.json:aurora-admin-design,dependencies 为空(零运行时依赖铁律)
playwright 放 devDependencies(CI 专用)
- tools/build-dist.mjs:零依赖构建脚本,产出 dist/
tokens/{tokens.css,tokens.json(DTCG),figma.json}
components/{<slug>.css ×79, index.css 聚合, <slug>.html ×79}
manifest.json(含 SHA 校验和) + README.md
- .npmignore / .gitignore 更新(dist/ node_modules/ 不入库)
- npm pack 实测:115.9 KB 压缩 / 566 KB 解压 / 167 文件 / 无 site|tests 泄漏
实测发现的三个缺陷(全部修复)
1. package.json 加 "type": "module" 会让 site/dev-server.js(CJS)崩溃
—— 移除该字段,靠 .mjs 扩展名区分模块系统
2. dist 里 HTML 引用 ../tokens/colors_and_type.css 但产物是 tokens.css
—— 路径对但文件不存在,产物是坏的。重写全部引用规则
(含 index.css 的 @import 从 ./tokens/ 改为 ../tokens/)
3. 断言总数不确定:icon-contrast 是条件性推入(依赖渲染时机),
导致同一页不同次运行总数不同(960 vs 961)
—— 改为恒定输出一条(无问题=pass,有问题=skip),
断言数从 960 稳定为 1038,连跑两次完全一致
4. 顺带修 na 与 skip 重复计算(na = total - denom,但 skip 已是同一批)
—— 统一为 na = skip,算术自洽:pass+fail+skip = total
验证
- runner:passRate 100% | 79 页全通过 | 1003/1003 | N/A 35 | exit 0
- collector:完全同口径(total 1038 / pass 1003 / fail 0 / skip 35)
- dist:79/79 页面浏览器实测正常(令牌解析、无加载失败)
- 连跑两次数字完全一致(可复现)
This commit is contained in:
+2
-1
@@ -153,7 +153,8 @@ pre#out { background: var(--au-color-card-bg); border: 1px solid var(--au-color-
|
||||
pages: results.length,
|
||||
pagesAllPass: results.filter(function (r) { return r.fail === 0 && r.total > 0; }).length,
|
||||
passRate: denom ? Math.round(passAssert / denom * 1000) / 10 : 0,
|
||||
assertions: { total: totalAssert, pass: passAssert, fail: failAssert, skip: skipAssert, na: totalAssert - denom },
|
||||
/* na 与 skip 是同一批,不重复计算 */
|
||||
assertions: { total: totalAssert, pass: passAssert, fail: failAssert, skip: skipAssert, na: skipAssert },
|
||||
failureKinds: kinds,
|
||||
/* 两次重试后仍无响应的页面:属采集环境问题(并发抢占),与断言失败分开统计 */
|
||||
timedOut: results.filter(function (r) { return (r.failures || []).indexOf('timeout') >= 0; }).map(function (r) { return r.slug; }),
|
||||
|
||||
+7
-1
@@ -445,7 +445,13 @@
|
||||
}
|
||||
});
|
||||
add('contrast>=4.5', contrastFailures.length === 0, contrastFailures.length ? '低于 WCAG AA:' + contrastFailures.join(';') : null);
|
||||
if (iconWarnings.length) list.push({ id: 'matrix:icon-contrast', status: 'skip', ms: 0, err: '图标低于 3:1(非阻塞):' + iconWarnings.join(';') });
|
||||
/* 图标对比度:恒定输出一条,避免断言总数随渲染时机浮动
|
||||
(此前仅在检出图标对比度不足时才推入 skip,导致同一页不同次运行的总数不同,
|
||||
对 CI 是不可接受的 —— 报告数字必须可复现)。
|
||||
status 语义:无问题 = pass;有问题 = skip(WCAG 1.4.11 非阻塞)。 */
|
||||
list.push(iconWarnings.length
|
||||
? { id: 'matrix:icon-contrast', status: 'skip', ms: 0, err: '图标低于 3:1(非阻塞):' + iconWarnings.join(';') }
|
||||
: { id: 'matrix:icon-contrast', status: 'pass', ms: 0, err: null });
|
||||
|
||||
/* token 一致性:用例区内联 hex 颜色。
|
||||
排除「数据驱动的颜色」——色板选项、轮播卡片背景、图表数据系列等,
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuite name="aurora-admin tests" tests="79" failures="0" time="0">
|
||||
<testcase name="tests/button" time="0"></testcase>
|
||||
<testcase name="tests/input" time="0"></testcase>
|
||||
<testcase name="tests/select" time="0"></testcase>
|
||||
<testcase name="tests/table" time="0"></testcase>
|
||||
<testcase name="tests/card" time="0"></testcase>
|
||||
<testcase name="tests/modal" time="0"></testcase>
|
||||
<testcase name="tests/tag" time="0"></testcase>
|
||||
<testcase name="tests/tabs" time="0"></testcase>
|
||||
<testcase name="tests/steps" time="0"></testcase>
|
||||
<testcase name="tests/breadcrumb" time="0"></testcase>
|
||||
<testcase name="tests/tree" time="0"></testcase>
|
||||
<testcase name="tests/dropdown" time="0"></testcase>
|
||||
<testcase name="tests/popconfirm" time="0"></testcase>
|
||||
<testcase name="tests/segmented" time="0"></testcase>
|
||||
<testcase name="tests/transfer" time="0"></testcase>
|
||||
<testcase name="tests/rate" time="0"></testcase>
|
||||
<testcase name="tests/slider" time="0"></testcase>
|
||||
<testcase name="tests/mention" time="0"></testcase>
|
||||
<testcase name="tests/autocomplete" time="0"></testcase>
|
||||
<testcase name="tests/collapse" time="0"></testcase>
|
||||
<testcase name="tests/calendar" time="0"></testcase>
|
||||
<testcase name="tests/carousel" time="0"></testcase>
|
||||
<testcase name="tests/imagepreview" time="0"></testcase>
|
||||
<testcase name="tests/qrcode" time="0"></testcase>
|
||||
<testcase name="tests/countdown" time="0"></testcase>
|
||||
<testcase name="tests/watermark" time="0"></testcase>
|
||||
<testcase name="tests/cardlist" time="0"></testcase>
|
||||
<testcase name="tests/shortcutpanel" time="0"></testcase>
|
||||
<testcase name="tests/bankcardinput" time="0"></testcase>
|
||||
<testcase name="tests/idcardinput" time="0"></testcase>
|
||||
<testcase name="tests/plateinput" time="0"></testcase>
|
||||
<testcase name="tests/bottomsheet" time="0"></testcase>
|
||||
<testcase name="tests/treetable" time="0"></testcase>
|
||||
<testcase name="tests/expandabletable" time="0"></testcase>
|
||||
<testcase name="tests/mergedcelltable" time="0"></testcase>
|
||||
<testcase name="tests/summaryrowtable" time="0"></testcase>
|
||||
<testcase name="tests/fixedcolumntable" time="0"></testcase>
|
||||
<testcase name="tests/timelinelist" time="0"></testcase>
|
||||
<testcase name="tests/steplist" time="0"></testcase>
|
||||
<testcase name="tests/chartpanel" time="0"></testcase>
|
||||
<testcase name="tests/dashboardcard" time="0"></testcase>
|
||||
<testcase name="tests/enhancedtabnav" time="0"></testcase>
|
||||
<testcase name="tests/sidemenu" time="0"></testcase>
|
||||
<testcase name="tests/topmenu" time="0"></testcase>
|
||||
<testcase name="tests/mixednavigation" time="0"></testcase>
|
||||
<testcase name="tests/quicknav" time="0"></testcase>
|
||||
<testcase name="tests/anchornav" time="0"></testcase>
|
||||
<testcase name="tests/backtotop" time="0"></testcase>
|
||||
<testcase name="tests/pagetransition" time="0"></testcase>
|
||||
<testcase name="tests/buttongroup" time="0"></testcase>
|
||||
<testcase name="tests/radiocard" time="0"></testcase>
|
||||
<testcase name="tests/checkboxcard" time="0"></testcase>
|
||||
<testcase name="tests/listpicker" time="0"></testcase>
|
||||
<testcase name="tests/cascader" time="0"></testcase>
|
||||
<testcase name="tests/colorpicker" time="0"></testcase>
|
||||
<testcase name="tests/rangequickpicker" time="0"></testcase>
|
||||
<testcase name="tests/numberrangeinput" time="0"></testcase>
|
||||
<testcase name="tests/switchgroup" time="0"></testcase>
|
||||
<testcase name="tests/dragupload" time="0"></testcase>
|
||||
<testcase name="tests/signaturepad" time="0"></testcase>
|
||||
<testcase name="tests/codeinput" time="0"></testcase>
|
||||
<testcase name="tests/passwordinput" time="0"></testcase>
|
||||
<testcase name="tests/phoneinput" time="0"></testcase>
|
||||
<testcase name="tests/messagepro" time="0"></testcase>
|
||||
<testcase name="tests/notificationpro" time="0"></testcase>
|
||||
<testcase name="tests/progressvariants" time="0"></testcase>
|
||||
<testcase name="tests/skeletonpro" time="0"></testcase>
|
||||
<testcase name="tests/emptypro" time="0"></testcase>
|
||||
<testcase name="tests/loadingoverlay" time="0"></testcase>
|
||||
<testcase name="tests/resultvariants" time="0"></testcase>
|
||||
<testcase name="tests/exceptionvariants" time="0"></testcase>
|
||||
<testcase name="tests/confirmmodal" time="0"></testcase>
|
||||
<testcase name="tests/alertmodal" time="0"></testcase>
|
||||
<testcase name="tests/formmodal" time="0"></testcase>
|
||||
<testcase name="tests/fullscreenmodal" time="0"></testcase>
|
||||
<testcase name="tests/themeswitcher" time="0"></testcase>
|
||||
<testcase name="tests/layoutswitcher" time="0"></testcase>
|
||||
<testcase name="tests/densityswitcher" time="0"></testcase>
|
||||
<testcase name="tests/employeecard" time="0"></testcase>
|
||||
</testsuite>
|
||||
+7
-9
@@ -1,18 +1,16 @@
|
||||
{
|
||||
"generated": "2026-09-11 17:42:00",
|
||||
"generated": "2026-09-11 15:12:19",
|
||||
"version": "1.4.1",
|
||||
"pages": 79,
|
||||
"pagesAllPass": 79,
|
||||
"passRate": 100,
|
||||
"assertions": {
|
||||
"total": 961,
|
||||
"pass": 925,
|
||||
"total": 1038,
|
||||
"pass": 1003,
|
||||
"fail": 0,
|
||||
"skip": 36,
|
||||
"na": 36
|
||||
"skip": 35,
|
||||
"na": 35
|
||||
},
|
||||
"failureKinds": {},
|
||||
"failedPages": [],
|
||||
"note": "v1.4.1:四轮审计(契约保真/令牌语义/i18n 质量/残留检查)+ 回归偶发根治。八次连跑 100% 零超时。N/A 36 条来自静态组件与单实例组件。此通过率不等于无障碍合规认证。",
|
||||
"timedOut": []
|
||||
"timedOut": [],
|
||||
"failedPages": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user