This commit is contained in:
dengqichen 2025-11-19 14:58:35 +08:00
parent d2fd4d2b1a
commit 747021896b
2 changed files with 26 additions and 57 deletions

View File

@ -39,20 +39,34 @@ class FillFormAction extends BaseAction {
* 填写单个字段 * 填写单个字段
*/ */
async fillField(key, fieldConfig, humanLike) { async fillField(key, fieldConfig, humanLike) {
let selector, value; let selector, value, fieldType;
// 支持种配置格式 // 支持种配置格式
if (typeof fieldConfig === 'object' && fieldConfig.find) { if (typeof fieldConfig === 'object' && fieldConfig.find) {
// 完整配置: { find: [...], value: "..." } // 完整配置: { find: [...], value: "...", type: "..." }
selector = fieldConfig.find; selector = fieldConfig.find;
value = this.replaceVariables(fieldConfig.value); value = this.replaceVariables(fieldConfig.value);
fieldType = fieldConfig.type;
} else if (typeof fieldConfig === 'string') {
// 超简化配置: { fieldName: "value" }
// 自动推断选择器
selector = [
{ css: `#${key}` },
{ name: key },
{ css: `input[name="${key}"]` },
{ css: `select[name="${key}"]` },
{ css: `textarea[name="${key}"]` }
];
value = this.replaceVariables(fieldConfig);
fieldType = 'input';
} else { } else {
// 简化配置: { selector: value } // 简化配置: { selector: value }(已有的逻辑)
selector = key; selector = key;
value = this.replaceVariables(fieldConfig); value = this.replaceVariables(fieldConfig);
fieldType = 'input';
} }
// 查找元素 // 查找元素(自动等待出现)
const smartSelector = SmartSelector.fromConfig(selector, this.page); const smartSelector = SmartSelector.fromConfig(selector, this.page);
const element = await smartSelector.find(10000); const element = await smartSelector.find(10000);
@ -62,8 +76,10 @@ class FillFormAction extends BaseAction {
this.log('debug', ` → 填写字段: ${key}`); this.log('debug', ` → 填写字段: ${key}`);
// 检查字段类型 // 检查字段类型(已在上面定义)
const fieldType = fieldConfig.type || 'input'; if (!fieldType) {
fieldType = fieldConfig.type || 'input';
}
if (fieldType === 'select') { if (fieldType === 'select') {
// 下拉框选择(需要 CSS 选择器) // 下拉框选择(需要 CSS 选择器)

View File

@ -27,29 +27,14 @@ workflow:
- '#lastName' - '#lastName'
- '#email' - '#email'
- 'input[type="checkbox"]' - 'input[type="checkbox"]'
waitAfter: 5000 # 增加等待时间,让页面完全稳定
# 1.2 填写基本信息 # 1.2 填写基本信息
- action: fillForm - action: fillForm
name: "填写基本信息" name: "填写基本信息"
fields: fields:
firstName: firstName: "{{account.firstName}}"
find: lastName: "{{account.lastName}}"
- css: '#firstName' email: "{{account.email}}"
- name: 'firstName'
value: "{{account.firstName}}"
lastName:
find:
- css: '#lastName'
- name: 'lastName'
value: "{{account.lastName}}"
email:
find:
- css: '#email'
- type: 'email'
value: "{{account.email}}"
# 1.3 勾选同意条款 # 1.3 勾选同意条款
- action: click - action: click
@ -72,13 +57,6 @@ workflow:
- 'input[type="password"]' - 'input[type="password"]'
# ==================== 步骤 2: 设置密码 ==================== # ==================== 步骤 2: 设置密码 ====================
- action: wait
name: "等待密码页面"
type: element
find:
- css: '#password'
timeout: 15000
- action: fillForm - action: fillForm
name: "设置密码" name: "设置密码"
fields: fields:
@ -100,7 +78,6 @@ workflow:
- text: 'Continue' - text: 'Continue'
selector: 'button, a' selector: 'button, a'
timeout: 30000 timeout: 30000
waitAfter: 2000
# ==================== 步骤 2.5: Cloudflare Turnstile 验证 ==================== # ==================== 步骤 2.5: Cloudflare Turnstile 验证 ====================
- action: custom - action: custom
@ -133,7 +110,6 @@ workflow:
- text: 'skip' - text: 'skip'
selector: 'button, a' selector: 'button, a'
exact: false exact: false
waitAfter: 2000
# ==================== 步骤 5: 选择计划 ==================== # ==================== 步骤 5: 选择计划 ====================
- action: click - action: click
@ -142,7 +118,6 @@ workflow:
- text: 'Select plan' - text: 'Select plan'
selector: 'button, a' selector: 'button, a'
timeout: 30000 timeout: 30000
waitAfter: 2000
# 等待跳转到 Stripe 支付页面(通用 URL 等待) # 等待跳转到 Stripe 支付页面(通用 URL 等待)
- action: wait - action: wait
@ -169,15 +144,6 @@ workflow:
- css: 'input[type="radio"][value="card"]' - css: 'input[type="radio"][value="card"]'
verifyAfter: verifyAfter:
checked: true # 验证 radio button 是否选中 checked: true # 验证 radio button 是否选中
waitAfter: 2000
# 等待支付表单加载(每次重试都需要等待)
- action: wait
name: "等待支付表单"
type: element
find:
- css: '#cardNumber'
timeout: 30000
# 填写银行卡信息(使用重新生成的卡号) # 填写银行卡信息(使用重新生成的卡号)
- action: fillForm - action: fillForm
@ -213,11 +179,6 @@ workflow:
value: "MO" value: "MO"
type: "select" type: "select"
# 等待地址字段加载
- action: wait
type: delay
duration: 1000
# 填写地址(动态字段) # 填写地址(动态字段)
- action: fillForm - action: fillForm
name: "填写地址" name: "填写地址"
@ -238,11 +199,6 @@ workflow:
name: "滚动到订阅按钮" name: "滚动到订阅按钮"
type: bottom type: bottom
# 等待页面稳定后再点击
- action: wait
type: delay
duration: 3000
# 提交支付(内部会等待按钮变为可点击状态) # 提交支付(内部会等待按钮变为可点击状态)
- action: click - action: click
name: "点击提交支付" name: "点击提交支付"
@ -251,7 +207,6 @@ workflow:
- css: 'button[type="submit"]' - css: 'button[type="submit"]'
timeout: 30000 # 给足够时间等待按钮从 disabled 变为可点击 timeout: 30000 # 给足够时间等待按钮从 disabled 变为可点击
waitForEnabled: true # 循环等待按钮激活(不是等待出现,而是等待可点击) waitForEnabled: true # 循环等待按钮激活(不是等待出现,而是等待可点击)
waitAfter: 3000 # 点击后等待3秒
# 验证点击是否生效(检查按钮状态变化) # 验证点击是否生效(检查按钮状态变化)
- action: custom - action: custom
@ -288,7 +243,6 @@ workflow:
- action: navigate - action: navigate
name: "跳转订阅页面" name: "跳转订阅页面"
url: "https://windsurf.com/subscription/usage" url: "https://windsurf.com/subscription/usage"
waitAfter: 3000
# 7.2 提取配额信息 # 7.2 提取配额信息
- action: extract - action: extract
@ -332,7 +286,6 @@ workflow:
options: options:
exact: true exact: true
caseInsensitive: false caseInsensitive: false
waitAfter: 2000
# 错误处理配置 # 错误处理配置
errorHandling: errorHandling: