# E2E 测试选择器指南 ## 概述 本文档记录了 NovaVis 睿视项目中实际使用的选择器,用于 E2E 测试。 ## 核心原则 1. **优先使用文本选择器** - 更稳定,不易受 UI 库变更影响 2. **避免依赖 data-testid** - 除非确实存在 3. **使用页面快照验证** - 确保选择器正确 ## 页面选择器映射 ### 案件管理页面 | 元素 | 选择器 | 说明 | |------|--------|------| | 案件列表项 | `button:has-text("进入")` | 使用"进入"按钮定位案件 | | 第一个案件 | `button:has-text("进入")` | 选择第一个案件 | | 案件卡片 | `generic[cursor=pointer]` | 卡片容器 | ### 导航菜单 | 元素 | 选择器 | 说明 | |------|--------|------| | 案件管理 | `menuitem:has-text("案件管理")` | 主菜单项 | | 概览 | `menuitem:has-text("概览")` | 子菜单项 | | 数据管理 | `menuitem:has-text("数据管理")` | 主菜单项 | | 关系分析 | `menuitem:has-text("关系分析")` | 主菜单项 | | 资金流向 | `menuitem:has-text("资金流向")` | 主菜单项 | | AI 分析 | `menuitem:has-text("AI 分析")` | 主菜单项 | | 报告中心 | `menuitem:has-text("报告中心")` | 主菜单项 | | 标注管理 | `menuitem:has-text("标注管理")` | 主菜单项 | | 系统设置 | `menuitem:has-text("系统设置")` | 主菜单项 | ### 数据导入页面 | 元素 | 选择器 | 说明 | |------|--------|------| | 页面标题 | `h3:has-text("数据导入")` | 页面标题 | | 导入步骤 | `[data-testid="import-steps"]` | 步骤指示器 | | 文件输入 | `input[type="file"]` | 文件上传输入框 | ### 网络图谱页面 | 元素 | 选择器 | 说明 | |------|--------|------| | 页面标题 | `h2:has-text("资金流向与关系网络分析")` | 页面标题 | | 数据源选择器 | `[data-testid="network-graph-datasource-selector"]` | 数据源下拉框 | | 布局选择器 | `[data-testid="network-graph-layout-selector"]` | 布局下拉框 | | 节点搜索 | `input[placeholder*="搜索"]` | 搜索输入框 | ### 报告生成页面 | 元素 | 选择器 | 说明 | |------|--------|------| | 页面标题 | `h2:has-text("报告生成")` | 页面标题 | | 模板选择器 | `.ant-select` | 模板下拉框 | | 生成按钮 | `button:has-text("生成报告")` | 生成按钮 | ## 交互处理 ### 按钮被遮挡 **问题**:侧边栏遮挡了按钮,导致点击失败 **解决方案**: ```typescript const button = page.locator('button:has-text("进入")').first() await button.scrollIntoViewIfNeeded() await button.click({ force: true }) ``` ### 页面默认状态 **问题**:页面默认显示案件管理页面,不需要导航 **解决方案**: ```typescript // ❌ 错误:尝试导航到案件管理 await page.click('[data-testid="nav-cases"]') // ✅ 正确:页面默认显示案件管理,直接操作 const enterButton = page.locator('button:has-text("进入")').first() await enterButton.click({ force: true }) ``` ## 最佳实践 1. **使用页面快照验证选择器** ```typescript const snapshot = await page.locator('body').innerHTML() console.log(snapshot) ``` 2. **优先使用文本选择器** ```typescript // ✅ 推荐 page.locator('button:has-text("进入")') // ❌ 不推荐(除非确实存在) page.locator('[data-testid="enter-button"]') ``` 3. **处理异步加载** ```typescript await page.waitForLoadState('networkidle') await page.waitForTimeout(500) ``` 4. **错误处理** ```typescript try { await element.click({ timeout: 5000 }) } catch (error) { console.log('Element not found or not clickable') } ```