name: dyad:deflake-e2e-recent-commits description: 自动从主分支的最近CI运行和wwwillchen/wwwillchen-bot的最近PR中收集不稳定的E2E测试,然后修复它们。
修复近期提交中的不稳定E2E测试
自动从主分支的最近CI运行和wwwillchen/wwwillchen-bot的最近PR中收集不稳定的E2E测试,然后修复它们。
参数
$ARGUMENTS:(可选)要扫描的最近提交数量(默认:10)
任务跟踪
**您必须使用TodoWrite工具来跟踪进度。**在开始时,为以下每个主要步骤创建待办事项。开始时标记为in_progress,完成时标记为completed。
指令
-
从主分支的最近CI运行收集不稳定测试:
列出由推送到main分支触发的最近CI工作流运行:
gh api "repos/{owner}/{repo}/actions/workflows/ci.yml/runs?branch=main&event=push&per_page=<COMMIT_COUNT * 3>&status=completed" --jq '.workflow_runs[] | select(.conclusion == "success" or .conclusion == "failure") | {id, head_sha, conclusion}'注意: 我们获取3倍于所需提交数量的运行,因为许多运行可能被
cancelled(由于并发组)。过滤只到success和failure结论的运行,以获取实际完成并有工件的运行。使用
$ARGUMENTS作为提交数量,如果未提供则默认为10。对于每个完成的运行,下载包含完整Playwright测试结果的
html-report工件,该工件包含results.json:a. 查找该运行的html-report工件:
gh api "repos/{owner}/{repo}/actions/runs/<run_id>/artifacts?per_page=30" --jq '.artifacts[] | select(.name | startswith("html-report")) | select(.expired == false) | .name'b. 使用
gh run download下载:gh run download <run_id> --name <artifact_name> --dir /tmp/playwright-report-<run_id>c. 解析
/tmp/playwright-report-<run_id>/results.json以提取不稳定测试。在.claude/目录内编写一个Node.js脚本来进行此解析。不稳定测试是那些最终结果状态为"passed"但先前结果状态为"failed"、"timedOut"或"interrupted"的测试。测试标题通过连接父套件标题(包括spec文件路径)和测试标题来构建,用>分隔。d. 解析后清理下载的工件目录。
注意: 某些运行可能没有html-report工件(例如,如果它们被提前取消、merge-reports作业未完成,或工件已超过3天保留期过期)。跳过这些运行并继续下一个。
-
从wwwillchen和wwwillchen-bot的最近PR收集不稳定测试:
除了主分支CI运行外,扫描
wwwillchen或wwwillchen-bot作者的最近开放PR,查找在Playwright报告评论中报告的不稳定测试。a. 列出这些作者的最近开放PR:
gh pr list --author wwwillchen --state open --limit 10 --json number,title gh pr list --author wwwillchen-bot --state open --limit 10 --json number,titleb. 对于每个PR,查找最近的Playwright测试结果评论(由机器人发布,包含"🎭 Playwright Test Results"):
gh api "repos/{owner}/{repo}/issues/<pr_number>/comments" --jq '[.[] | select(.user.type == "Bot" and (.body | contains("Playwright Test Results")))] | last'c. 解析评论正文以提取不稳定测试。评论格式包括一个"⚠️ Flaky Tests"部分,其中测试名称在反引号中:
- 查找匹配模式的行:
- `<test_title>` (passed after N retries) - 从反引号内提取测试标题
- 测试标题格式为:
<spec_file.spec.ts> > <Suite Name> > <Test Name>
d. 将这些不稳定测试添加到整体集合中,并注明它们来自PR #N以便摘要
- 查找匹配模式的行:
-
去重并按频率排名:
计算每个测试在所有CI运行中作为不稳定测试出现的次数。按频率排序(最不稳定优先)。按spec文件分组测试。
打印摘要表:
Flaky test summary: - setup_flow.spec.ts > Setup Flow > setup banner shows correct state... (7 occurrences) - select_component.spec.ts > select component next.js (5 occurrences) ... -
如果没有找到不稳定测试则跳过:
如果未找到任何不稳定测试,报告"在最近提交或PR中未找到不稳定测试"并停止。
-
安装依赖项并构建:
npm install npm run build重要: 在运行E2E测试之前必须执行此构建步骤。如果您对应用程序代码(
e2e-tests/目录外的任何内容)进行了任何更改,必须重新运行npm run build。 -
按顺序修复每个不稳定测试spec文件:
对于每个具有不稳定测试的唯一spec文件(按总不稳定出现次数排序,最不稳定优先):
a. 运行spec文件10次以确认不稳定性(注意:
<spec_file>已从解析中包括.spec.ts扩展名):PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_HTML_OPEN=never npm run e2e -- e2e-tests/<spec_file> --repeat-each=10重要:
PLAYWRIGHT_RETRIES=0是必需的,以禁用自动重试。否则,在CI环境(其中CI=true)中默认为2次重试,导致不稳定测试在重试时通过并被错误地跳过。b. 如果测试通过所有10次运行,跳过它(它可能已被修复)。
c. 如果测试至少失败一次,使用调试日志进行调查:
DEBUG=pw:browser PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_HTML_OPEN=never npm run e2e -- e2e-tests/<spec_file>d. 按照Playwright最佳实践修复不稳定测试:
- 在交互元素之前使用
await expect(locator).toBeVisible() - 对于网络依赖的测试,使用
await page.waitForLoadState('networkidle') - 使用稳定选择器(data-testid、role、text)而不是脆弱的CSS选择器
- 为动画添加显式等待:
await page.waitForTimeout(300)(谨慎使用) - 对于视觉测试,使用
await expect(locator).toHaveScreenshot()选项如maxDiffPixelRatio - 确保适当的测试隔离(测试前后的清洁状态)
重要: 不要更改任何应用程序代码。仅修改测试文件和快照基线。
e. 如果需要,更新快照基线:
PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_HTML_OPEN=never npm run e2e -- e2e-tests/<spec_file> --update-snapshotsf. 通过再次运行10次验证修复:
PLAYWRIGHT_RETRIES=0 PLAYWRIGHT_HTML_OPEN=never npm run e2e -- e2e-tests/<spec_file> --repeat-each=10g. 如果测试在修复尝试后仍然失败,还原对该spec文件的任何更改并移至下一个。不要花费超过2次尝试修复单个spec文件。
- 在交互元素之前使用
-
总结结果:
报告:
- 在主分支提交和PR中总共找到的不稳定测试
- 不稳定测试的来源(主分支CI运行 vs. wwwillchen/wwwillchen-bot的PR评论)
- 哪些测试被成功修复
- 对每个应用了哪些修复
- 哪些测试无法修复(以及原因)
- 验证结果
-
创建带修复的PR:
如果进行了任何修复,运行
/dyad:pr-push来提交、lint、测试和推送更改作为PR。使用分支名称如
deflake-e2e-<date>(例如,deflake-e2e-2025-01-15)。PR标题应为:
fix: deflake E2E tests (<list of spec files>)