name: Regression # 每次 push / PR 自动跑回归。 # 所有检查都在 Node 20 上执行;playwright 仅作为 CI 开发依赖。 on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: permissions: contents: read jobs: regression: runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 with: persist-credentials: false - name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' - name: Cache playwright browsers uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ hashFiles('package.json', 'package-lock.json') }} restore-keys: | ${{ runner.os }}-playwright- - name: Install dependencies run: npm ci - name: Install playwright chromium run: npx --no-install playwright install --with-deps chromium # npm run verify:nav 的断言依赖字体度量(7 条链接的文字宽度决定顶栏装不装得下)。 # 缺 CJK 字体时中文会退化成豆腐块或拉丁回退,宽度随之改变 → 断言假失败。 - name: Install CJK fonts run: sudo apt-get update -qq && sudo apt-get install -y -qq fonts-noto-cjk - name: Verify zero runtime dependencies run: | node -e " const p = require('./package.json'); const deps = Object.keys(p.dependencies || {}); if (deps.length) { console.error('FAIL: 运行时依赖必须为空,实际: ' + deps.join(', ')); process.exit(1); } console.log('zero-dep OK'); " - name: Start dev server run: | node site/dev-server.js & for i in $(seq 1 30); do if curl -sf http://127.0.0.1:3311/site/data.json > /dev/null; then echo "server ready after ${i} attempt(s)" exit 0 fi sleep 0.5 done echo "FAIL: dev-server 未在 15 秒内就绪" exit 1 - name: Verify i18n run: node tools/verify-i18n.mjs - name: Verify site routing run: node tools/verify-site-routing.mjs - name: Verify cross-platform structure run: node tools/verify-cross-platform.mjs - name: Verify theme modes run: node tools/verify-theme.mjs - name: Run regression run: node tools/run-regression.mjs - name: Smoke test site run: npm run smoke:site # 顶栏窄屏折叠(≤1366px 汉堡 + 抽屉):18 个宽度 × 中英双语 + 抽屉交互,约 35 秒。 # 必须在浏览器里跑 —— 元素"可见"不等于"点得到":遮罩层叠、visibility 过渡 # 都会让点击静默失效,而矩形与可见性断言全都会通过(改动前实测踩中两个)。 - name: Verify responsive nav run: npm run verify:nav - name: Upload report uses: actions/upload-artifact@v4 if: always() with: name: regression-report path: | tests/report.json tests/report-junit.xml tests/cross-platform-report.json retention-days: 30 - name: Publish test summary if: always() run: | if [ -f tests/report.json ]; then node -e " const r = require('./tests/report.json'); const a = r.assertions; console.log('## 回归结果'); console.log(''); console.log('| 项 | 值 |'); console.log('|---|---|'); console.log('| 通过率 | ' + r.passRate + '% |'); console.log('| 断言 | ' + a.pass + '/' + (a.pass + a.fail) + ' |'); console.log('| N/A | ' + (a.na || 0) + ' |'); console.log('| 页面全通过 | ' + r.pagesAllPass + '/' + r.pages + ' |'); console.log('| 超时 | ' + ((r.timedOut || []).length) + ' |'); " >> "$GITHUB_STEP_SUMMARY" fi