ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AionUi Assistant 设置页 E2E 测试门禁实践:从需求评审到 Playwright 落地的多角色协作全记录

AionUi Assistant 设置页 E2E 测试门禁实践:从需求评审到 Playwright 落地的多角色协作全记录 AionUi Assistant 设置页 E2E 测试门禁实践从需求评审到 Playwright 落地的多角色协作全记录【免费下载链接】AionUi免费、本地、开源的 24/7 全天候 Cowork 应用以及适用于 Gemini CLI、Claude Code、Codex、OpenCode、Qwen Code、Goose CLI、Auggie 等的 OpenClaw | 喜欢就点star吧项目地址: https://gitcode.com/iOfficeAI/AionUi本文以 AionUi 仓库中 tests/e2e/docs/assistants/discussion-log.zh.md 这份多角色协作讨论日志为主体还原 Assistant 设置功能从需求文档起草、双角色评审、测试用例设计到 Playwright E2E 测试落地门 1 → 门 2 → 门 3的完整门禁流程。读者可以从中掌握一整套可复用的测试驱动协作方法论如何用源码证据校验需求文档、如何从可测试性视角设计 E2E 用例、如何在真实实施中处理依赖外部数据与禁止 skip的冲突。讨论日志的背景一份需求文档如何被三方来回锤炼discussion-log.zh.md是 AionUi 中 Assistant 设置功能开发过程中的协作讨论档案记录了一天之内围绕需求文档requirements.zh.md和测试用例文档test-cases.zh.md展开的多轮评审与修订。日志中活跃着三个明确的 AI 角色assistant-analyst-2需求文档主笔负责源码验证与需求映射assistant-designer-2测试用例设计者负责把需求细化为可执行的 Playwright 步骤assistant-engineer-2测试实现者负责从可测试性/可观测性角度审查并最终落地 E2E 测试代码。整体流程被划分为三道门禁门 1需求定稿→ 门 2用例定稿→ 门 3代码实现每道门都需要多角色 review 通过才能进入下一阶段。这种Analyst 起草 → Engineer Designer 双 review → 修订 → 再确认的循环在仓库中留下了可对照的产物tests/e2e/features/assistants/core-interactions.e2e.ts、tests/e2e/features/assistants/ui-states.e2e.ts 和 tests/e2e/features/assistants/edge-cases.e2e.ts。门 1需求文档的起草与双角色评审Analyst 起草以源码行号为准绳的 61 条功能需求第一轮由 analyst 起草。核心动作是逐条对照 4 个关键源码文件验证 61 条功能需求的文件路径与行号准确性涉及文件包括index.tsx、AssistantListPanel.tsx、AssistantEditDrawer.tsx注当前仓库中该组件已重构为全页编辑器形态与assistantUtils.ts。同时将 33 个已覆盖测试用例crud 15 条 permissions 8 条 skills 10 条映射到具体需求 ID并为 32 条未被覆盖的需求分配了 P0/P1/P2 优先级。需要特别指出的是当前仓库中 Assistant 设置页的编辑器已经从抽屉Drawer重构为全页编辑器形态。在 packages/desktop/src/renderer/pages/settings/AssistantSettings/index.tsx 的头部注释中可以看到按助手类型划分的编辑权限表这一设计意图与讨论日志中Extension Name 应为 read-only的争议同源字段BuiltinCustomSave 按钮yesyesNamenoyesDescriptionnoyesAvatarnoyesMain AgentyesyesPrompt 编辑noyesDeletenoyes重构后的 E2E 测试也印证了这一演变——core-interactions.e2e.ts 的头部注释明确写着aligned with the latest single-list full-page-editor design。三个核心争议点设计与实现的裂缝Analyst 在验证中暴露了三个待讨论事项这是整份日志中最有价值的事实核对素材Extension Name 输入权限矛盾设计意图是 read-only但源码实际用disabled{activeAssistant?.isBuiltin}控制而 Extension 的isBuiltinfalse导致 Name 输入框实际上可以编辑Extension showSkills 行为showSkills isCreating || hasBuiltinSkills || (!activeAssistant.isBuiltin)Extension 满足第三个条件因此会显示 Skills 区但为只读Edit 模式 Save 是否自动关闭编辑器specs 注释声称不自动关闭但需要实际验证。这三点后来分别被定性为源码 bug、合理设计和需实测确认体现了以源码实际行为为准的测试原则。Engineer Review可测试性视角的体检Engineer 从四个维度审查了需求文档源码追溯抽查全部通过包括highlightId滚动逻辑2 秒高亮 onHighlightConsumed回调与 intent 自动打开sessionStorage route state 两条路径。这两点在当前仓库中均有直接对应实现AssistantListPanel.tsxsetTimeout延迟 150ms 后scrollIntoView 高亮2 秒后清空并调用onHighlightConsumed?.()且return () clearTimeout(timer)保证卸载时清理定时器index.tsxuseEffect中同时解析 route state 与sessionStorage中的guid.openAssistantEditorIntent消费后立即removeItem并置位hasConsumedNavigationIntentRef防止重复打开。data-testid 完整性扫描给出了两组清单17 个已有标识符列表assistant-card-{id}、btn-create-assistant、btn-search-toggle、input-search-assistant等编辑器assistant-editor-page、btn-save-assistant、btn-delete-assistant等和 10 个缺失标识符的元素AddSkillsModal 外部源 pill、技能卡片 Add 按钮、Drawer 关闭图标、Cancel 按钮、Rules Expand/Collapse 按钮等后者的定位方案依赖 Arco Design 的类名与文本组合 selector。P0 核心交互技术可行性评估给出了 5 条用例的关键断言点例如搜索栏展开/折叠需要验证图标从 Search 切换到 CloseSmall、input-search-assistant可见且 autoFocus卡片点击区域隔离需要验证点击右侧 Switch/Duplicate 不触发卡片 onClick依赖e.stopPropagation()。当前源码 AssistantListPanel.tsx 中右侧操作区确实包裹了onClick{(e) e.stopPropagation()}与文档描述完全一致。Designer Review补上移动端与边界场景的盲区Designer 的独立审查发现了 Engineer 未覆盖的问题移动端布局遗漏AssistantListPanel.tsx使用layout.isMobile判断移动端移动端下 Create 按钮宽度 100%、高度 36px桌面 32px搜索区与操作区纵向排列flex-col——于是新增需求F-L-10高亮动画中途卸载setTimeout期间组件卸载时useEffectcleanup 应清理 timer新增边界B-14P0-5 优先级争议openAssistantEditorIntent属于低频辅助特性主路径是直接点击卡片建议从 P0 降级为 P1S-09 覆盖范围描述不准确extension assistant drawer opens without error只验证了可打开不报错并未断言 Skills 区是否渲染应改为部分覆盖Drawer 响应式宽度Math.min(1024, Math.max(480, width * 0.5))公式缺少测试覆盖建议按 480/1024/2048 viewport 验证。门 1 定稿8 条建议全部落地的 v1.1修订后的统计变化清晰可见功能需求 61 → 62 条F-L-10边界场景 13 → 15 条B-14、B-15补充测试从 P05/P125/P22 的 32 条调整为 P06/P126/P25 的 37 条。其中 B-15搜索 Tab 过滤同时生效的空态对应源码 assistantUtils.ts 的filterAssistants实现——先对 name/description 做 searchQuery 过滤再按 filter 条件过滤两个条件为与关系。门 2把 37 条补充清单细化为 38 个可执行用例用例文档的结构化设计Designer 产出的test-cases.zh.md约 23K、38 个用例每个用例包含六要素用例 IDP0-1 ~ P2-5、用例名称Playwright 风格英文短句、覆盖需求引用需求 ID 如 F-S-01/B-08、前置条件、测试步骤含 Playwright 代码示例、data-testid 标注、断言点与清理操作。例如 P0-1 的核心代码const searchToggle page.locator([data-testidbtn-search-toggle]); const searchInput page.locator([data-testidinput-search-assistant]); await expect(searchInput).toBeHidden(); // 初始折叠 await searchToggle.click(); await expect(searchInput).toBeVisible(); await expect(searchInput).toBeFocused(); // 验证 autoFocusAnalyst Review1:1 覆盖度验证Analyst 逐条对照需求文档第 8 章与 38 个用例建立映射关系结论是100% 完整覆盖P0 6/6、P1 27/27、P2 5/5且抽查的 4 个关键用例P0-1、P0-6、P1-18、P2-1需求 ID 引用无偏差。同时发现两个问题P0-2 的清理操作虽声称Switch 已恢复原状态但缺少恢复后的断言建议补充expect(isCheckedRestored).toBe(isCheckedBefore)需求文档第 8 章标题未标注总条目数。Engineer Review可执行性分层Engineer 将 38 个用例按可执行性分为三类27 个可直接实现P0 全 6 个 P1 18 个 P2 3 个7 个需 skip 待数据依赖 Pending/Custom 技能、外部技能源等占 18.4%2 个需 mockP1-23 用page.evaluate()设置 sessionStorageP2-5 的dialog.showOpen建议改用electronApp.evaluate()直接 mock 主进程的dialog.showOpenDialog因为覆盖window.electron.dialog可能与 preload 脚本暴露的实际 IPC 不一致。此外还评估了断言准确性P0-1 图标切换建议用行为验证点击后输入框可见即证明初始为 Search 图标而非 SVG 结构断言P1-13 状态点颜色建议用 class 判断而非getComputedStyle解析P1-22 Drawer 宽度断言建议允许 2px 渲染误差。门 3Playwright E2E 的真实落地配置变更testDir 从 specs 扩展到全目录实施的第一步是修改 playwright.config.tstestDir从./tests/e2e/specs改为./tests/e2etestMatch: **/*.e2e.ts保持不变使specs/与features/两个目录的测试都能被发现。配置中workers: 1与fullyParallel: false的设定来自注释说明tests share a singleton Electron app instance——Electron 测试共享单例应用实例因此无法并行。20 个测试的验收结果最终运行命令E2E_DEV1 bun run test:e2e tests/e2e/features/assistants/的结果为19 passed / 1 skipped50.1sP0 核心交互 6/6100%、P1 UI 状态 13/2748%、P2 边界 0/5。其中唯一的 skip 是 P1-9Rules 区 Expand/Collapse 按钮因为源码缺少data-testidbtn-expand-rules。五个关键的技术决策实施过程中沉淀了五条可复用的 Electron Playwright 经验避免page.goto()Electron E2E 环境中page.goto(/#/...)与 HashRouter 不兼容改用page.evaluate(() { window.location.hash /settings/assistants?highlight id; })。这在 core-interactions.e2e.ts 的 P0-4 用例中得到验证i18n 文本用正则匹配UI 有中英文两套文案硬编码英文会挂掉中文环境统一用/Delete|删除/i这类正则断言可靠的 Drawer 关闭 helperEscape键并非总是可靠封装closeDrawer()时先用isVisible()探测再按键、再waitFor({ state: hidden })隐藏元素只断言可见性对折叠状态下的搜索框只做toBeHidden()不尝试断言隐藏元素的值Hover 触发 unhover移动到 (0,0) 不可靠改为 hover 到页面标题等其他元素如text/Assistant|助手设置/i再等待 200ms。可测性调整当禁止 skip撞上无法构造的数据门 3 实施中爆发了最核心的方法论冲突team-lead 要求禁止test.skip()无例外但 P1-14 ~ P1-18 依赖的数据无法通过invokeBridge构造——Pending Skills 是临时 React state、Custom Skills 需要预置外部文件系统路径、Auto-injected Skills 依赖 Builtin 助手特定配置。Designer 提出了两个方案最终采用方案 A空态验证把正向验证标签渲染反转成验证无此类数据时不显示对应 UI。例如 P1-14 从Pending 技能显示 PENDING 标签改为无 Pending 技能时不显示 PENDING 标签。这样既能满足无 skip 的硬性要求、验证价值不减验证无数据 → 无 UI的逻辑又不依赖外部环境。随后实施又暴露了两轮更深的根因问题P1-16 定位器错误用例中使用[class*skill-card]定位但实际 DOM 是div.flex.items-start.gap-8px.p-8px通用容器且删除按钮是opacity-0 group-hover:opacity-100必须先 hover 卡片才可见P1-18 预期反转设计时假设大部分 Builtin 助手没有 Auto-injected 配置但实际assistantPresets.ts中几乎所有 Builtin 助手word-creator、ppt-creator、excel-creator、cowork 等都有defaultEnabledSkills于是把空态验证反转为正向验证有 Auto-injected 时显示该分组 N/M 计数P1-16 根本性设计错误Builtin Skills 卡片根本没有删除按钮只能通过 Checkbox 取消勾选取消激活而非删除删除弹窗F-SC-01/F-SC-02只对 Pending/Custom 技能适用。最终 P1-16 被重写为Builtin Skill 通过 Checkbox 取消勾选不触发删除弹窗覆盖需求从 F-SC-01/02 改为 F-SK-08。从这份日志中可以沉淀的工程方法论回顾discussion-log.zh.md的完整流程其价值远超一份需求文档的修改记录它本身就是一套可复用的测试驱动协作模板需求必须有源码证据每条需求标注文件路径与行号评审时抽查核对杜绝凭感觉写需求可测试性是需求的一部分data-testid 的覆盖情况、元素定位方案、断言可行性应在需求阶段就评估完毕而非实现阶段临时补课评审角色互补Engineer 盯能不能测可观测性、定位稳定性、mock 可行性Designer 盯有没有漏移动端、边界场景、优先级合理性外部数据依赖要尽早识别依赖 Pending/Custom 技能、Extension 助手、系统对话框的用例应提前标注 skip/mock 策略避免门 3 实施时返工禁止 skip会倒逼更好的设计空态验证、逻辑反转、行为验证这些替代方案往往比原方案更稳定、更有长期回归价值定位器要贴近真实 DOM以group-hover:opacity这类 Tailwind/Arco 实现细节为准而不是臆想 class 命名。如果你想在自己的仓库中复现这套流程可以直接参考本仓库的产物结构讨论记录放在 tests/e2e/docs/assistants/最终测试代码落在 tests/e2e/features/assistants/公共定位与操作 helper 集中在 tests/e2e/helpers/运行入口统一由 playwright.config.ts 管理。这套文档 → 用例 → 代码 → 截图的完整链路是 E2E 测试可持续演进的关键保障。【免费下载链接】AionUi免费、本地、开源的 24/7 全天候 Cowork 应用以及适用于 Gemini CLI、Claude Code、Codex、OpenCode、Qwen Code、Goose CLI、Auggie 等的 OpenClaw | 喜欢就点star吧项目地址: https://gitcode.com/iOfficeAI/AionUi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表