Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 62ff682769 | |||
| 53c31d435d | |||
| a9d5af63be | |||
| 3516eb6918 | |||
| 0c9375ff32 | |||
| ef344e9ffc | |||
| 0d4904433e | |||
| 708662394f | |||
| 9b034764ad | |||
| 8748b43070 | |||
| d213a055a1 | |||
| 2371860f82 | |||
| dbd956fc6e | |||
| 1d59ee5336 |
@@ -266,6 +266,28 @@ jobs:
|
||||
-w /workspace/apps/web \
|
||||
docker.m.daocloud.io/library/node:20 \
|
||||
sh -lc 'npx vitest run src/test'
|
||||
|
||||
- name: Run npm audit (high severity)
|
||||
continue-on-error: true
|
||||
shell: sh
|
||||
run: |
|
||||
set +e
|
||||
echo "=== npm audit 检查 (high 级别及以上) ==="
|
||||
docker run --rm \
|
||||
-v "$PWD:/workspace" \
|
||||
-w /workspace/apps/web \
|
||||
docker.m.daocloud.io/library/node:20 \
|
||||
sh -lc 'npm audit --audit-level=high'
|
||||
AUDIT_EXIT=$?
|
||||
if [ "$AUDIT_EXIT" -ne 0 ]; then
|
||||
echo ""
|
||||
echo "⚠️ npm audit 发现 high 级别漏洞,请关注(当前为告警模式,不阻断 CI)"
|
||||
echo "建议后续根据存量漏洞情况决定是否设置为阻断"
|
||||
else
|
||||
echo "✅ npm audit 未发现 high 级别漏洞"
|
||||
fi
|
||||
exit 0
|
||||
|
||||
deploy-staging:
|
||||
name: Build & Push Staging (Watchtower auto-deploy)
|
||||
runs-on: saas
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
name: Test SSH Secret
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
paths:
|
||||
- '.gitea/workflows/test-ssh-secret.yml'
|
||||
|
||||
jobs:
|
||||
test-ssh:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install SSH client
|
||||
run: |
|
||||
which ssh || (apt-get update && apt-get install -y openssh-client)
|
||||
ssh -V
|
||||
|
||||
- name: Debug environment
|
||||
run: |
|
||||
echo "=== Environment ==="
|
||||
echo "Runner hostname: $(hostname)"
|
||||
echo "Runner IP: $(hostname -i || echo 'unknown')"
|
||||
echo "Current user: $(whoami)"
|
||||
echo "=== Secrets check ==="
|
||||
if [ -n "$STAGING_SSH_HOST" ]; then
|
||||
echo "STAGING_SSH_HOST: [SET] value_length=${#STAGING_SSH_HOST}"
|
||||
else
|
||||
echo "STAGING_SSH_HOST: [EMPTY]"
|
||||
fi
|
||||
if [ -n "$STAGING_SSH_USER" ]; then
|
||||
echo "STAGING_SSH_USER: [SET] value_length=${#STAGING_SSH_USER}"
|
||||
else
|
||||
echo "STAGING_SSH_USER: [EMPTY]"
|
||||
fi
|
||||
if [ -n "$STAGING_SSH_KEY" ]; then
|
||||
echo "STAGING_SSH_KEY: [SET] value_length=${#STAGING_SSH_KEY}"
|
||||
else
|
||||
echo "STAGING_SSH_KEY: [EMPTY]"
|
||||
fi
|
||||
env:
|
||||
STAGING_SSH_HOST: ${{ secrets.STAGING_SSH_HOST }}
|
||||
STAGING_SSH_USER: ${{ secrets.STAGING_SSH_USER }}
|
||||
STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }}
|
||||
|
||||
- name: Setup SSH key
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
echo "$STAGING_SSH_KEY" > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub 2>/dev/null || echo "No public key generated"
|
||||
echo "=== SSH Key fingerprint ==="
|
||||
ssh-keygen -lf ~/.ssh/id_ed25519 || echo "Key fingerprint failed"
|
||||
env:
|
||||
STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }}
|
||||
|
||||
- name: Test SSH connection
|
||||
run: |
|
||||
echo "Attempting SSH connection to $STAGING_SSH_HOST..."
|
||||
ssh -i ~/.ssh/id_ed25519 \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o ConnectTimeout=10 \
|
||||
-o BatchMode=yes \
|
||||
-v \
|
||||
$STAGING_SSH_USER@$STAGING_SSH_HOST "echo 'SSH_CONNECTION_SUCCESS' && hostname && whoami"
|
||||
echo "=== SSH Test Complete ==="
|
||||
env:
|
||||
STAGING_SSH_HOST: ${{ secrets.STAGING_SSH_HOST }}
|
||||
STAGING_SSH_USER: ${{ secrets.STAGING_SSH_USER }}
|
||||
@@ -0,0 +1,289 @@
|
||||
# 前端冒烟测试用例清单
|
||||
|
||||
> 版本:v1.0
|
||||
> 更新日期:2026-07-13
|
||||
> 用途:CI 部署后自动化冒烟测试,验证核心业务流程可用
|
||||
|
||||
---
|
||||
|
||||
## 一、测试分级
|
||||
|
||||
| 级别 | 说明 | 必测场景 | 建议频率 |
|
||||
|------|------|----------|----------|
|
||||
| P0 | 阻断级:核心功能不可用则立即回滚 | 登录、首页加载、API连通性 | 每次部署 |
|
||||
| P1 | 核心业务:主流程关键节点 | 生成、上传、播放、支付 | 每次部署 |
|
||||
| P2 | 重要功能:常用模块 | 各列表页、设置、管理后台 | 每日/版本发布 |
|
||||
|
||||
---
|
||||
|
||||
## 二、P0 级用例(部署必测)
|
||||
|
||||
### 1. 首页加载
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P0-001 |
|
||||
| **路径** | `/` 首页 |
|
||||
| **前置条件** | 无 |
|
||||
| **操作步骤** | 1. 访问首页 URL<br>2. 等待页面加载 |
|
||||
| **预期结果** | 1. HTTP 状态码 200<br>2. 页面标题包含「小虾」或产品名<br>3. 页面有可见内容(非空白)<br>4. 静态资源(JS/CSS)全部加载成功,无 404/500 |
|
||||
| **验证方式** | HTTP 状态码 + DOM 元素存在性检查 |
|
||||
| **对应现有冒烟** | ✅ 已有(Web frontend HTTP 200) |
|
||||
|
||||
### 2. 登录页可用性
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P0-002 |
|
||||
| **路径** | `/login` |
|
||||
| **前置条件** | 无 |
|
||||
| **操作步骤** | 1. 访问登录页<br>2. 验证页面元素存在 |
|
||||
| **预期结果** | 1. 页面正常渲染,无白屏<br>2. 邮箱输入框存在<br>3. 密码输入框存在<br>4. 登录按钮可见<br>5. 注册/忘记密码链接可点击 |
|
||||
| **验证方式** | DOM 元素存在性 + 表单字段检查 |
|
||||
|
||||
### 3. 登录 API 连通性
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P0-003 |
|
||||
| **接口** | `POST /api/v1/auth/login` |
|
||||
| **前置条件** | 无 |
|
||||
| **操作步骤** | 1. 用错误账号密码调用登录接口 |
|
||||
| **预期结果** | 1. 返回 HTTP 401 或 422(非 500/502/503)<br>2. 返回 JSON 格式响应<br>3. 响应包含错误信息字段 |
|
||||
| **验证方式** | HTTP 状态码 + 响应格式检查 |
|
||||
| **对应现有冒烟** | ✅ 已有(Login API expect 401) |
|
||||
|
||||
### 4. 健康检查接口
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P0-004 |
|
||||
| **接口** | `GET /health` |
|
||||
| **前置条件** | 无 |
|
||||
| **操作步骤** | 1. 调用健康检查接口 |
|
||||
| **预期结果** | 1. HTTP 状态码 200<br>2. 返回包含 status 字段<br>3. 响应时间 < 3s |
|
||||
| **验证方式** | HTTP 状态码 + 响应时间 |
|
||||
| **对应现有冒烟** | ✅ 已有(Health check) |
|
||||
|
||||
### 5. API 文档可访问
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P0-005 |
|
||||
| **路径** | `/docs` |
|
||||
| **前置条件** | 无 |
|
||||
| **操作步骤** | 1. 访问 API 文档页面 |
|
||||
| **预期结果** | 1. HTTP 状态码 200<br>2. 页面正常返回(非 500 错误页) |
|
||||
| **验证方式** | HTTP 状态码检查 |
|
||||
| **对应现有冒烟** | ✅ 已有(/docs endpoint) |
|
||||
|
||||
---
|
||||
|
||||
## 三、P1 级用例(核心业务流程)
|
||||
|
||||
### 6. 用户注册流程
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-001 |
|
||||
| **路径** | `/register` |
|
||||
| **前置条件** | 无 |
|
||||
| **操作步骤** | 1. 访问注册页<br>2. 填写邮箱、密码、确认密码<br>3. 点击注册 |
|
||||
| **预期结果** | 1. 注册页正常渲染<br>2. 表单校验生效(空值/格式错误有提示)<br>3. 注册成功后跳转到登录页或首页<br>4. 新用户可正常登录 |
|
||||
| **验证方式** | 表单验证 + 页面跳转 + 登录回环 |
|
||||
|
||||
### 7. Dashboard 数据加载
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-002 |
|
||||
| **路径** | `/app/dashboard` |
|
||||
| **前置条件** | 已登录 |
|
||||
| **操作步骤** | 1. 登录后进入 Dashboard<br>2. 等待数据加载 |
|
||||
| **预期结果** | 1. 页面布局正常(侧边栏 + 主内容区)<br>2. 统计卡片正常显示(使用量/剩余额度等)<br>3. 无接口 500 错误<br>4. 加载状态合理(loading → 内容) |
|
||||
| **验证方式** | 页面布局检查 + API 响应检查 |
|
||||
|
||||
### 8. 素材库页面
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-003 |
|
||||
| **路径** | `/app/assets` |
|
||||
| **前置条件** | 已登录 |
|
||||
| **操作步骤** | 1. 进入素材库页面<br>2. 浏览列表 |
|
||||
| **预期结果** | 1. 页面正常渲染,无白屏<br>2. 素材列表正常显示(或空状态提示)<br>3. 分页/筛选控件可用<br>4. 上传按钮可见 |
|
||||
| **验证方式** | 页面渲染 + 列表数据检查 |
|
||||
|
||||
### 9. 生成页面(核心功能入口)
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-004 |
|
||||
| **路径** | `/app/generate` |
|
||||
| **前置条件** | 已登录 |
|
||||
| **操作步骤** | 1. 进入生成页面<br>2. 检查各功能模块 |
|
||||
| **预期结果** | 1. 页面正常渲染<br>2. 生成表单各字段正常显示<br>3. 生成按钮可点击<br>4. 模板/音色等下拉选项可展开 |
|
||||
| **验证方式** | 页面元素存在性 + 交互控件可用性 |
|
||||
|
||||
### 10. 任务历史列表
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-005 |
|
||||
| **路径** | `/app/history` |
|
||||
| **前置条件** | 已登录 |
|
||||
| **操作步骤** | 1. 进入任务历史页面 |
|
||||
| **预期结果** | 1. 任务列表正常显示(或空状态)<br>2. 任务状态标签正确(处理中/完成/失败)<br>3. 分页正常 |
|
||||
| **验证方式** | 列表渲染 + 状态标签检查 |
|
||||
|
||||
### 11. 成品库页面
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-006 |
|
||||
| **路径** | `/app/products` |
|
||||
| **前置条件** | 已登录 |
|
||||
| **操作步骤** | 1. 进入成品库页面 |
|
||||
| **预期结果** | 1. 成品卡片列表正常显示<br>2. 视频缩略图正常加载<br>3. 筛选/搜索功能可用 |
|
||||
| **验证方式** | 列表渲染 + 图片加载检查 |
|
||||
|
||||
### 12. 订阅页面
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| **用例ID** | SMOKE-P1-007 |
|
||||
| **路径** | `/app/subscription` |
|
||||
| **前置条件** | 已登录 |
|
||||
| **操作步骤** | 1. 进入订阅页面 |
|
||||
| **预期结果** | 1. 套餐列表正常显示<br>2. 当前套餐标识正确<br>3. 升级/续费按钮可见 |
|
||||
| **验证方式** | 页面渲染 + 套餐数据检查 |
|
||||
|
||||
---
|
||||
|
||||
## 四、P2 级用例(重要功能)
|
||||
|
||||
### 13. 标题库
|
||||
- **路径**:`/app/titles`
|
||||
- **验证**:列表正常、筛选可用、搜索功能
|
||||
|
||||
### 14. 音色库
|
||||
- **路径**:`/app/voices`
|
||||
- **验证**:音色列表、试听功能、分类筛选
|
||||
|
||||
### 15. 模板库
|
||||
- **路径**:`/app/templates`
|
||||
- **验证**:模板卡片、预览功能、分类筛选
|
||||
|
||||
### 16. 我的模板
|
||||
- **路径**:`/app/my-templates`
|
||||
- **验证**:用户自定义模板列表、编辑/删除操作
|
||||
|
||||
### 17. 剪辑规划师
|
||||
- **路径**:`/app/editing-planner`
|
||||
- **验证**:页面渲染、功能模块正常
|
||||
|
||||
### 18. 声音克隆
|
||||
- **路径**:`/app/voice-clone`
|
||||
- **验证**:页面渲染、上传入口、克隆流程入口
|
||||
|
||||
### 19. 我的音色
|
||||
- **路径**:`/app/my-voices`
|
||||
- **验证**:用户音色列表、状态标签
|
||||
|
||||
### 20. 声音素材库
|
||||
- **路径**:`/app/voice-materials`
|
||||
- **验证**:素材列表、上传功能
|
||||
|
||||
### 21. 个人设置
|
||||
- **路径**:`/app/profile`
|
||||
- **验证**:基本信息展示、修改密码入口、账号安全设置
|
||||
|
||||
### 22. 账单页面
|
||||
- **路径**:`/app/subscription/billing`
|
||||
- **验证**:账单列表、消费记录
|
||||
|
||||
### 23. 忘记密码
|
||||
- **路径**:`/forgot-password`
|
||||
- **验证**:页面渲染、邮箱输入、提交功能
|
||||
|
||||
### 24. 管理后台入口
|
||||
- **路径**:`/app/admin`
|
||||
- **验证**:管理员权限校验、页面正常访问或正确跳转
|
||||
|
||||
---
|
||||
|
||||
## 五、现有冒烟测试 vs 建议扩展
|
||||
|
||||
### 当前已有(4 项)
|
||||
| 编号 | 测试项 | 级别 |
|
||||
|------|--------|------|
|
||||
| 1 | 健康检查 `/health` | P0 ✅ |
|
||||
| 2 | 登录 API(expect 401) | P0 ✅ |
|
||||
| 3 | API 文档 `/docs` | P0 ✅ |
|
||||
| 4 | 前端页面可访问 | P0 ✅ |
|
||||
|
||||
### 建议新增(首批扩展到 10 项)
|
||||
| 编号 | 测试项 | 级别 | 优先级 |
|
||||
|------|--------|------|--------|
|
||||
| 5 | 登录页 DOM 元素检查 | P0 | 高 |
|
||||
| 6 | 注册页可用性 | P1 | 高 |
|
||||
| 7 | Dashboard 数据加载 | P1 | 高 |
|
||||
| 8 | 生成页面可用性 | P1 | 高 |
|
||||
| 9 | 素材库页面 | P1 | 中 |
|
||||
| 10 | 任务历史列表 | P1 | 中 |
|
||||
|
||||
### 后续扩展(第二阶段)
|
||||
- 所有 P1 + P2 用例
|
||||
- 用户完整操作链路(注册 → 登录 → 生成 → 查看结果)
|
||||
- 视频播放功能
|
||||
- 文件上传功能
|
||||
|
||||
---
|
||||
|
||||
## 六、自动化实现建议
|
||||
|
||||
### 方案选型
|
||||
- **轻量方案**:Playwright + 简单脚本,CI 中直接运行
|
||||
- **推荐方案**:项目已有 Playwright 配置(`playwright.config.ts` + `e2e/` 目录),直接复用
|
||||
|
||||
### CI 集成方式
|
||||
```
|
||||
staging部署完成 → 触发 E2E 冒烟测试 → 全部通过 → 标记成功
|
||||
→ 有失败 → 告警 + 保留现场
|
||||
```
|
||||
|
||||
### 失败处理
|
||||
- P0 级失败:立即告警,标记部署失败,触发回滚
|
||||
- P1 级失败:告警通知,人工确认是否回滚
|
||||
- P2 级失败:记录日志,不阻断部署
|
||||
|
||||
---
|
||||
|
||||
## 七、附录:核心页面清单
|
||||
|
||||
| 页面 | 路由 | 模块 | 优先级 |
|
||||
|------|------|------|--------|
|
||||
| 首页 | `/` | 公共 | P0 |
|
||||
| 登录 | `/login` | 认证 | P0 |
|
||||
| 注册 | `/register` | 认证 | P1 |
|
||||
| 忘记密码 | `/forgot-password` | 认证 | P2 |
|
||||
| 重置密码 | `/reset-password` | 认证 | P2 |
|
||||
| Dashboard | `/app/dashboard` | 主功能 | P1 |
|
||||
| 素材库 | `/app/assets` | 资源 | P1 |
|
||||
| 标题库 | `/app/titles` | 资源 | P2 |
|
||||
| 音色库 | `/app/voices` | 资源 | P2 |
|
||||
| 模板库 | `/app/templates` | 资源 | P2 |
|
||||
| 生成页面 | `/app/generate` | 核心 | P1 |
|
||||
| 任务历史 | `/app/history` | 核心 | P1 |
|
||||
| 成品库 | `/app/products` | 核心 | P1 |
|
||||
| 成品详情 | `/app/products/:id` | 核心 | P2 |
|
||||
| 剪辑规划师 | `/app/editing-planner` | 功能 | P2 |
|
||||
| 我的模板 | `/app/my-templates` | 功能 | P2 |
|
||||
| 声音克隆 | `/app/voice-clone` | 功能 | P2 |
|
||||
| 声音素材库 | `/app/voice-materials` | 功能 | P2 |
|
||||
| 我的音色 | `/app/my-voices` | 功能 | P2 |
|
||||
| 订阅计划 | `/app/subscription` | 支付 | P1 |
|
||||
| 升级订阅 | `/app/subscription/upgrade` | 支付 | P2 |
|
||||
| 账单 | `/app/subscription/billing` | 支付 | P2 |
|
||||
| 个人设置 | `/app/profile` | 设置 | P2 |
|
||||
| 管理后台 | `/app/admin` | 管理 | P2 |
|
||||
Reference in New Issue
Block a user