150 lines
3.8 KiB
Markdown
150 lines
3.8 KiB
Markdown
---
|
|
name: uncaged-test
|
|
version: 3.1.0
|
|
description: >
|
|
Uncaged Web UI 场景化测试。场景文件在 uncaged 代码库的 tests/e2e/scenes/,
|
|
subagent 按场景描述自主操作验证。失败时收集 logs 并开 bug issue。
|
|
metadata:
|
|
requiredTools: ["secret"]
|
|
---
|
|
|
|
# Uncaged Test
|
|
|
|
场景化 E2E 测试,设计给 subagent 自主执行。
|
|
|
|
**场景文件在代码库:** `<uncaged-repo>/tests/e2e/scenes/`
|
|
**回归脚本在代码库:** `<uncaged-repo>/tests/e2e/scripts/run-tests.sh`
|
|
|
|
## 使用方式
|
|
|
|
### 验证单个场景
|
|
|
|
```
|
|
读 <uncaged-repo>/tests/e2e/scenes/<场景>.md,按描述验证。失败了收集 logs 开 bug。
|
|
```
|
|
|
|
### 跑全部场景(快速回归)
|
|
|
|
```bash
|
|
bash <uncaged-repo>/tests/e2e/scripts/run-tests.sh [TOKEN_NAME]
|
|
```
|
|
|
|
### 可用场景
|
|
|
|
| 场景文件 | 说明 |
|
|
|:---------|:-----|
|
|
| `scenes/auth.md` | 认证:token 登录、session、refresh |
|
|
| `scenes/chat.md` | 聊天:发消息、历史、清空 |
|
|
| `scenes/streaming.md` | SSE 流式响应 |
|
|
| `scenes/tool-gateway.md` | Tool Gateway:builtin 列表、invoke |
|
|
| `scenes/tool-search.md` | 输入框工具搜索(本地过滤) |
|
|
| `scenes/error-handling.md` | 异常处理:401、404、429 |
|
|
|
|
## 环境准备
|
|
|
|
### 登录获取 cookies
|
|
|
|
```bash
|
|
TOKEN=$(secret get UNCAGED_AGENT_TOKEN_XINGYUE)
|
|
curl -s -X POST "https://uncaged.shazhou.work/auth/token" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"token\": \"$TOKEN\"}" \
|
|
-c /tmp/uncaged-cookies.txt
|
|
```
|
|
|
|
### 常量
|
|
|
|
```
|
|
BASE_URL = https://uncaged.shazhou.work
|
|
AGENT_PATH = /scott/doudou
|
|
COOKIES = /tmp/uncaged-cookies.txt
|
|
REPO = oc-xiaoju/uncaged
|
|
```
|
|
|
|
## 失败处理
|
|
|
|
### 1. 收集 Worker 日志
|
|
|
|
```bash
|
|
CF_TOKEN=$(secret get CLOUDFLARE_API_TOKEN)
|
|
CF_ACCOUNT=$(secret get CLOUDFLARE_ACCOUNT_ID)
|
|
cd <uncaged-repo>/packages/worker
|
|
|
|
CLOUDFLARE_API_TOKEN="$CF_TOKEN" CLOUDFLARE_ACCOUNT_ID="$CF_ACCOUNT" \
|
|
npx wrangler tail --format json > /tmp/worker-logs.json 2>/dev/null &
|
|
sleep 3
|
|
# 复现失败请求
|
|
# ...
|
|
sleep 10; kill %1 2>/dev/null
|
|
|
|
python3 -c "
|
|
import sys, json
|
|
for line in open('/tmp/worker-logs.json'):
|
|
try:
|
|
e = json.loads(line.strip())
|
|
logs, excs = e.get('logs',[]), e.get('exceptions',[])
|
|
status = e.get('event',{}).get('response',{}).get('status','?')
|
|
if logs or excs or (isinstance(status,int) and status >= 400):
|
|
url = e.get('event',{}).get('request',{}).get('url','?')
|
|
print(f'[{status}] {url}')
|
|
for l in logs: print(f' LOG: {l.get(\"message\",l)}')
|
|
for x in excs: print(f' ERR: {x.get(\"message\",x)}')
|
|
except: pass
|
|
"
|
|
```
|
|
|
|
### 2. 收集前端状态
|
|
|
|
```bash
|
|
curl -s https://uncaged.shazhou.work/auth/session -b /tmp/uncaged-cookies.txt | python3 -m json.tool
|
|
curl -s https://uncaged.shazhou.work/scott/doudou/api/history -b /tmp/uncaged-cookies.txt | python3 -c "
|
|
import sys,json
|
|
for m in json.load(sys.stdin).get('history',[])[-3:]:
|
|
print(f' [{m[\"role\"]}] {str(m.get(\"content\",\"\"))[:100]}')
|
|
"
|
|
```
|
|
|
|
### 3. 开 Bug Issue
|
|
|
|
```bash
|
|
gh issue create --repo oc-xiaoju/uncaged \
|
|
--title "bug: <简短描述>" \
|
|
--body "## Bug Report
|
|
|
|
### 场景
|
|
<场景文件 + 步骤>
|
|
|
|
### 期望
|
|
<应该发生什么>
|
|
|
|
### 实际
|
|
<实际发生了什么>
|
|
|
|
### 复现
|
|
\`\`\`bash
|
|
<curl 命令>
|
|
\`\`\`
|
|
|
|
### Worker 日志
|
|
\`\`\`
|
|
<日志>
|
|
\`\`\`
|
|
|
|
---
|
|
*Auto-generated by uncaged-test skill*" \
|
|
--label "bug"
|
|
```
|
|
|
|
## API 速查
|
|
|
|
| 端点 | 方法 | 说明 |
|
|
|:-----|:-----|:-----|
|
|
| `/auth/token` | POST | Token 登录 |
|
|
| `/auth/session` | GET | 检查 session |
|
|
| `/auth/refresh` | POST | 刷新 token |
|
|
| `/:o/:a/api/chat` | POST | 发消息(⚠️ 不是 /api/v1/chat) |
|
|
| `/:o/:a/api/chat/stream` | POST | SSE 流式 |
|
|
| `/:o/:a/api/history` | GET | 历史记录 |
|
|
| `/:o/:a/api/v1/tools/builtin` | GET | Builtin 工具列表 |
|
|
| `/:o/:a/api/v1/tools/:slug/invoke` | POST | 直接调用工具 |
|