This commit is contained in:
dengqichen 2025-11-18 21:53:17 +08:00
parent 331fd8e4bd
commit 4309e8aadf

View File

@ -595,10 +595,52 @@ selector:
- urlNotContains: "stripe.com"
failure:
- textContains: "declined"
- textContains: "card was declined"
timeout: 10000
pollInterval: 500
onFailure: "throw"
```
**执行流程示例**
```
第1次尝试
├─ 填写卡号: 4111111111111111
├─ 处理验证码
├─ 提交支付
└─ verify 检测
└─ 发现 "declined" ❌
└─ throw Error ⚡
└─ retryBlock 捕获 → 重试 1/5
第2次尝试
├─ regenerateCard() 生成新卡: 4242424242424242
├─ 填写新卡号: 4242424242424242
├─ 处理验证码
├─ 提交支付
└─ verify 检测
└─ URL 不包含 "stripe.com" ✅
└─ 成功!继续下一步
总结尝试了2次第2次成功流程继续
```
**日志输出示例**
```log
[Windsurf] [验证支付结果]
[windsurf] ✗ 验证失败: 页面包含文本: "card was declined"
[windsurf] ⚠ WARNING: 步骤失败,触发重试 (1/5)
[windsurf] 执行重试前钩子...
[windsurf] 重新生成银行卡...
[windsurf] ✓ 新卡号: 4242424242424242
[windsurf] 重新执行步骤...
[Windsurf] [填写银行卡信息]
[Windsurf] [验证支付结果]
[windsurf] ✓ 验证成功: URL 不包含 "stripe.com"
[windsurf] 支付流程完成!
```
---
### retryBlock - 重试块
@ -998,12 +1040,56 @@ fields:
...
```
### 7. 代码vs配置的选择
### 7. 使用 verify + retryBlock 实现智能重试
```yaml
# ✅ 最佳实践:将需要重试的步骤放在 retryBlock 内
# hCaptcha 等验证码只处理一次(放在 retryBlock 外)
- action: custom
handler: "handleCaptcha"
# 支付提交和验证放在 retryBlock 内
- action: retryBlock
maxRetries: 5
onRetryBefore:
- action: custom
handler: "regenerateCard"
steps:
- action: fillForm
fields:
cardNumber:
value: "{{card.number}}"
- action: click
selector:
- css: "#submit"
# verify 失败会触发重试
- action: verify
conditions:
success:
- urlNotContains: "payment"
failure:
- textContains: "declined"
onFailure: "throw"
# ❌ 避免:把验证码放在 retryBlock 内
# 会导致每次重试都要处理验证码
```
**关键点**
- ✅ 只重试必要的步骤(填表 + 提交 + 验证)
- ✅ 一次性步骤放在 retryBlock 外(验证码、页面导航)
- ✅ 用 `verify` 检测结果,`onFailure: "throw"` 触发重试
- ✅ 用 `onRetryBefore` 重新生成数据(如新卡号)
### 8. 代码vs配置的选择
| 场景 | 推荐方式 | 原因 |
|------|---------|------|
| 点击、填表、等待 | YAML | 简单、可维护 |
| 数据提取 | YAML (extract) + 处理(custom) | 提取配置化,处理逻辑化 |
| 结果验证 | YAML (verify) | 轮询检测、触发重试 |
| 验证码、人机验证 | custom | 复杂逻辑 |
| 条件判断、循环 | custom | YAML 不支持 |
| 数据库操作 | custom | 需要导入模块 |
@ -1053,6 +1139,43 @@ A: 检查:
2. 是否在 `beforeWorkflow()` 中设置了 `this.context.data`
3. 日志中查看变量值
### Q: verify 失败会终止整个流程吗?
A: **不会!**
- 在 `retryBlock` 内使用 `onFailure: "throw"`,失败会触发重试
- 只有所有重试都失败,才会终止流程
- 单次失败只是触发重试,不影响整体流程
### Q: 如何避免重试时重复处理验证码?
A: 将验证码处理放在 `retryBlock` 外面:
```yaml
# ✅ 正确:验证码只处理一次
- action: custom
handler: "handleCaptcha"
- action: retryBlock
steps:
- 填写表单
- 提交
- 验证
# ❌ 错误:每次重试都处理验证码
- action: retryBlock
steps:
- action: custom
handler: "handleCaptcha"
- 填写表单
- 提交
```
### Q: verify 的 timeout 和 retryBlock 的 maxRetries 有什么区别?
A:
- **verify 的 timeout**单次验证的轮询时间如检测支付结果15秒
- **retryBlock 的 maxRetries**失败后重试的次数如支付失败重试5次
- 总耗时 ≈ `timeout × maxRetries`(如 15秒 × 5次 = 75秒
---
## 更新日志