提交 46a566f2 authored 作者: 陈泽健's avatar 陈泽健

feat(element-locate): 元素定位功能优化 - API增强 + 配置面板

Phase 1: 后端 API 增强
- 新增 BatchLocateRequest 参数: page_load_timeout, extra_wait_time, wait_for_selector, retry_on_empty, max_retries
- 新增 BatchLocateResponse 字段: elements_extracted, retries, page_load_time
- 增强 _do_locate_with_executor 支持配置参数和重试机制

Phase 2: 微前端元素提取增强
- 优化 extract_interactive_elements 函数,增强元素去重
- 扩展 Element UI/Vuetify/Ant Design 组件支持
- 提取更多元素属性(data-*, title, alt, role 等)

Phase 3: 前端配置面板
- 新增获取定位配置弹窗(支持配置等待时间、重试等参数)
- 新增预览页面按钮
- 优化定位结果显示(元素数量、耗时、重试次数)
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
上级 885b901c
......@@ -300,31 +300,43 @@ function extractInteractiveElements() {
### 8.1 Phase 1 执行记录
**开始时间**:
**结束时间**:
**执行人**:
**完成情况**:
**开始时间**: 2026-08-03
**结束时间**: 2026-08-03
**执行人**: Claude Code
**完成情况**: ✅ 已完成
- 更新 BatchLocateRequest/BatchLocateResponse schema
- 增强 _do_locate_with_executor 支持配置参数和重试机制
- 记录元素数量、重试次数、页面加载耗时
### 8.2 Phase 2 执行记录
**开始时间**:
**结束时间**:
**执行人**:
**完成情况**:
**开始时间**: 2026-08-03
**结束时间**: 2026-08-03
**执行人**: Claude Code
**完成情况**: ✅ 已完成
- 优化 extract_interactive_elements 函数
- 增强元素去重逻辑(多重属性组合 key)
- 扩展 Element UI/Vuetify/Ant Design 组件支持
- 提取更多元素属性(data-*, title, alt, role 等)
### 8.3 Phase 3 执行记录
**开始时间**:
**结束时间**:
**执行人**:
**完成情况**:
**开始时间**: 2026-08-03
**结束时间**: 2026-08-03
**执行人**: Claude Code
**完成情况**: ✅ 已完成
- 新增获取定位配置弹窗
- 支持配置页面加载超时、额外等待时间、等待特定元素
- 新增预览页面按钮
- 优化定位结果显示(元素数量、耗时、重试次数)
- 前端构建验证通过
### 8.4 Phase 4 执行记录
**开始时间**:
**结束时间**:
**执行人**:
**完成情况**:
**开始时间**: 待执行
**结束时间**:
**执行人**:
**完成情况**: ⏳ 待部署验证
---
......
......@@ -2,10 +2,16 @@
> **生成时间**: 2026-08-03
> **当前分支**: `platform-auto-test`
> **最近提交**: `82c6f778` fix(element-locate): 修复批量定位数据库更新问题,延长超时时间
> **状态**: ✅ 元素定位功能完成 + 始终使用 Claude CLI + 前端步骤表格显示优化
> **最近提交**: `待提交` feat(element-locate): 元素定位功能优化 - API增强 + 配置面板
> **状态**: ✅ 元素定位功能优化完成(Phase 1-3)
>
> **本次会话完成**:
> - ✅ Phase 1: 后端 API 增强 — 新增 5 个配置参数 + 3 个响应字段 + 重试机制
> - ✅ Phase 2: 微前端元素提取增强 — 扩展 Element UI/Vuetify/Ant Design 组件支持
> - ✅ Phase 3: 前端配置面板 — 获取定位配置弹窗 + 预览页面功能
> - ✅ 前端构建验证通过
>
> **上次会话完成**:
> - ✅ 修复步骤表格不显示定位信息问题(新增"定位类型"和"定位值"列)
> - ✅ 去掉置信度判断,始终调用 Claude CLI 进行元素匹配
> - ✅ 修复批量定位数据库更新失败问题
......@@ -13,8 +19,6 @@
> - ✅ 优化微前端元素提取(支持 shadow DOM + Element UI 组件)
> - ✅ 优化 Claude CLI 调用(直接传递元素列表,不再让宿主机重新访问页面)
> - ✅ 创建测试用例验证闭环(登录成功 8/8,会议列表 2/7)
> - ✅ 生成优化需求文档和计划执行文档
> - ✅ 代码提交并推送到远程仓库
---
......@@ -197,7 +201,12 @@
{
"case_id": "case_xxx",
"page_url": "https://192.168.5.44/",
"auto_login": true
"auto_login": true,
"page_load_timeout": 10000, // 可选:页面加载超时(毫秒)
"extra_wait_time": 5000, // 可选:额外等待时间(毫秒)
"wait_for_selector": "", // 可选:等待特定元素(CSS选择器)
"retry_on_empty": true, // 可选:元素为空时重试
"max_retries": 2 // 可选:最大重试次数
}
```
......@@ -219,7 +228,10 @@
"message": "置信度 95%"
}
],
"message": "成功定位 5/6 个步骤"
"message": "成功定位 5/6 个步骤",
"elements_extracted": 42, // 新增:提取到的元素总数
"retries": 0, // 新增:实际重试次数
"page_load_time": 12.5 // 新增:页面加载耗时(秒)
}
```
......@@ -240,7 +252,7 @@
| 优先级 | 任务 | 说明 |
|--------|------|------|
| 🔴 **P0** | 元素定位功能优化 | 按已生成的 PRD 和计划执行文档实施优化 |
| 🔴 **P0** | 部署到服务器 | 前端已构建,需上传到 192.168.5.60 并验证 |
| 🟡 **P1** | 设备模拟模块联调 | MQTT 环境配置与联调待验证 |
| 🟢 **P2** | 清理临时脚本 | 根目录大量探索脚本和部署脚本待清理 |
| 🟢 **P2** | Phase 5 剩余 | Pinia 状态管理、单元测试 |
......
......@@ -64,6 +64,16 @@ export interface BatchLocateRequest {
page_url?: string
/** 是否自动登录(默认 true) */
auto_login?: boolean
/** 页面加载超时时间(毫秒,默认 10000) */
page_load_timeout?: number
/** 页面加载后额外等待时间(毫秒,默认 5000) */
extra_wait_time?: number
/** 等待特定元素出现(CSS选择器) */
wait_for_selector?: string
/** 元素为空时是否重试(默认 true) */
retry_on_empty?: boolean
/** 最大重试次数(默认 2) */
max_retries?: number
}
/**
......@@ -102,6 +112,12 @@ export interface BatchLocateResponse {
results: StepLocateResult[]
/** 消息 */
message: string
/** 提取到的元素总数 */
elements_extracted?: number
/** 实际重试次数 */
retries?: number
/** 页面加载耗时(秒) */
page_load_time?: number
}
/**
......
......@@ -188,7 +188,7 @@
size="small"
type="success"
link
@click="batchLocate(row)"
@click="showLocateConfig(row)"
:loading="locatingCaseId === row.id"
:disabled="row.caseType !== 'ui'"
>
......@@ -217,6 +217,67 @@
</div>
</el-card>
<!-- 获取定位配置弹窗 -->
<el-dialog
v-model="locateConfigVisible"
title="批量获取定位"
width="500px"
destroy-on-close
>
<el-form label-width="120px">
<el-form-item label="用例名称">
<el-input :value="locateConfigCaseName" disabled />
</el-form-item>
<el-divider content-position="left">高级配置</el-divider>
<el-form-item label="页面加载超时">
<el-input-number
v-model="locateConfig.page_load_timeout"
:min="5000"
:max="60000"
:step="5000"
style="width: 150px"
/>
<span style="margin-left: 10px; color: #999">毫秒</span>
</el-form-item>
<el-form-item label="额外等待时间">
<el-input-number
v-model="locateConfig.extra_wait_time"
:min="0"
:max="30000"
:step="1000"
style="width: 150px"
/>
<span style="margin-left: 10px; color: #999">毫秒</span>
</el-form-item>
<el-form-item label="等待特定元素">
<el-input
v-model="locateConfig.wait_for_selector"
placeholder="CSS 选择器(可选)"
style="width: 300px"
/>
</el-form-item>
<el-form-item label="自动重试">
<el-switch v-model="locateConfig.retry_on_empty" />
<span style="margin-left: 10px; color: #999">元素为空时自动重试</span>
</el-form-item>
<el-form-item v-if="locateConfig.retry_on_empty" label="最大重试次数">
<el-input-number
v-model="locateConfig.max_retries"
:min="1"
:max="5"
style="width: 100px"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="previewPage">预览页面</el-button>
<el-button @click="locateConfigVisible = false">取消</el-button>
<el-button type="primary" @click="batchLocate" :loading="locatingCaseId !== ''">
开始获取
</el-button>
</template>
</el-dialog>
<!-- 创建/编辑用例弹窗 -->
<el-dialog
v-model="editDialogVisible"
......@@ -884,6 +945,34 @@ const deleteCase = async (row: any) => {
/** 当前正在获取定位的用例 ID */
const locatingCaseId = ref('')
/** 配置面板相关状态 */
const locateConfigVisible = ref(false)
const locateConfigCaseId = ref('')
const locateConfigCaseName = ref('')
const locateConfig = ref({
page_load_timeout: 10000,
extra_wait_time: 5000,
wait_for_selector: '',
retry_on_empty: true,
max_retries: 2,
})
/**
* 显示获取定位配置面板
*/
const showLocateConfig = (row: any) => {
locateConfigCaseId.value = row.id
locateConfigCaseName.value = row.name
locateConfigVisible.value = true
}
/**
* 预览页面(在新窗口打开已登录的目标页面)
*/
const previewPage = () => {
window.open('https://192.168.5.44/', '_blank')
}
/**
* 一键获取用例所有步骤的元素定位
*
......@@ -893,29 +982,35 @@ const locatingCaseId = ref('')
* 3. 为每个步骤匹配定位器并更新到数据库
* 4. 前端显示结果
*/
const batchLocate = async (row: any) => {
try {
await ElMessageBox.confirm(
`将为用例「${row.name}」的所有步骤自动获取元素定位,是否继续?`,
'批量获取定位',
{ type: 'info', confirmButtonText: '开始获取', cancelButtonText: '取消' }
)
} catch {
return
}
const batchLocate = async () => {
locateConfigVisible.value = false
locatingCaseId.value = locateConfigCaseId.value
locatingCaseId.value = row.id
try {
ElMessage.info('正在启动浏览器获取定位,请稍候...')
const result = await elementLocateApi.locateBatch({
case_id: row.id,
case_id: locateConfigCaseId.value,
page_url: 'https://192.168.5.44/',
auto_login: true,
page_load_timeout: locateConfig.value.page_load_timeout,
extra_wait_time: locateConfig.value.extra_wait_time,
wait_for_selector: locateConfig.value.wait_for_selector || undefined,
retry_on_empty: locateConfig.value.retry_on_empty,
max_retries: locateConfig.value.max_retries,
})
if (result.success) {
const msg = `定位完成:成功 ${result.located_steps}/${result.total_steps} 个步骤`
let msg = `定位完成:成功 ${result.located_steps}/${result.total_steps} 个步骤`
if (result.elements_extracted) {
msg += `,提取 ${result.elements_extracted} 个元素`
}
if (result.page_load_time) {
msg += `,耗时 ${result.page_load_time.toFixed(1)}s`
}
if (result.retries) {
msg += `,重试 ${result.retries} 次`
}
ElMessage.success(msg)
// 刷新用例列表
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论