|
|
@@ -0,0 +1,301 @@
|
|
|
+# Story 2.5: 修复发现的问题
|
|
|
+
|
|
|
+Status: ready-for-dev
|
|
|
+
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
+
|
|
|
+## Story
|
|
|
+
|
|
|
+作为测试开发者,
|
|
|
+我想要修复 Story 2.4 中发现的问题,
|
|
|
+以便工具可以正常使用。
|
|
|
+
|
|
|
+## Background
|
|
|
+
|
|
|
+在 Epic 2 的前四个 Story 中:
|
|
|
+- **Story 2.1**: 已安装 E2E 测试工具包并验证类型安全
|
|
|
+- **Story 2.2**: 已将静态 Select 操作迁移到新工具
|
|
|
+- **Story 2.3**: 已将异步 Select 操作迁移到新工具
|
|
|
+- **Story 2.4**: 运行了测试并收集了问题和改进建议
|
|
|
+
|
|
|
+Story 2.4 在测试过程中发现并已经修复了多个问题,但需要验证修复效果,并处理可能遗留的问题。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+
|
|
|
+1. **验证 Story 2.4 的修复效果**
|
|
|
+ - 确认 listbox → option 修复工作正常
|
|
|
+ - 确认下拉框关闭等待逻辑工作正常
|
|
|
+ - 确认超时配置优化合理
|
|
|
+
|
|
|
+2. **检查是否有遗留问题**
|
|
|
+ - 检查 Story 2.4 完成笔记中记录的问题
|
|
|
+ - 确定哪些问题需要在本 Story 中处理
|
|
|
+ - 确定哪些问题可以推迟或已解决
|
|
|
+
|
|
|
+3. **运行测试验证**
|
|
|
+ - 运行 E2E 测试确认所有功能正常
|
|
|
+ - 记录测试结果
|
|
|
+
|
|
|
+4. **更新文档**
|
|
|
+ - 更新工具包 README(如有需要)
|
|
|
+ - 记录修复的问题
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+
|
|
|
+- [ ] 分析 Story 2.4 完成笔记 (AC: #1, #2)
|
|
|
+ - [ ] 审查已应用的修复(listbox → option、下拉框关闭、超时配置)
|
|
|
+ - [ ] 确定是否需要额外修复
|
|
|
+- [ ] 运行测试验证修复效果 (AC: #3)
|
|
|
+ - [ ] 运行 `timeout 60 pnpm test:e2e:chromium disability-person-complete`
|
|
|
+ - [ ] 记录测试结果
|
|
|
+- [ ] 处理遗留问题 (AC: #2)
|
|
|
+ - [ ] 如有 HIGH 优先级问题,立即修复
|
|
|
+ - [ ] 如有 MEDIUM 优先级问题,评估是否需要修复
|
|
|
+ - [ ] LOW 优先级问题记录到待办事项
|
|
|
+- [ ] 更新文档 (AC: #4)
|
|
|
+ - [ ] 如有需要,更新 README
|
|
|
+ - [ ] 记录修复的问题到 Story 完成笔记
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### Story 2.4 发现的问题回顾
|
|
|
+
|
|
|
+根据 Story 2.4 的完成笔记,以下问题已被发现和修复:
|
|
|
+
|
|
|
+#### 已应用的修复 (2026-01-10)
|
|
|
+
|
|
|
+1. **[工具 Bug - HIGH] listbox 依赖问题**
|
|
|
+ - 问题:工具等待 `[role="listbox"]` 元素,但 Radix UI Select v2.2.5 不使用此角色
|
|
|
+ - 修复:改用 `getByRole("option")` 代替 `waitForSelector("[role=listbox]")`
|
|
|
+ - 文件:`packages/e2e-test-utils/src/radix-select.ts`
|
|
|
+
|
|
|
+2. **下拉框关闭等待逻辑**
|
|
|
+ - 问题:选项点击后下拉框未关闭,下一个选择器被遮挡
|
|
|
+ - 修复:
|
|
|
+ - 点击选项后等待 200ms
|
|
|
+ - 等待 `getByRole("option")` 变为 `hidden` 状态
|
|
|
+
|
|
|
+3. **超时配置优化**
|
|
|
+ - 问题:超时时间过长,失败反馈慢
|
|
|
+ - 修复:将 `findTrigger` 和 `findAndClickOption` 中的超时从 5000ms 减少到 2000ms
|
|
|
+
|
|
|
+### 本 Story 需要完成的工作
|
|
|
+
|
|
|
+由于 Story 2.4 已经应用了修复,本 Story 主要工作是:
|
|
|
+
|
|
|
+1. **验证修复效果**:运行 E2E 测试确认修复有效
|
|
|
+2. **检查遗留问题**:确定是否还有需要处理的问题
|
|
|
+3. **文档更新**:如有需要,更新相关文档
|
|
|
+
|
|
|
+### Project Structure Notes
|
|
|
+
|
|
|
+**主要文件:**
|
|
|
+```
|
|
|
+packages/e2e-test-utils/
|
|
|
+└── src/
|
|
|
+ └── radix-select.ts # 包含修复的工具函数
|
|
|
+
|
|
|
+web/tests/e2e/
|
|
|
+├── specs/admin/
|
|
|
+│ └── disability-person-complete.spec.ts # 验证测试
|
|
|
+└── playwright.config.ts # 超时配置
|
|
|
+```
|
|
|
+
|
|
|
+### References
|
|
|
+
|
|
|
+- [Story 2.4 - 运行测试并收集问题][1]
|
|
|
+- [Story 2.3 - 异步 Select 重写][2]
|
|
|
+- [Story 2.2 - 静态 Select 重写][3]
|
|
|
+- [E2E 测试工具包 README][4]
|
|
|
+- [E2E Radix UI 测试标准][5]
|
|
|
+
|
|
|
+[1]: /mnt/code/188-179-template-6/_bmad-output/implementation-artifacts/2-4-run-tests-collect-feedback.md
|
|
|
+[2]: /mnt/code/188-179-template-6/_bmad-output/implementation-artifacts/2-3-rewrite-async-select.md
|
|
|
+[3]: /mnt/code/188-179-template-6/_bmad-output/implementation-artifacts/2-2-rewrite-static-select.md
|
|
|
+[4]: /mnt/code/188-179-template-6/packages/e2e-test-utils/README.md
|
|
|
+[5]: /mnt/code/188-179-template-6/docs/standards/e2e-radix-testing.md
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Developer Context
|
|
|
+
|
|
|
+> **重要提示:** 本部分包含开发者实现此故事所需的所有关键上下文和约束条件。
|
|
|
+
|
|
|
+### 当前状态
|
|
|
+
|
|
|
+Story 2.4 已经完成以下修复:
|
|
|
+
|
|
|
+1. **selectRadixOption 修复**:
|
|
|
+ - 使用 `getByRole("option", { name: value })` 定位选项
|
|
|
+ - 移除 `exact: true` 允许模糊匹配
|
|
|
+ - 添加下拉框关闭等待逻辑
|
|
|
+
|
|
|
+2. **selectRadixOptionAsync 修复**:
|
|
|
+ - 同样使用 `getByRole` 策略
|
|
|
+ - 应用相同的下拉框关闭等待逻辑
|
|
|
+
|
|
|
+3. **超时配置**:
|
|
|
+ - `findTrigger` 和 `findAndClickOption` 超时从 5000ms 改为 2000ms
|
|
|
+
|
|
|
+### 技术需求
|
|
|
+
|
|
|
+#### 1. 修复后的选择器策略
|
|
|
+
|
|
|
+```typescript
|
|
|
+// packages/e2e-test-utils/src/radix-select.ts
|
|
|
+
|
|
|
+// 新的选项定位策略(更可靠)
|
|
|
+async function findAndClickOption(page: Page, value: string): Promise<void> {
|
|
|
+ // 使用 getByRole 而非 waitForSelector
|
|
|
+ const option = page.getByRole("option", { name: value });
|
|
|
+ await option.click({ timeout: 2000 });
|
|
|
+
|
|
|
+ // 等待下拉框关闭
|
|
|
+ await page.waitForTimeout(200);
|
|
|
+ await page.getByRole("option").first().waitFor({ state: 'hidden' });
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 2. 验证步骤
|
|
|
+
|
|
|
+运行以下测试验证修复效果:
|
|
|
+
|
|
|
+```bash
|
|
|
+cd web
|
|
|
+timeout 60 pnpm test:e2e:chromium disability-person-complete
|
|
|
+```
|
|
|
+
|
|
|
+**预期结果**:
|
|
|
+- 所有表单字段成功填写
|
|
|
+- 静态 Select(残疾类型、残疾等级)正常工作
|
|
|
+- 异步 Select(省份、城市)正常工作
|
|
|
+- 无超时或元素未找到错误
|
|
|
+
|
|
|
+#### 3. 可能的遗留问题
|
|
|
+
|
|
|
+基于 Story 2.4 的完成笔记,以下问题可能需要关注:
|
|
|
+
|
|
|
+| 优先级 | 问题 | 状态 |
|
|
|
+|--------|------|------|
|
|
|
+| HIGH | listbox 依赖 | ✅ 已修复 |
|
|
|
+| HIGH | 下拉框关闭 | ✅ 已修复 |
|
|
|
+| MEDIUM | 错误消息清晰度 | ⚠️ 可能需要改进 |
|
|
|
+| LOW | 性能优化 | ⚠️ 已部分修复(超时缩短) |
|
|
|
+
|
|
|
+### 架构合规性
|
|
|
+
|
|
|
+#### 工具包设计原则
|
|
|
+
|
|
|
+**Playwright API 使用**:
|
|
|
+- ✅ 使用 `getByRole()` 进行角色定位(推荐方式)
|
|
|
+- ✅ 使用 `waitFor({ state: 'hidden' })` 等待元素隐藏
|
|
|
+- ⚠️ 使用 `waitForTimeout(200)` 作为最小等待(可接受,用于等待 UI 响应)
|
|
|
+
|
|
|
+**错误处理**:
|
|
|
+- 所有错误应使用 `E2ETestError` 抛出
|
|
|
+- 错误消息应包含:操作类型、目标、期望值、可用选项、修复建议
|
|
|
+
|
|
|
+### 库和框架要求
|
|
|
+
|
|
|
+#### Playwright 版本
|
|
|
+
|
|
|
+| 包 | 版本 | 要求 |
|
|
|
+|---|------|------|
|
|
|
+| @playwright/test (web) | 1.55.0 | ✅ 满足 ^1.40.0 |
|
|
|
+| @d8d/e2e-test-utils | - | peer dependency: ^1.40.0 |
|
|
|
+
|
|
|
+#### 测试超时配置
|
|
|
+
|
|
|
+```typescript
|
|
|
+// web/tests/e2e/playwright.config.ts
|
|
|
+timeout: 60000 // 60秒,单个测试的默认超时
|
|
|
+```
|
|
|
+
|
|
|
+### 测试要求
|
|
|
+
|
|
|
+#### 验证步骤
|
|
|
+
|
|
|
+**1. 运行完整测试:**
|
|
|
+```bash
|
|
|
+cd web
|
|
|
+timeout 60 pnpm test:e2e:chromium disability-person-complete
|
|
|
+```
|
|
|
+
|
|
|
+**2. 观察点:**
|
|
|
+- ✅ 所有表单字段成功填写
|
|
|
+- ✅ 静态 Select 工作正常
|
|
|
+- ✅ 异步 Select 工作正常
|
|
|
+- ✅ 无超时或元素未找到错误
|
|
|
+- ✅ 下拉框关闭逻辑工作正常
|
|
|
+
|
|
|
+**3. 性能检查:**
|
|
|
+- 总测试时间应在合理范围内(< 60 秒)
|
|
|
+- 单个 Select 操作应快速完成(< 2 秒静态,< 5 秒异步)
|
|
|
+
|
|
|
+### 上一个故事的经验(Story 2.4)
|
|
|
+
|
|
|
+#### Story 2.4 关键经验
|
|
|
+
|
|
|
+**1. DOM 结构理解**:
|
|
|
+- Radix UI Select v2.2.5 使用 `[role="combobox"]` 而非 `[role="listbox"]`
|
|
|
+- 选项使用 `[role="option"]`,可通过 `getByRole` 定位
|
|
|
+
|
|
|
+**2. 修复验证**:
|
|
|
+- Story 2.4 完成笔记中确认所有表单字段都成功填写
|
|
|
+- 包括:姓名、性别、身份证号、残疾类型、残疾等级、省份、城市
|
|
|
+
|
|
|
+**3. 测试命令**:
|
|
|
+- 使用 `timeout` 命令限制总运行时间
|
|
|
+- 示例:`timeout 60 pnpm test:e2e:chromium`
|
|
|
+
|
|
|
+### Epic 1 回顾经验
|
|
|
+
|
|
|
+#### TypeScript + Playwright 最佳实践 [来源: epic-1-retrospective.md]
|
|
|
+
|
|
|
+**1. 使用 getByRole 优先**:
|
|
|
+- ✅ 推荐:`page.getByRole("option", { name: value })`
|
|
|
+- ❌ 避免:`page.waitForSelector("[role=listbox]")`
|
|
|
+
|
|
|
+**2. 精确文本匹配**:
|
|
|
+- 使用 `name: value` 而非 `exact: true` 进行模糊匹配
|
|
|
+- 这可以处理选项包含额外空格或格式的情况
|
|
|
+
|
|
|
+**3. 等待元素隐藏**:
|
|
|
+- ✅ 推荐:`await element.waitFor({ state: 'hidden' })`
|
|
|
+- ❌ 避免:假设元素立即消失
|
|
|
+
|
|
|
+### 项目上下文引用
|
|
|
+
|
|
|
+**完整项目上下文:** `_bmad-output/project-context.md`
|
|
|
+
|
|
|
+**关键规范:**
|
|
|
+- 测试框架:Playwright 1.55.0
|
|
|
+- 包管理:pnpm workspace 协议
|
|
|
+- TypeScript:严格模式,无 `any` 类型
|
|
|
+- 测试命令:`pnpm test:e2e:chromium`
|
|
|
+
|
|
|
+**相关文档:**
|
|
|
+- Epic 2 详情:`_bmad-output/planning-artifacts/epics.md#Epic-2`
|
|
|
+- Story 2.4:`_bmad-output/implementation-artifacts/2-4-run-tests-collect-feedback.md`
|
|
|
+- 工具包源码:`packages/e2e-test-utils/src/radix-select.ts`
|
|
|
+- 测试标准:`docs/standards/e2e-radix-testing.md`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+
|
|
|
+Claude Opus 4.5 (claude-opus-4-5-20251101)
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+
|
|
|
+(开发过程中添加调试日志引用)
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+
|
|
|
+(完成时添加笔记)
|
|
|
+
|
|
|
+### File List
|
|
|
+
|
|
|
+(完成时添加文件列表)
|