# myclaw 向导系统测试说明

本文档说明如何对 myclaw wizard 系统进行测试，分为两类：
**自动化逻辑测试**（可直接用 `run_command` 执行）和 **交互式 TUI 测试**（需要真实终端）。

---

## 一、自动化逻辑测试

> 适合 AI 使用 `run_command` 工具直接运行，无需用户参与。

### 1.1 运行验证脚本

在 `/Users/yiran/.openclaw/workspace-yiranclaw/myclaw` 目录下写一个临时 `verify.js` 并运行：

```bash
node verify.js
```

验证内容清单（期望全部 ✓）：

| 检查项 | 验证方法 |
|--------|---------|
| `render.js` 的 `getW()` 返回数字 | `typeof getW() === 'number'` |
| `$ref` 展开正常（gateway.steps.json） | `weixin.steps.find(s => s.id === 'restart-gateway')` 不为 null |
| 主向导步骤数 ≥ 8 | `weixin.steps.length >= 8` |
| `bind.config.json` 的 `check-accounts` 有 `capture` 字段 | `step.capture === 'accounts_output'` |
| `bind-account-1` 有 `requires` 字段 | `step.requires` 是数组 |
| `bind-account-1` 有 `show_capture` 字段 | `step.show_capture === 'accounts_output'` |
| `fillTemplate` 替换正确 | `{{account}}` → `wx_123`，`{{agent}}` → `blog` |
| `WizardRunner` 可实例化 | `new WizardRunner(config)` 不抛出 |
| `context.captures` 初始化为空对象 | `typeof runner.context.captures === 'object'` |
| `requires` 未满足时 `_isLocked = true` | `statuses[id] = 'pending'` → locked |
| `requires` 满足后 `_isLocked = false` | `statuses[id] = 'done'` → unlocked |
| 数字键 `3` 跳转至 `cursor = 2` | 模拟 `_onData('3')` |
| `wizards/index.js` 导出 `runWeixin` 函数 | `typeof runWeixin === 'function'` |

### 1.2 验证 stdin pause bug 修复

已知 Node.js 的 `readline.close()` 会内部调用 `stdin.pause()`，导致后续键盘监听失效（历史 bug，已修复）。

```bash
node verify_stdin.js
```

期望输出：
```
readline.close() 前 isPaused: false
readline.close() 后 isPaused: true   ← BUG 根本原因（Node.js 内部行为）
resume()         后 isPaused: false  ← 修复有效
```

**修复位置**：
- `wizards/runner/input-prompt.js`：`collectInputs` 末尾加 `process.stdin.resume()`
- `wizards/runner/wizard-runner.js`：`_runCommand` 里 `setRawMode(true)` 后加 `process.stdin.resume()`

---

## 二、交互式 TUI 测试

> 需要真实终端（TTY），AI 无法用 `run_command` 自动执行。  
> 可使用 `expect` 脚本或让用户手动测试。

### 2.1 前置准备

```bash
cd /Users/yiran/.openclaw/workspace-yiranclaw/myclaw
npm link          # 确保本地 link 最新代码
myclaw            # 确认 CLI 可运行，显示帮助菜单
```

### 2.2 主向导测试（`myclaw weixin`）

```bash
myclaw weixin
```

**期望行为逐项检查：**

| # | 测试操作 | 期望结果 |
|---|---------|---------|
| T1 | 启动后看界面 | 显示步骤列表（8步）+ 说明区，无报错 |
| T2 | 按 `↓` 移动光标 | 光标下移，说明区内容变为下一步说明 |
| T3 | 按 `2` 数字键 | 光标直接跳到第2步（渠道连接状态） |
| T4 | 按 `8` 数字键 | 光标跳到第8步（多账号绑定），步骤显示 `▸ 子向导` 徽章 |
| T5 | 在第8步按 Enter | 进入子向导，界面左上角显示「← q 返回」 |
| T6 | 在子向导按 `q` | 返回主向导（不退出程序） |
| T7 | 在主向导按 `q` | 退出程序，显示「再见！👋」 |
| T8 | 拉伸/缩小终端窗口 | 界面自动重绘，适配新宽度 |

### 2.3 check 类型步骤测试

在主向导（`myclaw weixin`）中：

```
按 1 → Enter（查看微信插件状态）
```

