auto-account-machine/src/tools/automation-framework/configs/sites/windsurf.yaml
2025-11-19 17:44:35 +08:00

258 lines
7.8 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Windsurf 注册自动化配置
site:
name: Windsurf
url: https://windsurf.com/account/register
# 工作流定义
workflow:
# ==================== 步骤 1: 打开注册页面并填写信息(带重试) ====================
- action: retryBlock
name: "打开注册页面并填写基本信息"
maxRetries: 3
retryDelay: 3000
steps:
# 1.1 导航到注册页面
- action: navigate
name: "打开注册页面"
url: "https://windsurf.com/account/register"
options:
waitUntil: 'networkidle2'
timeout: 30000
# URL验证确保没有跳转到会员中心
verifyUrl: "/account/register"
# 验证关键元素(确保页面完整加载)
verifyElements:
- '#firstName'
- '#lastName'
- '#email'
- 'input[type="checkbox"]'
# 1.2 填写基本信息
- action: fillForm
name: "填写基本信息"
fields:
firstName: "{{account.firstName}}"
lastName: "{{account.lastName}}"
email: "{{account.email}}"
# 1.3 勾选同意条款
- action: click
name: "勾选同意条款"
selector:
- css: 'input[type="checkbox"]'
optional: true
# 1.4 点击 Continue
- action: click
name: "点击 Continue (基本信息)"
selector:
- text: 'Continue'
selector: 'button, a' # 明确指定查找范围:按钮或链接
timeout: 30000
# 验证点击后密码页面出现
verifyAfter:
appears:
- '#password'
- 'input[type="password"]'
# ==================== 步骤 2: 设置密码 ====================
- action: fillForm
name: "设置密码"
fields:
password: "{{account.password}}"
passwordConfirmation: "{{account.password}}"
- action: click
name: "提交密码"
selector:
- text: 'Continue'
selector: 'button, a'
timeout: 30000
# ==================== 步骤 2.5: Cloudflare Turnstile 验证 ====================
- action: custom
name: "Cloudflare Turnstile 验证"
handler: "handleTurnstile"
params:
timeout: 30000
maxRetries: 3
# 重试策略:
# - 'refresh': 刷新页面(适用于保持状态的网站)
# - 'restart': 刷新后重新填写(适用于刷新=重置的网站,如 Windsurf
# - 'wait': 只等待不刷新
retryStrategy: 'restart' # Windsurf 刷新会回到第一步
optional: true
# ==================== 步骤 3: 邮箱验证 ====================
# 需要自定义处理:获取邮件验证码 + 填写6个输入框
- action: custom
name: "邮箱验证"
handler: "handleEmailVerification"
params:
timeout: 120000
# ==================== 步骤 4: 跳过问卷调查 ====================
- action: click
name: "跳过问卷"
selector:
- text: 'Skip this step'
selector: 'button, a'
- text: 'skip'
selector: 'button, a'
exact: false
# ==================== 步骤 5: 选择计划 ====================
- action: click
name: "选择计划"
selector:
- text: 'Select plan'
selector: 'button, a'
timeout: 30000
# 等待跳转到 Stripe 支付页面(通用 URL 等待)
- action: wait
name: "等待跳转到 Stripe"
type: url
urlContains: "stripe.com"
timeout: 20000
# ==================== 步骤 6: 填写支付信息(带重试) ====================
- action: retryBlock
name: "提交支付并验证"
maxRetries: 9999 # 无限重试,直到成功
retryDelay: 15000 # 增加到15秒避免触发Stripe风控
onRetryBefore:
# 生成银行卡(第一次或重试都生成新卡)
- action: custom
handler: "generateCard"
steps:
# 6.1 选择银行卡支付方式(每次重试都重新选择)
- action: click
name: "选择银行卡支付"
selector:
- css: 'input[type="radio"][value="card"]'
verifyAfter:
checked: true # 验证 radio button 是否选中
# 填写支付信息(银行卡+国家+地址)
- action: fillForm
name: "填写支付信息"
fields:
cardNumber: "{{card.number}}"
cardExpiry: "{{card.month}}{{card.year}}"
cardCvc: "{{card.cvv}}"
billingName: "{{account.firstName}} {{account.lastName}}"
billingCountry:
find:
- css: '#billingCountry'
value: "MO"
type: "select"
addressLine1:
find:
- css: 'input[placeholder*="地址"]'
- css: 'input[placeholder*="Address"]'
value: "kowloon"
# 滚动到页面底部(确保订阅按钮可见)
- action: scroll
name: "滚动到订阅按钮"
type: bottom
# 提交支付(内部会等待按钮变为可点击状态)
- action: click
name: "点击提交支付"
selector:
- css: 'button[data-testid="hosted-payment-submit-button"]'
- css: 'button[type="submit"]'
timeout: 30000 # 给足够时间等待按钮从 disabled 变为可点击
waitForEnabled: true # 循环等待按钮激活(不是等待出现,而是等待可点击)
# 验证点击是否生效(检查按钮状态变化)
- action: custom
name: "验证订阅按钮点击生效"
handler: "verifySubmitClick"
# 处理 hCaptcha等待60秒让用户手动完成
- action: custom
name: "hCaptcha 验证"
handler: "handleHCaptcha"
# 验证支付结果(轮询检测成功或失败)
- action: verify
name: "验证支付结果"
conditions:
success:
- urlNotContains: "stripe.com"
- urlNotContains: "checkout.stripe.com"
failure:
- textContains: "card was declined"
- textContains: "Your card was declined"
- textContains: "declined"
- textContains: "卡片被拒绝"
- textContains: "我们无法验证您的支付方式"
- textContains: "我们未能验证您的支付方式"
- textContains: "请选择另一支付方式并重试"
- elementExists: ".error-message"
timeout: 15000
pollInterval: 500
onFailure: "throw"
# ==================== 步骤 7: 获取订阅信息 ====================
# 7.1 跳转到订阅使用页面
- action: navigate
name: "跳转订阅页面"
url: "https://windsurf.com/subscription/usage"
# 7.2 提取配额信息
- action: extract
name: "提取配额信息"
selector: "p.caption1.font-medium.text-sk-black\\/80 span.caption3 span"
multiple: true
contextKey: "quotaRaw"
required: false
# 7.3 提取账单周期信息
- action: extract
name: "提取账单周期"
selector: "p.caption1"
extractType: "text"
filter:
contains: "Next billing cycle"
regex: "(\\d+)\\s+days?.*on\\s+([A-Za-z]+\\s+\\d+,\\s+\\d{4})"
saveTo:
days: "$1"
date: "$2"
contextKey: "billingInfo"
required: false
# 7.4 处理提取的数据(自定义)
- action: custom
name: "处理订阅数据"
handler: "processSubscriptionData"
optional: true
# ==================== 步骤 8: 保存到数据库 ====================
- action: custom
name: "保存到数据库"
handler: "saveToDatabase"
optional: true
# ==================== 步骤 9: 退出登录 ====================
- action: click
name: "点击退出登录"
selector:
- text: "Log out"
options:
exact: true
caseInsensitive: false
# 错误处理配置
errorHandling:
screenshot: true
retry:
enabled: true
maxAttempts: 3
delay: 2000