提交 7890c5bd authored 作者: 陈泽健's avatar 陈泽健

docs(test): 更新自动化测试用例生成工具文档并修复登录定位问题

- 添加登录按钮定位错误问题处理文档
- 更新操作手册增加Python脚本执行方式
- 修正module_config.json配置示例
- 扩展Claude工具能力配置
- 生成区域管理增值服务测试用例文件
- 创建计划执行文档详述技术方案
上级 b6ce7d77
...@@ -120,7 +120,9 @@ ...@@ -120,7 +120,9 @@
"mcp__chrome-devtools__wait_for", "mcp__chrome-devtools__wait_for",
"mcp__chrome-devtools__press_key", "mcp__chrome-devtools__press_key",
"mcp__chrome-devtools__new_page", "mcp__chrome-devtools__new_page",
"mcp__chrome-devtools__close_page" "mcp__chrome-devtools__close_page",
"mcp__chrome-devtools__list_pages",
"mcp__chrome-devtools__fill_form"
] ]
} }
} }
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
"module_function": ["添加","编辑","删除"] "module_function": ["添加","编辑","删除"]
}, },
{ {
"system_type": "台系统", "system_type": "台系统",
"module_name": "会议室管理", "module_name": "授权管理",
"module_name_son": "会议室列表", "module_name_son": "会议授权",
"module_function": ["添加","编辑"] "module_function": ["编辑","停用","启用","批量启用","批量停用"]
} }
] ]
\ No newline at end of file \ No newline at end of file
此差异已折叠。
{
"name": "区域管理_增值服务_删除",
"para": [
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【区域管理】菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'区域管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【增值服务】子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'增值服务')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击第一行数据的【删除】按钮",
"locator_type": "XPATH",
"locator_value": "//tbody/tr[1]//button[contains(text(),'删 除')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击删除确认对话框的【确定】按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'确定')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "验证删除成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'删除成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "删除成功"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
{
"name": "区域管理_增值服务_添加",
"para": [
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【区域管理】菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'区域管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【增值服务】子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'增值服务')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【添加】按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'添加')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "填写商品名称",
"locator_type": "XPATH",
"locator_value": "//input[@placeholder='请输入商品名称']",
"element_type": "input",
"element_value": "测试商品001",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击商品分类下拉框",
"locator_type": "XPATH",
"locator_value": "//input[@placeholder='请选择商品分类']",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "选择分类【商品】",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'商品')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "填写商品描述",
"locator_type": "XPATH",
"locator_value": "//textarea[@placeholder='请输入商品描述']",
"element_type": "input",
"element_value": "自动化测试商品描述",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【确定】按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'确定')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "验证添加成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'添加成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "添加成功"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
{
"name": "区域管理_增值服务_编辑",
"para": [
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【区域管理】菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'区域管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【增值服务】子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'增值服务')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击第一行数据的【编辑】按钮",
"locator_type": "XPATH",
"locator_value": "//tbody/tr[1]//button[contains(text(),'编辑')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "清空并填写商品名称",
"locator_type": "XPATH",
"locator_value": "//input[@placeholder='请输入商品名称']",
"element_type": "input",
"element_value": "测试商品001_已修改",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "点击【确定】按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'确定')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "Backend/MeetingRoom/ServiceManage",
"step": "验证编辑成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'修改成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "修改成功"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
{
"name": "授权管理_会议授权_启用",
"para": [
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击授权管理菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'授权管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击会议授权子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'会议授权')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击已停用记录的启用按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'启用')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "验证启用成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'启用成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "启用成功"
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "验证状态已更新为已激活",
"locator_type": "XPATH",
"locator_value": "(//td[contains(text(),'已激活')])[1]",
"element_type": "getText",
"element_value": "",
"expected_result": "验证状态显示为已激活"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
{
"name": "授权管理_会议授权_批量停用",
"para": [
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击授权管理菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'授权管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击会议授权子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'会议授权')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "勾选第一条记录复选框",
"locator_type": "XPATH",
"locator_value": "(//input[@type='checkbox'])[2]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "勾选第二条记录复选框",
"locator_type": "XPATH",
"locator_value": "(//input[@type='checkbox'])[3]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击批量停用按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'批量停用')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "验证批量停用成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'批量停用成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "批量停用成功"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
{
"name": "授权管理_会议授权_批量启用",
"para": [
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击授权管理菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'授权管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击会议授权子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'会议授权')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "勾选第一条记录复选框",
"locator_type": "XPATH",
"locator_value": "(//input[@type='checkbox'])[2]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "勾选第二条记录复选框",
"locator_type": "XPATH",
"locator_value": "(//input[@type='checkbox'])[3]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击批量启用按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'批量启用')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "验证批量启用成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'批量启用成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "批量启用成功"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
{
"name": "授权管理_会议授权_编辑",
"para": [
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击授权管理菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'授权管理')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击会议授权子菜单",
"locator_type": "XPATH",
"locator_value": "//li[contains(text(),'会议授权')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击第一条记录的编辑按钮",
"locator_type": "XPATH",
"locator_value": "(//button[contains(text(),'编辑')])[1]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "修改授权码说明",
"locator_type": "XPATH",
"locator_value": "//input[@placeholder='授权码说明']",
"element_type": "input",
"element_value": "自动化测试编辑授权码说明",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "点击确定按钮",
"locator_type": "XPATH",
"locator_value": "//button[contains(text(),'确定')]",
"element_type": "click",
"element_value": "",
"expected_result": ""
},
{
"page": "#/Backend/AuthorizationCode/AuthCode",
"step": "验证编辑成功提示",
"locator_type": "XPATH",
"locator_value": "//p[contains(text(),'编辑成功')]",
"element_type": "getTips",
"element_value": "",
"expected_result": "编辑成功"
}
],
"platform": "web",
"base_url": "https://192.168.5.44"
}
...@@ -2,13 +2,16 @@ ...@@ -2,13 +2,16 @@
## 前置条件 ## 前置条件
### 1. 确保Chrome DevTools MCP工具已启动 ### 1. Python环境准备
确保已安装必要的Python依赖:
```bash ```bash
# 检查MCP服务是否正常运行 pip install selenium
# 确保 Claude Code 可以访问 chrome-devtools MCP 工具
``` ```
### 2. 准备配置文件 ### 2. ChromeDriver
确保已安装ChromeDriver,并且版本与Chrome浏览器匹配。
### 3. 准备配置文件
确保以下配置文件已正确配置: 确保以下配置文件已正确配置:
- `AuxiliaryTool/TestCaseGenerator/config/system_config.json` - 系统登录配置 - `AuxiliaryTool/TestCaseGenerator/config/system_config.json` - 系统登录配置
- `AuxiliaryTool/TestCaseGenerator/config/module_config.json` - 模块配置 - `AuxiliaryTool/TestCaseGenerator/config/module_config.json` - 模块配置
...@@ -17,7 +20,58 @@ ...@@ -17,7 +20,58 @@
## 操作步骤 ## 操作步骤
### 使用Claude Code对话式生成 ## 方式一:运行Python脚本(推荐)⭐
**推荐使用此方式**,无需对话交互,可直接运行,支持CI/CD集成。
### Step 1: 更新模块配置文件
编辑 `module_config.json`,添加新模块配置:
```json
[
{
"system_type": "后台系统",
"module_name": "一级菜单名称",
"module_name_son": "二级菜单名称",
"module_function": ["添加", "编辑", "删除"]
}
]
```
**配置说明:**
- `system_type`: 包含"后台"或"admin"使用后台URL,否则使用前台URL
- `module_name`: 一级菜单名称(如:区域管理、用户管理)
- `module_name_son`: 二级菜单名称(如:增值服务、用户列表)
- `module_function`: 需要生成的功能类型,支持:
- `添加` - 新增数据操作
- `编辑` - 修改数据操作
- `删除` - 删除数据操作
- `停用` - 停用操作
- `启用` - 启用操作
- `批量启用` - 批量启用操作
- `批量停用` - 批量停用操作
### Step 2: 运行生成脚本
```bash
# 进入目录
cd E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator
# 运行脚本
python generate_testcases.py
```
### Step 3: 查看生成的文件
生成的文件位于:
```
AuxiliaryTool/TestCaseGenerator/testcases/{模块名}_{子模块名}_{功能}.json
```
---
## 方式二:使用Claude Code对话式生成
#### Step 1: 更新模块配置文件 #### Step 1: 更新模块配置文件
...@@ -294,9 +348,11 @@ mkdir -p "E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator/confi ...@@ -294,9 +348,11 @@ mkdir -p "E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator/confi
## 附录:快速开始模板 ## 附录:快速开始模板
### Step 1: 确保配置文件存在 ### 使用Python脚本方式(推荐)
**创建config目录(如果不存在):** **Step 1: 确保配置文件存在**
创建config目录(如果不存在):
```bash ```bash
mkdir -p "E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator/config" mkdir -p "E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator/config"
``` ```
...@@ -319,18 +375,43 @@ mkdir -p "E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator/confi ...@@ -319,18 +375,43 @@ mkdir -p "E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator/confi
"system_type": "后台系统", "system_type": "后台系统",
"module_name": "一级菜单", "module_name": "一级菜单",
"module_name_son": "二级菜单", "module_name_son": "二级菜单",
"module_function": ["添加"] "module_function": ["添加", "编辑", "删除"]
}] }]
``` ```
### Step 2: 在Claude Code中执行 **Step 2: 运行生成脚本**
```bash
cd E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator
python generate_testcases.py
```
**Step 3: 查看结果**
生成的文件位于:
```
AuxiliaryTool/TestCaseGenerator/testcases/
```
### 使用Claude Code对话方式
**Step 1: 在Claude Code中执行**
直接输入指令: 直接输入指令:
``` ```
请根据module_config.json和system_config.json生成自动化测试JSON数据 请根据module_config.json和system_config.json生成自动化测试JSON数据
``` ```
### Step 3: 查看结果 **Step 2: Claude Code自动执行流程**
Claude Code会通过MCP工具自动执行以下流程:
1. 打开浏览器并登录系统
2. 导航到指定模块(点击一级菜单 > 二级菜单)
3. 执行配置的功能操作(添加/编辑/删除)
4. 收集元素定位信息(使用XPATH等方式)
5. 生成测试用例JSON文件
**Step 3: 查看结果**
生成的文件位于: 生成的文件位于:
``` ```
...@@ -341,18 +422,33 @@ AuxiliaryTool/TestCaseGenerator/testcases/ ...@@ -341,18 +422,33 @@ AuxiliaryTool/TestCaseGenerator/testcases/
## 总结 ## 总结
**目前唯一支持的方式:** 通过Claude Code对话式生成 ### 两种方式对比
| 特性 | 方式一:Python脚本 | 方式二:Claude Code对话 |
|------|-------------------|------------------------|
| **执行方式** | 直接运行脚本 | 对话输入指令 |
| **自动化程度** | 完全自动化 | 半自动化 |
| **会话清除影响** | 无影响,脚本可重复运行 | 需要重新输入指令 |
| **CI/CD集成** | 支持 | 不支持 |
| **调试难度** | 可通过日志调试 | 需要对话交互调试 |
| **推荐使用场景** | 日常开发、批量生成、CI/CD | 快速验证、一次性生成 |
### 推荐使用方式一(Python脚本)
**核心优势:** **核心优势:**
- 无需编写代码 - ✅ 无需对话交互,直接运行
- 自动处理浏览器操作 - ✅ 会话清除不影响使用
- 智能识别元素定位 - ✅ 可集成到CI/CD流程
- 自动生成标准JSON格式 - ✅ 可批量处理多个模块
- ✅ 生成结果稳定可重复
**下次使用时:** 只需更新 `module_config.json`,然后在Claude Code中输入指令即可! **使用流程:**
1. 更新 `module_config.json` 配置
2. 运行 `python generate_testcases.py`
3.`testcases/` 目录查看生成的文件
--- ---
*文档版本:v1.1* *文档版本:v2.0*
*更新日期:2026-03-06* *更新日期:2026-03-06*
*更新说明:移除命令行方式,仅保留Claude Code对话式生成方式* *更新说明:新增Python脚本执行方式,作为主要推荐方式*
# _PRD_程序执行定位登录按钮错误_问题处理
> 来源:
- `AuxiliaryTool/TestCaseGenerator/generate_testcases.py`
## 1. 背景与目标
### 1.1 背景
执行程序时,在登录页面定位登录按钮失败报错。
### 1.2 目标
确保能够正常登录进去自动根据两份config文件进行自动获取生成自动化测试用例JSON数据。
---
## 2. 问题报错信息
### 2.1 问题一
```
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1772782382.794702 25060 voice_transcription.cc:58] Registering VoiceTranscriptionCapability
✗ 执行出错: Message: no such element: Unable to locate element: {"method":"css selector","selector":"button[type='submit']"}
(Session info: chrome=137.0.7151.41); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
Stacktrace:
GetHandleVerifier [0x0x7ff6696191f5+2853845]
GetHandleVerifier [0x0x7ff669373ac0+79008]
(No symbol) [0x0x7ff669139bda]
(No symbol) [0x0x7ff6691900f6]
(No symbol) [0x0x7ff6691903ac]
(No symbol) [0x0x7ff6691e3b07]
(No symbol) [0x0x7ff6691b84ff]
(No symbol) [0x0x7ff6691e08f5]
(No symbol) [0x0x7ff6691b8293]
(No symbol) [0x0x7ff669181061]
(No symbol) [0x0x7ff669181df3]
GetHandleVerifier [0x0x7ff66964410d+3029741]
GetHandleVerifier [0x0x7ff66963e52d+3006221]
GetHandleVerifier [0x0x7ff66965d5b2+3133330]
GetHandleVerifier [0x0x7ff66938d98e+185198]
GetHandleVerifier [0x0x7ff669394edf+215231]
GetHandleVerifier [0x0x7ff66937c324+113924]
GetHandleVerifier [0x0x7ff66937c4d9+114361]
GetHandleVerifier [0x0x7ff669363208+11240]
BaseThreadInitThunk [0x0x7ffb9a90e8d7+23]
RtlUserThreadStart [0x0x7ffb9b0cc53c+44]
Traceback (most recent call last):
File "E:\GithubData\ubains-module-test\AuxiliaryTool\TestCaseGenerator\generate_testcases.py", line 158, in login
login_btn = self.driver.find_element(By.XPATH, "//button[contains(text(),'登') or contains(text(),'Login')]")
File "E:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 917, in find_element
return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]
File "E:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 448, in execute
self.error_handler.check_response(response)
File "E:\Python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button[contains(text(),'登') or contains(text(),'Login')]"}
(Session info: chrome=137.0.7151.41); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
Stacktrace:
GetHandleVerifier [0x0x7ff6696191f5+2853845]
GetHandleVerifier [0x0x7ff669373ac0+79008]
(No symbol) [0x0x7ff669139bda]
(No symbol) [0x0x7ff6691900f6]
(No symbol) [0x0x7ff6691903ac]
(No symbol) [0x0x7ff6691e3b07]
(No symbol) [0x0x7ff6691b84ff]
(No symbol) [0x0x7ff6691e08f5]
(No symbol) [0x0x7ff6691b8293]
(No symbol) [0x0x7ff669181061]
(No symbol) [0x0x7ff669181df3]
GetHandleVerifier [0x0x7ff66964410d+3029741]
GetHandleVerifier [0x0x7ff66963e52d+3006221]
GetHandleVerifier [0x0x7ff66965d5b2+3133330]
GetHandleVerifier [0x0x7ff66938d98e+185198]
GetHandleVerifier [0x0x7ff669394edf+215231]
GetHandleVerifier [0x0x7ff66937c324+113924]
GetHandleVerifier [0x0x7ff66937c4d9+114361]
GetHandleVerifier [0x0x7ff669363208+11240]
BaseThreadInitThunk [0x0x7ffb9a90e8d7+23]
RtlUserThreadStart [0x0x7ffb9b0cc53c+44]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\GithubData\ubains-module-test\AuxiliaryTool\TestCaseGenerator\generate_testcases.py", line 582, in main
generator.run()
File "E:\GithubData\ubains-module-test\AuxiliaryTool\TestCaseGenerator\generate_testcases.py", line 539, in run
self.login(system_info)
File "E:\GithubData\ubains-module-test\AuxiliaryTool\TestCaseGenerator\generate_testcases.py", line 161, in login
login_btn = self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
File "E:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 917, in find_element
return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]
File "E:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 448, in execute
self.error_handler.check_response(response)
File "E:\Python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"button[type='submit']"}
(Session info: chrome=137.0.7151.41); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception
Stacktrace:
GetHandleVerifier [0x0x7ff6696191f5+2853845]
GetHandleVerifier [0x0x7ff669373ac0+79008]
(No symbol) [0x0x7ff669139bda]
(No symbol) [0x0x7ff6691900f6]
(No symbol) [0x0x7ff6691903ac]
(No symbol) [0x0x7ff6691e3b07]
(No symbol) [0x0x7ff6691b84ff]
(No symbol) [0x0x7ff6691e08f5]
(No symbol) [0x0x7ff6691b8293]
(No symbol) [0x0x7ff669181061]
(No symbol) [0x0x7ff669181df3]
GetHandleVerifier [0x0x7ff66964410d+3029741]
GetHandleVerifier [0x0x7ff66963e52d+3006221]
GetHandleVerifier [0x0x7ff66965d5b2+3133330]
GetHandleVerifier [0x0x7ff66938d98e+185198]
GetHandleVerifier [0x0x7ff669394edf+215231]
GetHandleVerifier [0x0x7ff66937c324+113924]
GetHandleVerifier [0x0x7ff66937c4d9+114361]
GetHandleVerifier [0x0x7ff669363208+11240]
BaseThreadInitThunk [0x0x7ffb9a90e8d7+23]
RtlUserThreadStart [0x0x7ffb9b0cc53c+44]
```
### 3.6 问题状态
- [x] 已解决
---
## 4. 解决方案
### 4.1 根因分析
**原因1:XPATH语法错误**
```python
// 错误的XPATH语法
//button[contains(text(),'登') or contains(text(),'Login')]
```
XPATH中 `or` 操作符不能直接用于 `contains()` 函数之间,应使用 `|` (管道符)。
**原因2:定位方式单一**
代码仅依赖单一定位方式,失败后缺乏备选方案。
### 4.2 修复内容
**修复1:修正XPATH语法**
```python
// 正确的XPATH语法(使用管道符 |
//button[contains(text(),'登')] | //button[contains(text(),'Login')]
```
**修复2:实现多重定位策略**
按优先级尝试8种不同的登录按钮定位方式:
| 优先级 | 定位方式 | 说明 |
|--------|----------|------|
| 1 | 文本内容(中文/英文) | 使用 `|` 管道符组合 |
| 2 | class属性包含login | `//button[contains(@class,'login')]` |
| 3 | type属性为submit | `//button[@type='submit']` |
| 4 | CSS primary按钮 | `button.el-button--primary` |
| 5 | CSS type选择器 | `button[type='submit']` |
| 6 | CSS包含login | `button[class*='login']` |
| 7 | CSS包含Login | `button[class*='Login']` |
| 8 | CSS包含primary | `button[class*='primary']` |
| 9 | JavaScript点击 | 最后的兜底方案 |
### 4.3 代码变更
**文件:** `AuxiliaryTool/TestCaseGenerator/generate_testcases.py`
**变更内容:**
- 修正XPATH语法错误
- 实现8种备选定位方式
- 添加详细日志输出
- 增加JavaScript点击兜底方案
### 4.4 验证方式
运行以下命令验证修复:
```bash
cd E:/GithubData/ubains-module-test/AuxiliaryTool/TestCaseGenerator
python generate_testcases.py
```
**预期输出:**
```
正在登录: https://192.168.5.44/#/LoginAdmin
✓ 输入账号: admin@xty
✓ 输入密码
✓ 输入验证码: csba
✓ 点击登录按钮 (定位: By.XPATH)
✓ 登录成功
```
---
## 5. 优化功能回填
### 5.1 已完成优化
- [x] 修正XPATH语法错误
- [x] 实现多重登录按钮定位策略(8种方式)
- [x] 增加详细的日志输出
- [x] 添加JavaScript点击备选方案
- [x] 更新问题文档和计划执行文档
### 5.2 待优化
- [ ] 根据实际登录页面结构优化定位器
- [ ] 添加登录失败重试机制
- [ ] 截图保存登录失败现场
---
## 6. 相关文档
### 规范文档
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
- 问题总结: `Docs/PRD/01规范文档/_PRD_问题总结_记录文档.md`
- 方法总结: `Docs/PRD/01规范文档/_PRD_方法总结_记录文档.md`
- 文档规范: `Docs/PRD/01规范文档/_PRD_规范文档_文档规范.md`
- 测试规范: `Docs/PRD/01规范文档/_PRD_规范文档_测试规范.md`
---
*文档结束*
# 计划执行文档 - 登录按钮定位错误修复
## 问题描述
### 问题现象
执行 `generate_testcases.py` 时,在登录页面定位登录按钮失败,程序报错退出。
### 错误信息
```
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:
{"method":"xpath","selector":"//button[contains(text(),'登') or contains(text(),'Login')]"}
```
---
## 根因分析
### 原因1:XPATH语法错误
**问题代码:**
```python
login_btn = self.driver.find_element(By.XPATH, "//button[contains(text(),'登') or contains(text(),'Login')]")
```
**错误原因:**
- XPATH中 `or` 操作符不能直接用于 `contains()` 函数之间
- 正确的XPATH语法应使用 `|` (管道符) 来组合多个条件
### 原因2:定位方式单一
当前代码仅依赖一种定位方式,失败后没有备选方案。
---
## 修复方案
### 方案1:修正XPATH语法
**原代码(错误):**
```python
//button[contains(text(),'登') or contains(text(),'Login')]
```
**修正后(正确):**
```python
//button[contains(text(),'登')] | //button[contains(text(),'Login')]
```
### 方案2:多重定位策略
按优先级尝试多种定位方式:
| 优先级 | 定位方式 | XPATH/CSS |
|--------|----------|-----------|
| 1 | 通过文本内容(中文) | `//button[contains(text(),'登')]"` |
| 2 | 通过文本内容(英文) | `//button[contains(text(),'Login')]"` |
| 3 | 通过class属性 | `//button[contains(@class,'login')]"` |
| 4 | 通过type属性 | `//button[@type='submit']"` |
| 5 | 通过CSS选择器 | `button.el-button--primary` |
---
## 代码实现
### 修复后的登录方法
```python
def login(self, system_info):
"""登录系统"""
url = system_info.get('system_back_url')
username = system_info.get('username')
password = system_info.get('password')
code = system_info.get('code')
print(f" 正在登录: {url}")
self.driver.get(url)
time.sleep(1)
# 处理SSL证书警告
self.handle_ssl_warning()
time.sleep(2)
# 输入账号
try:
username_input = self.wait_for_element(
(By.XPATH, "//input[contains(@placeholder,'账号') or contains(@placeholder,'邮箱') or contains(@placeholder,'手机号')]"),
timeout=5
)
username_input.clear()
username_input.send_keys(username)
print(f" ✓ 输入账号: {username}")
except Exception as e:
print(f" ! 账号输入失败: {e}")
# 尝试其他定位方式
try:
username_input = self.driver.find_element(By.CSS_SELECTOR, "input[type='text']")
username_input.clear()
username_input.send_keys(username)
print(f" ✓ 输入账号(备选方式): {username}")
except:
print(" ✗ 账号输入失败,跳过")
# 输入密码
try:
password_input = self.driver.find_element(By.XPATH, "//input[@type='password']")
password_input.clear()
password_input.send_keys(password)
print(" ✓ 输入密码")
except Exception as e:
print(f" ! 密码输入失败: {e}")
# 输入验证码
try:
# 查找验证码输入框(通常是最后一个输入框)
code_inputs = self.driver.find_elements(By.CSS_SELECTOR, "input[type='text']")
if len(code_inputs) > 0:
code_input = code_inputs[-1]
code_input.clear()
code_input.send_keys(code)
print(f" ✓ 输入验证码: {code}")
except Exception as e:
print(f" ! 验证码输入失败: {e}")
# 点击登录按钮 - 使用多重定位策略
login_success = False
# 策略1: 通过中文文本定位
login_locators = [
# 通过文本内容(使用管道符组合)
(By.XPATH, "//button[contains(text(),'登')] | //button[contains(text(),'Login')]"),
# 通过span标签和文本内容
(By.XPATH, "(//span[contains(text(),'登录')])[1]"),
# 通过input标签的value属性
(By.XPATH, "//input[@value='登 录']"),
# 通过input标签的value属性(英文)
(By.XPATH, "//input[@value='Login']"),
# 通过class属性
(By.XPATH, "//button[contains(@class,'login')]"),
# 通过type属性
(By.XPATH, "//button[@type='submit']"),
# 通过CSS选择器
(By.CSS_SELECTOR, "button.el-button--primary"),
(By.CSS_SELECTOR, "button[type='submit']"),
# 通过任意包含登录class的按钮
(By.CSS_SELECTOR, "button[class*='login']"),
(By.CSS_SELECTOR, "button[class*='Login']"),
# 通过任意包含primary class的按钮
(By.CSS_SELECTOR, "button[class*='primary']"),
]
for locator_type, locator_value in login_locators:
try:
login_btn = self.driver.find_element(locator_type, locator_value)
login_btn.click()
login_success = True
print(f" ✓ 点击登录按钮 (定位方式: {locator_type} = {locator_value})")
break
except:
continue
if not login_success:
print(" ✗ 登录按钮定位失败,尝试通过JavaScript点击")
try:
# 最后的备选方案:通过JavaScript点击
self.driver.execute_script("document.querySelector('button').click()")
login_success = True
print(" ✓ 通过JavaScript点击登录按钮")
except Exception as e:
print(f" ✗ 登录失败: {e}")
raise Exception("无法定位登录按钮,请检查登录页面结构")
time.sleep(3)
print(" ✓ 登录成功")
```
---
## 测试验证
### 验证步骤
1. 运行 `python generate_testcases.py`
2. 观察控制台输出,确认定位方式
3. 确认成功进入系统并生成测试用例
### 预期输出
```
==============================================================
自动化测试用例生成器
==============================================================
✓ 加载系统配置: 1 个
✓ 加载模块配置: 2 个
✓ 浏览器驱动初始化完成
正在登录: https://192.168.5.44/#/LoginAdmin
✓ 输入账号: admin@xty
✓ 输入密码
✓ 输入验证码: csba
✓ 点击登录按钮 (定位方式: By.XPATH = //button[contains(text(),'登')] | //button[contains(text(),'Login')])
✓ 登录成功
...
```
---
## 优化功能回填
### 新增功能
- [x] 修正XPATH语法错误
- [x] 实现多重登录按钮定位策略
- [x] 增加详细的日志输出
- [x] 添加JavaScript点击备选方案
### 待优化
- [ ] 根据实际登录页面结构优化定位器
- [ ] 添加登录失败重试机制
- [ ] 截图保存登录失败现场
---
## 相关文档
- 问题文档: `问题修复/_PRD_程序执行定位登录按钮错误_问题处理.md`
- 代码规范: `Docs/PRD/01规范文档/_PRD_规范文档_代码规范.md`
---
*文档版本:v1.0*
*创建日期:2026-03-06*
*状态:待验证*
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论