| 步骤 | 期望结果 |
|------|---------|
| 按 Enter 进入 | 显示执行前说明页，包含完整命令 |
| 再按 Enter | 执行 `openclaw plugins list`，cmd 输出透传到终端 |
| 执行完毕 | 显示「✓ 执行完成」，光标自动推进到下一步 |
| 执行结果（check 类） | 账号状态格式为 `configured, enabled`（已绑定）或 `not configured, enabled`（已登录未绑定） |
| 按任意键 | 返回步骤列表，步骤1显示「✓ 完成」徽章 |

### 2.4 input 类型步骤测试（核心，历史有 bug）

进入多账号绑定子向导（主向导按 `8` → Enter）：

```
在子向导按 5 → Enter（绑定账号1 → Agent）
```

| 步骤 | 期望结果 |
|------|---------|
| 按 Enter | 显示说明页 + 命令模板（含 `{{account}}` 占位符） |
| 再按 Enter | 进入参数填写页 |
| 输入账号ID（如 `test-123`）+ 回车 | 提示下一个参数 |
| 输入 Agent 名（如 `blog`）+ 回车 | 进入确认页 |
| **确认页显示** | 完整拼好的命令（`...--account test-123 --agent blog`） |
| **确认页提示** | 「按 **y** 确认执行 \| 按其他键取消（防止误触）」 |
| 按 `y` | **程序保持运行**，执行命令，显示命令输出 |
| 执行完毕（成功/失败都算） | 显示结果，光标推进，按任意键返回步骤列表 |

> ⚠️ **历史 bug（已修复）**：按 `y` 后程序闪退/无响应  
> **原因**：`readline.close()` 会 pause stdin，需显式调用 `resume()`  
> **修复版本**：v1.0.31

### 2.5 requires 前置检查测试

在多账号绑定子向导中，**不执行步骤4**，直接跳到步骤5：

```
按 5（绑定账号1）→ Enter
```

| 期望结果 |
|---------|
| 显示「🔒 前置步骤未完成」警告页 |
| 列出需要先完成的步骤（步骤4） |
| 提示「按 Enter 仍然继续 \| 按 q 返回先完成前置步骤」 |
| 按 `q` 返回步骤列表（步骤5显示 🔒 锁定标记） |

### 2.6 submenu + capture + show_capture 联动测试

在多账号绑定子向导中，按顺序执行：

1. 执行步骤4（查看账号列表）→ 命令输出被捕获
2. 进入步骤5（绑定账号1）→ 说明页后进入参数填写页
3. 参数填写页期望：显示「📋 参考信息（来自上一步执行结果）」区域，内容为步骤4的输出

---

## 三、使用 expect 自动化（可选）

macOS 上可用 `expect` 脚本模拟按键（需 `brew install expect`）：

```tcl
#!/usr/bin/expect -f
set timeout 10

spawn myclaw weixin

# 等待主界面出现
expect "步骤列表"

# 按数字 8 跳转到子向导步骤
send "8"
expect "多账号绑定"

# 进入子向导
send "\r"
expect "q 返回"

# 返回主向导
send "q"
expect "步骤列表"

# 退出
send "q"
expect "再见"
```

运行：
```bash
expect test_wizard.exp
```

> **注意**：`expect` 只适合测试导航流程，input 类型步骤涉及 readline 切换，
> 在 expect 下行为与真实 TTY 有差异，建议手动验证。

---

## 四、常见问题排查

| 现象 | 可能原因 | 检查方式 |
|------|---------|---------|
| 按 y 后程序无响应/退出 | stdin 未 resume | 检查 `input-prompt.js` 末尾是否有 `process.stdin.resume()` |
| 子向导退出后主界面不刷新 | `onExit` 回调未触发 | 检查 `_openSubmenu` 里 `sub.run()` 是否正确传 `onExit` |
| `$ref` 步骤加载失败 | 相对路径解析错误 | 检查 config 的 `_dir` 是否正确注入，`require` 是否用绝对路径 |
| 数字键无效 | `_onData` 中 `parseInt` 判断范围 | 确认步骤数量在 1-9 范围内 |
| 终端 resize 无效 | resize 事件监听器未注册 | 检查 `run()` 里 `process.stdout.on('resize', ...)` |
