dasdasd
This commit is contained in:
parent
d2fd4d2b1a
commit
747021896b
@ -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 选择器)
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user