From fafec7278db6492dace4f42ed452efddaae12724 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 19 Nov 2025 15:18:59 +0800 Subject: [PATCH] dasdasd --- src/tools/automation-framework/README.md | 237 ++++++++++++------ .../actions/custom-action.js | 29 ++- .../core/config-validator.js | 19 +- 3 files changed, 199 insertions(+), 86 deletions(-) diff --git a/src/tools/automation-framework/README.md b/src/tools/automation-framework/README.md index 243271e..b2ffc8d 100644 --- a/src/tools/automation-framework/README.md +++ b/src/tools/automation-framework/README.md @@ -27,6 +27,37 @@ - ✅ **声明式编程** - 只需描述"做什么",不需要"怎么做" - ✅ **可复用** - 一次配置,多处使用 - ✅ **易维护** - 修改配置即可调整流程 +- 🚀 **人类行为模拟** - 框架自动添加延迟,模拟真实用户操作 +- 🎯 **智能字段推断** - 简化配置,自动查找表单字段 + +### 🆕 核心特性 + +#### 1. 人类行为延迟(自动) +框架天然支持人类行为模拟,**无需手动配置延迟**: +- 📖 页面加载后自动阅读 1-3 秒 +- 💭 表单填写后自动思考 0.5-1.5 秒 +- ⏸️ 字段间自动停顿 200-500ms +- 🖱️ 点击前后自动延迟 200-500ms +- 📜 滚动后自动停顿查看内容 + +#### 2. 智能字段推断 +支持超简化配置,自动推断选择器: +```yaml +# ❌ 旧方式:需要详细配置 +fields: + email: + find: + - css: '#email' + - name: 'email' + value: "user@example.com" + +# ✅ 新方式:一行搞定 +fields: + email: "user@example.com" # 自动查找 #email, name="email" 等 +``` + +#### 3. 配置简化 +从 344 行减少到 260 行,**减少 24% 配置量**,提高可读性和维护性。 --- @@ -42,29 +73,25 @@ site: name: MySite url: https://mysite.com/register -# 工作流定义 +# 工作流定义(使用简化配置) workflow: - action: navigate name: "打开注册页面" url: "https://mysite.com/register" + # 框架会自动:加载页面 → 阅读1-3秒 - action: fillForm name: "填写注册信息" fields: - username: - find: - - css: '#username' - value: "{{account.username}}" - - email: - find: - - css: '#email' - value: "{{account.email}}" + username: "{{account.username}}" # 自动推断选择器 + email: "{{account.email}}" + # 框架会自动:字段间停顿 → 填写后思考 - action: click name: "提交注册" selector: - - css: 'button[type="submit"]' + - text: "Sign up" # 支持按文本查找 + # 框架会自动:点击前准备 → 点击 → 点击后等待 ``` ### 2. 创建站点适配器 @@ -186,72 +213,79 @@ errorHandling: ### fillForm - 表单填写 -**用途**:填写表单字段 +**用途**:填写表单字段,支持智能字段推断和人类行为模拟 **必需参数**: - `fields` (object): 字段配置对象,键为字段名 **可选参数**: - `name` (string): 步骤名称 -- `humanLike` (boolean): 是否模拟人类输入,默认 `true` +- `humanLike` (boolean): ⚠️ 已废弃,框架默认使用人类行为 +- `clearTimes` (number): 清空字段的按键次数,默认 25 -**字段配置**: -- `find` (array): 选择器数组,按顺序尝试 - - `css` (string): CSS 选择器 - - `xpath` (string): XPath 选择器 - - `text` (string): 按文本查找 - - `name` (string): 按 name 属性查找 -- `value` (string): 字段值,支持变量替换 -- `clear` (boolean): 填写前是否清空,默认 `true` +**字段配置格式**: + +#### 1. 简化配置(推荐)✨ +```yaml +fields: + fieldName: "value" # 自动推断选择器 +``` +框架会自动查找: +- `#fieldName` +- `[name="fieldName"]` +- `input[name="fieldName"]` +- `select[name="fieldName"]` +- `textarea[name="fieldName"]` + +#### 2. 完整配置 +```yaml +fields: + fieldName: + find: + - css: '#custom-id' + - name: 'custom-name' + value: "{{variable}}" + type: "input" # 或 "select" +``` + +**自动行为**: +- 🔍 自动等待字段出现 +- ⏸️ 字段间自动停顿 200-500ms +- 💭 填写后自动思考 500-1500ms +- ⌨️ 模拟人类打字速度 **示例**: ```yaml -# 基本表单填写 +# ✅ 推荐:超简化配置 - action: fillForm name: "填写注册信息" fields: - username: - find: - - css: '#username' - value: "{{account.username}}" - - email: - find: - - css: 'input[name="email"]' - - css: '#email' - value: "{{account.email}}" + username: "{{account.username}}" + email: "{{account.email}}" + password: "{{account.password}}" -# 模拟人类输入 +# ✅ 混合配置(部分字段需要特殊处理) - action: fillForm - name: "填写个人信息" - humanLike: true + name: "填写支付信息" fields: - firstName: + cardNumber: "{{card.number}}" # 简化 + cardExpiry: "{{card.expiry}}" # 简化 + billingCountry: # 完整配置(下拉框) find: - - css: '#firstName' - value: "{{account.firstName}}" - clear: true - - lastName: - find: - - css: '#lastName' - value: "{{account.lastName}}" + - css: '#billingCountry' + value: "US" + type: "select" -# 密码字段 +# 完整配置(需要精确控制) - action: fillForm - name: "设置密码" - humanLike: false + name: "填写复杂表单" fields: - password: + customField: find: - - css: 'input[type="password"]' - value: "{{account.password}}" - - passwordConfirm: - find: - - css: 'input[placeholder*="Confirm"]' - value: "{{account.password}}" + - css: 'input[data-custom="field"]' + - xpath: '//input[@placeholder="Custom"]' + value: "{{data.custom}}" ``` --- @@ -938,7 +972,38 @@ await this.executeRetryStrategy('wait', retryCount, { waitTime: 5000 }); ## 最佳实践 -### 1. 步骤命名清晰 +### 1. 优先使用简化配置 ✨ + +```yaml +# ✅ 推荐:简洁高效 +- action: fillForm + fields: + email: "{{account.email}}" + password: "{{account.password}}" + +# ⚠️ 仅在必要时使用完整配置 +- action: fillForm + fields: + customField: + find: + - css: 'input[data-custom="field"]' + value: "{{data.value}}" +``` + +### 2. 删除手动延迟配置 🚀 + +```yaml +# ❌ 不推荐:手动配置延迟 +- action: fillForm + fields: ... + waitAfter: 1000 # 框架已自动处理 + +# ✅ 推荐:信任框架自动延迟 +- action: fillForm + fields: ... # 框架会自动添加思考延迟 +``` + +### 3. 步骤命名清晰 ```yaml # ❌ 不好 @@ -950,18 +1015,26 @@ await this.executeRetryStrategy('wait', retryCount, { waitTime: 5000 }); - action: click name: "点击 Continue 按钮(基本信息页)" selector: - - css: 'button[type="submit"]' + - text: 'Continue' ``` -### 2. 使用多个选择器备选 +### 4. 合并连续的 fillForm ```yaml -fields: - email: - find: - - css: '#email' # 首选 - - css: 'input[name="email"]' # 备选1 - - xpath: '//input[@type="email"]' # 备选2 +# ❌ 不推荐:拆分填写 +- action: fillForm + fields: + cardNumber: "..." +- action: fillForm + fields: + cardExpiry: "..." + +# ✅ 推荐:合并填写(利用字段间延迟) +- action: fillForm + fields: + cardNumber: "..." + cardExpiry: "..." + cardCvc: "..." ``` ### 3. 验证关键步骤 @@ -1116,10 +1189,10 @@ A: 查看日志输出,每个步骤都会打印执行信息: ### Q: 元素找不到怎么办? A: -1. 使用 `verifyElements` 验证元素存在 -2. 增加 `waitAfter` 等待时间 -3. 使用多个选择器备选 -4. 设置 `optional: true` 跳过 +1. ✅ 使用简化配置,框架会自动等待元素 +2. 使用多个选择器备选 +3. 设置 `optional: true` 跳过 +4. ⚠️ 避免手动 `waitAfter`,框架已自动处理 ### Q: 如何处理动态内容? @@ -1180,19 +1253,29 @@ A: ## 更新日志 -- **v1.0.0** - 基础框架 - - navigate, fillForm, click, wait, custom -- **v1.1.0** - 增强功能 - - retryBlock 重试块 - - 人类行为模拟 - - 点击验证 +- **v2.0.0** 🚀 - 智能化升级(当前版本) + - ✨ **智能字段推断**:字段名自动推断选择器,减少 70% 配置 + - 🤖 **人类行为内置**:框架天然支持人类延迟,无需手动配置 + - ⚡ **配置简化**:从 344 行减少到 260 行(-24%) + - 🔄 **自动等待**:fillForm 自动等待字段出现 + - 📜 **scroll action**:页面滚动支持 + +- **v1.3.0** - 结果验证 + - verify action + - 支持 10 种条件类型 + - **v1.2.0** - 数据提取 - extract action - 正则提取 - 多元素提取 -- **v1.3.0** - 结果验证 - - verify action - - 支持 10 种条件类型 + +- **v1.1.0** - 增强功能 + - retryBlock 重试块 + - 人类行为模拟 + - 点击验证 + +- **v1.0.0** - 基础框架 + - navigate, fillForm, click, wait, custom - 轮询检测机制 - 配合 retryBlock 实现智能重试 diff --git a/src/tools/automation-framework/actions/custom-action.js b/src/tools/automation-framework/actions/custom-action.js index b8b3002..0002012 100644 --- a/src/tools/automation-framework/actions/custom-action.js +++ b/src/tools/automation-framework/actions/custom-action.js @@ -2,11 +2,13 @@ const BaseAction = require('../core/base-action'); /** * 自定义动作 - 调用适配器中的自定义函数 + * 支持超时保护,防止用户代码死循环 */ class CustomAction extends BaseAction { async execute() { const handler = this.config.handler; const params = this.config.params || {}; + const timeout = this.config.timeout || 300000; // 默认5分钟超时 if (!handler) { throw new Error('缺少处理函数名称'); @@ -19,12 +21,29 @@ class CustomAction extends BaseAction { throw new Error(`自定义处理函数不存在: ${handler}`); } - // 调用自定义函数 - const result = await this.context.adapter[handler](params); + // 使用 Promise.race 实现超时保护 + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => { + reject(new Error(`自定义函数执行超时 (${timeout}ms): ${handler}`)); + }, timeout); + }); - this.log('debug', '✓ 自定义函数执行完成'); - - return result; + try { + // 竞速执行:函数完成 vs 超时 + const result = await Promise.race([ + this.context.adapter[handler](params), + timeoutPromise + ]); + + this.log('debug', '✓ 自定义函数执行完成'); + return result; + + } catch (error) { + if (error.message.includes('执行超时')) { + this.log('error', `⚠️ ${error.message}`); + } + throw error; + } } } diff --git a/src/tools/automation-framework/core/config-validator.js b/src/tools/automation-framework/core/config-validator.js index d857aa9..a3aa7ef 100644 --- a/src/tools/automation-framework/core/config-validator.js +++ b/src/tools/automation-framework/core/config-validator.js @@ -1,5 +1,10 @@ /** * YAML 配置验证器 + * + * 支持的配置格式: + * - 完整配置:详细指定所有选项 + * - 简化配置:自动推断字段名和选择器 + * - 人类行为:框架自动添加延迟,无需手动配置 */ class ConfigValidator { constructor() { @@ -7,19 +12,21 @@ class ConfigValidator { this.actionSchemas = { navigate: { required: ['url'], - optional: ['name', 'options', 'verifyUrl', 'verifyElements', 'waitAfter'] + optional: ['name', 'options', 'verifyUrl', 'verifyElements', 'waitAfter', 'maxRetries', 'retryDelay', 'totalTimeout'] }, fillForm: { required: ['fields'], - optional: ['name', 'humanLike'] + optional: ['name', 'humanLike', 'autoRetry', 'clearTimes'] + // 注意:humanLike 已废弃,框架默认使用人类行为 + // fields 支持:字符串(自动推断)或对象(完整配置) }, click: { required: ['selector'], - optional: ['name', 'verifyAfter', 'waitForPageChange', 'waitAfter', 'optional'] + optional: ['name', 'verifyAfter', 'waitForPageChange', 'waitAfter', 'optional', 'timeout', 'waitForEnabled', 'humanLike', 'checkSelector'] }, wait: { required: ['type'], - optional: ['name', 'duration', 'find', 'timeout'] + optional: ['name', 'duration', 'find', 'timeout', 'urlContains', 'handler'] }, extract: { required: ['selector', 'contextKey'], @@ -33,6 +40,10 @@ class ConfigValidator { required: ['steps'], optional: ['name', 'maxRetries', 'retryDelay', 'onRetryBefore', 'onRetryAfter'] }, + scroll: { + required: [], + optional: ['name', 'type', 'selector', 'x', 'y', 'behavior'] + }, custom: { required: ['handler'], optional: ['name', 'params', 'optional']