dasdasd
This commit is contained in:
parent
cfd243aeda
commit
fafec7278d
@ -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}}"
|
||||
username: "{{account.username}}"
|
||||
email: "{{account.email}}"
|
||||
password: "{{account.password}}"
|
||||
|
||||
email:
|
||||
find:
|
||||
- css: 'input[name="email"]'
|
||||
- css: '#email'
|
||||
value: "{{account.email}}"
|
||||
|
||||
# 模拟人类输入
|
||||
# ✅ 混合配置(部分字段需要特殊处理)
|
||||
- action: fillForm
|
||||
name: "填写个人信息"
|
||||
humanLike: true
|
||||
name: "填写支付信息"
|
||||
fields:
|
||||
firstName:
|
||||
cardNumber: "{{card.number}}" # 简化
|
||||
cardExpiry: "{{card.expiry}}" # 简化
|
||||
billingCountry: # 完整配置(下拉框)
|
||||
find:
|
||||
- css: '#firstName'
|
||||
value: "{{account.firstName}}"
|
||||
clear: true
|
||||
- css: '#billingCountry'
|
||||
value: "US"
|
||||
type: "select"
|
||||
|
||||
lastName:
|
||||
find:
|
||||
- css: '#lastName'
|
||||
value: "{{account.lastName}}"
|
||||
|
||||
# 密码字段
|
||||
# 完整配置(需要精确控制)
|
||||
- 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
|
||||
# ❌ 不推荐:拆分填写
|
||||
- action: fillForm
|
||||
fields:
|
||||
email:
|
||||
find:
|
||||
- css: '#email' # 首选
|
||||
- css: 'input[name="email"]' # 备选1
|
||||
- xpath: '//input[@type="email"]' # 备选2
|
||||
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 实现智能重试
|
||||
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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']
|
||||
|
||||
Loading…
Reference in New Issue
Block a user