# 微信开发者工具自动化工作流

## 连接策略

### 首次连接
```
connect_devtools（strategy: "auto"）
```
auto 策略会依次尝试：发现已运行实例 → 通过 CLI 启动 → ws 直连。

### 连接失败排查
1. `check_environment` — 检查 CLI 路径、项目路径是否正确
2. `diagnose_connection` — 检查端口、进程状态
3. 确认开发者工具「设置 → 安全 → 服务端口」已开启

### 重连
```
reconnect_devtools  // 复用上次参数
```

## 页面导航模式

### 普通页面跳转
```
navigate_to(url: "/pages/task/task-list/index", params: { status: "pending" })
```

### TabBar 页面
```
switch_tab(url: "/pages/index/index")
```
注意：`navigate_to` 无法跳转 TabBar 页面，必须用 `switch_tab`。

### 重启并跳转
```
relaunch(url: "/pages/index/index")
```
清空页面栈，适合需要干净状态的场景。

### 返回
```
navigate_back(delta: 1)  // 返回上一页
navigate_back(delta: 2)  // 返回两层
```

## 元素操作最佳实践

### 操作流程（必须遵循）
1. `get_page_snapshot` 获取当前页面所有元素的 uid
2. 从快照中找到目标元素的 uid
3. 用 uid 执行操作（click / input_text / get_value / assert_*）

### 快照格式选择
- `compact`（默认推荐）：含 uid、标签、文本、位置、尺寸，token 用量减少 60-70%
- `minimal`：只含 uid、标签、文本，最省 token
- `json`：完整 JSON，需要属性详情时用

### CSS 选择器查找
```
$("view.container")     // 类名
$("#myId")              // ID
$("text=按钮")          // 文本匹配
```
返回匹配元素的详细信息，适合精确定位。

### 输入文本
```
input_text(uid: "xxx", text: "测试内容")
input_text(uid: "xxx", text: "追加内容", append: true)
input_text(uid: "xxx", text: "新内容", clear: true)  // 先清空再输入
```

### 表单控件
```
set_form_control(uid: "xxx", value: 2)          // picker 选第3项
set_form_control(uid: "xxx", value: true)        // switch 开启
set_form_control(uid: "xxx", value: 50)          // slider 设为50
```

## 断言验证

### 文本断言
```
assert_text(uid: "xxx", text: "精确匹配")
assert_text(uid: "xxx", textContains: "包含")
assert_text(uid: "xxx", textMatches: "\\d{4}-\\d{2}-\\d{2}")  // 正则
```

### 状态断言
```
assert_state(uid: "xxx", visible: true)
assert_state(uid: "xxx", enabled: false)
assert_state(uid: "xxx", checked: true)
```

### 属性断言
```
assert_attribute(uid: "xxx", attributeKey: "class", attributeValue: "active")
```

## JS 执行

### 读取页面数据
```javascript
evaluate_script({
  function: "() => { const pages = getCurrentPages(); return pages[pages.length-1].data; }"
})
```

### 读取全局数据
```javascript
evaluate_script({
  function: "() => { return getApp().globalData; }"
})
```

### 调用 wx API
```javascript
evaluate_script({
  function: "() => { return wx.getSystemInfoSync(); }"
})
```

### 带参数执行
```javascript
evaluate_script({
  function: "(key) => { return wx.getStorageSync(key); }",
  args: ["userToken"]
})
```

## 截图与视觉验证

### 保存截图到文件
```
screenshot(path: "C:/Project/NeoZQYY/export/screenshots/task-list.png")
```

### 配合 pixel-audit Power 做视觉对比
1. H5 页面用 Playwright 截图
2. MP 页面用 `screenshot` 截图
3. 用 `image-compare`（已集成在 pixel-audit）对比差异

## 网络请求监控

### 查看请求
```
get_network_requests(urlPattern: "api/v1/tasks", limit: 10)
get_network_requests(type: "request", successOnly: true)
```

### 清空并重新监控
```
clear_network_requests → 执行操作 → get_network_requests
```

## 等待策略

### 等待元素出现
```
waitFor(selector: ".loading", disappear: true, timeout: 10000)  // 等 loading 消失
waitFor(selector: ".task-card", timeout: 5000)                   // 等元素出现
waitFor(text: "加载完成", timeout: 5000)                         // 等文本出现
```

### 固定延时
```
waitFor(delay: 2000)  // 等待 2 秒
```

## 常见问题

| 问题 | 解决方案 |
|------|----------|
| 连接超时 | 检查 9420 端口是否开启，`diagnose_connection` |
| 元素找不到 | 先 `get_page_snapshot` 确认页面已加载完成 |
| navigate_to 失败 | TabBar 页面必须用 `switch_tab` |
| evaluate_script 报错 | 函数不能引用外部闭包变量，必须自包含 |
| 截图空白 | 页面可能还在加载，先 `waitFor` |
