资讯动态

AionUi Assistant 设置页 E2E 测试用例设计:从需求到 Playwright 可执行步骤的完整实践

发布时间:2026/9/11 14:03:22 来源:尧图企业网站定制
AionUi Assistant 设置页 E2E 测试用例设计从需求到 Playwright 可执行步骤的完整实践【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20 more CLI Agent | Customize your assistants | Team them upStar if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi导读本文以 AionUi 仓库中 Assistant 设置页补充测试用例文档 为核心骨架系统讲解如何将 37 条补充测试清单细化为可执行的 Playwright 测试用例步骤。该测试体系覆盖桌面端设置中心子页面Assistant 设置页路由#/settings/assistants的搜索交互、卡片点击隔离、删除确认、高亮路由、技能管理、响应式布局等核心场景。读完本文你将掌握一套带data-testid、断言点与清理策略的完整 E2E 测试用例写法并了解其背后的源码实现依据与优先级分级P0 必测 / P1 推荐 / P2 可选方法论。一、背景为什么需要补充 E2E 测试AionUi 的 Assistant 设置页用于管理应用中所有 AI 助手助手按来源分为三类详见 需求文档Builtin内置由ASSISTANT_PRESETS预置ID 前缀builtin-Extension扩展由已加载的 extension 贡献ID 前缀ext-Custom自定义用户自行创建页面 UI 由以下主要组件构成引用自packages/desktop/src/renderer/pages/settings/AssistantSettings/index.tsx组件职责AssistantListPanel列表视图 搜索/过滤 新建按钮AssistantEditDrawer编辑抽屉右侧 DrawerDeleteAssistantModal删除确认弹窗AddSkillsModal从外部源添加技能的弹窗AddCustomPathModal为技能库添加自定义路径的弹窗SkillConfirmModals删除 pending 技能 / 移除 custom 技能的确认弹窗尽管已有 assistant-settings-crud.e2e.ts、assistant-settings-permissions.e2e.ts、assistant-settings-skills.e2e.ts 等既有测试经逐条对照发现仍有多处未被覆盖的需求项——例如搜索栏切换按钮的图标变化、卡片右侧操作区与主体的点击隔离、Delete 弹窗的预览卡片渲染、?highlight路由高亮、AddSkillsModal 的搜索空态等。因此产生了 38 条补充测试清单P06 / P127 / P25并进一步细化成可执行的测试用例步骤。二、测试用例格式说明每个测试用例统一包含以下字段这是整个测试体系的契约用例 IDP0-1 ~ P2-5对应优先级用例名称简短描述英文作为test(...)的标题覆盖需求引用 requirements 文档的需求 ID如 F-S-01、F-L-07、B-08前置条件测试开始前的状态要求测试步骤编号步骤包含具体操作 >const searchToggle page.locator([data-testidbtn-search-toggle]); const searchInput page.locator([data-testidinput-search-assistant]); await expect(searchInput).toBeHidden(); await searchToggle.click(); await page.waitForTimeout(200); // 等待展开动画 await expect(searchInput).toBeVisible(); await expect(searchInput).toBeFocused(); // F-S-04 autoFocus await searchInput.fill(test); await expect(searchInput).toBeVisible(); // F-S-08 非空保持可见 await searchToggle.click(); await expect(searchInput).toHaveValue(); await expect(searchInput).toBeHidden();P0-2: 卡片点击区域隔离主体 vs 右侧操作区覆盖需求F-L-07 / B-08 / B-09该用例验证卡片内不同区域的点击行为差异是防止误触的关键。源码中 Duplicate 按钮与 Switch 共享同一个stopPropagation容器AssistantListPanel.tsx。点击卡片主体Avatar 名称区域→ 编辑 Drawer[data-testidassistant-edit-drawer]打开点击 Switch[data-testidswitch-enabled-id]→ Drawer 不打开但 Switch 状态翻转验证点击确实生效随后恢复原状态Hover 后点击 Duplicate 按钮[data-testidbtn-duplicate-id]→ Drawer 打开且为 Create 模式保存按钮文案为 Create// 点击卡片主体 → Drawer 打开 await firstCard.locator(.flex.items-center.gap-12px).first().click(); await expect(drawer).toBeVisible({ timeout: 5000 }); await page.keyboard.press(Escape); await drawer.waitFor({ state: hidden, timeout: 3000 }); // 点击 Switch → Drawer 不打开状态改变 const switchElement page.locator([data-testidswitch-enabled-${assistantId}]); const isCheckedBefore await switchElement.isChecked(); await switchElement.click(); await expect(drawer).toBeHidden(); expect(await switchElement.isChecked()).toBe(!isCheckedBefore); await switchElement.click(); // 恢复原状态P0-3: Delete 确认弹窗含助手预览卡片覆盖需求F-R-03 / F-R-04 / F-R-05验证删除确认弹窗的完整渲染对应源码 DeleteAssistantModal.tsx创建测试助手用Date.now()生成唯一名称通过btn-create-assistant→input-assistant-name→btn-save-assistant完成创建打开 Drawer 并点击 Delete[data-testidbtn-delete-assistant]验证 Modal[data-testidmodal-delete-assistant]标题含 Delete预览区含 Avatar.arco-avatar、助手名称与描述确认按钮为 danger 状态.arco-btn-status-danger且文案 Delete取消按钮文案 Cancel确认删除Modal 与 Drawer 依次关闭助手卡片从列表移除const modal page.locator([data-testidmodal-delete-assistant]); await expect(modal).toBeVisible({ timeout: 3000 }); await expect(modal.locator(.arco-modal-title)).toContainText(Delete); await expect(modal.locator(.arco-avatar)).toBeVisible(); await expect(modal).toContainText(testName); await expect(modal).toContainText(testDesc); const confirmBtn modal.locator(.arco-btn-status-danger); await expect(confirmBtn).toContainText(Delete); await confirmBtn.click(); await expect(targetCard).toBeHidden({ timeout: 5000 });P0-4: highlightId 滚动到卡片并高亮 2 秒之后清 query覆盖需求3.2 交互流程验证通过 URL query 直达指定助手的功能对应 AssistantListPanel.tsx 的useEffect实现setTimeout2 秒高亮 return () clearTimeout(timer)清理await page.goto(/#/settings/assistants?highlightbuiltin-agent); const targetCard page.locator([data-testidassistant-card-builtin-agent]); await targetCard.waitFor({ state: visible, timeout: 10000 }); // 卡片应滚动到视口内 const isInViewport await targetCard.evaluate((el) { const rect el.getBoundingClientRect(); return rect.top 0 rect.bottom window.innerHeight; }); expect(isInViewport).toBe(true); // 高亮样式 border-primary-5 bg-primary-1 expect(await targetCard.getAttribute(class)).toContain(border-primary-5); // 2 秒后高亮消失query 清空 await page.waitForTimeout(2100); expect(await targetCard.getAttribute(class)).not.toContain(border-primary-5); expect(page.url()).not.toContain(highlight);P0-5: AddSkillsModal 搜索框过滤 无结果文案覆盖需求F-A-03 / F-A-04验证添加技能弹窗的搜索过滤与空态反馈打开 Custom 助手 Drawer → 点击 Add Skills[data-testidbtn-add-skills]→ Modal 打开.arco-modal Add Skills 文本搜索框无>await page.evaluate(() { window.electron window.electron || {}; window.electron.dialog { showOpen: async () ({ canceled: false, filePaths: [/mock/selected/path] }), }; }); const folderBtn pathModal.locator(button).filter({ has: page.locator([class*folder]) }); await folderBtn.click(); await expect(pathModal.locator(input).last()).toHaveValue(/mock/selected/path);六、测试实施注意事项6.1 数据依赖与 skip 策略部分用例依赖外部数据实施时需明确 skip 条件P0-6、P1-6依赖 Extension 助手存在ID 前缀ext-如无则 skipP1-14 ~ P1-17依赖外部技能源或 Pending/Custom 技能建议 mock 或 skipP1-18依赖 Builtin 助手有 Auto-injected Skills建议用builtin-agentP1-21依赖已添加的技能建议 skip 或 mock6.2 contenteditable="false">【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20 more CLI Agent | Customize your assistants | Team them upStar if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价