38dc055a27
- 添加菜单数据修复设计文档 - 添加用户管理和角色管理测试修复设计文档 - 添加本地开发测试设计文档 - 添加相关实现计划
120 lines
3.6 KiB
Markdown
120 lines
3.6 KiB
Markdown
# 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')
|
||
}
|
||
```
|