fischer-agentkit/docs/plans/2026-06-28-001-feat-full-e2...

275 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "feat: 全项目 E2E 测试套件 + CI workflow"
date: 2026-06-28
plan_type: feat
origin: docs/solutions/integration-issues/jwt-secret-dev-mode-user-id-mismatch.md
depth: deep
---
# feat: 全项目 E2E 测试套件 + CI workflow
## Summary
建立覆盖全项目的 E2E 测试体系,包括前端所有关键视图的 Playwright spec、后端 API/WS 闭环测试、认证状态持久化测试、数据一致性测试,以及 GitHub Actions/Gitea CI workflow。目标让本次出现的 reload 登录失效、日历数据不一致、对话无法删除等问题在 CI 阶段就被捕获,不再流入用户手中。
## Problem Frame
当前项目虽有测试基础设施(后端 `tests/e2e/` + 前端 Playwright 4 spec但存在严重缺口
1. **认证状态持久化未测**reload 后登录态保持、token 跨重启持久化、refresh token 冷启动 — 这些场景无 E2E 覆盖导致问题4reload 跳登录页)长期未发现
2. **数据一致性未测**agent 通过工具创建数据如日历事件UI 能否看到 — 无端到端验证导致问题2日历事件看不到长期未发现
3. **前端视图覆盖不足**:仅 login/chat/calendar/terminal 4个 specskills/documents/bitable/evolution/monitor/settings/admin 等视图零覆盖
4. **CI 完全无测试**`.github/workflows/` 和 `.gitea/workflows/` 都没有测试 job所有测试依赖开发者手动运行
5. **对话管理 CRUD 未测**创建、删除、切换对话的端到端流程未覆盖导致问题1对话无法删除长期未发现
## Requirements
- R1: 认证状态持久化 E2E — 覆盖 reload、token 跨重启、refresh token 冷启动
- R2: 数据一致性 E2E — 覆盖 agent 工具创建数据后 UI 可见性(日历优先)
- R3: 对话管理 CRUD E2E — 覆盖创建、删除、切换、历史加载
- R4: 前端全视图 E2E — 覆盖 skills/documents/bitable/evolution/monitor/settings/admin
- R5: 后端 API E2E 补充 — 覆盖未测的 REST 端点experts/mcp/workflows 等)
- R6: CI workflow — GitHub Actions + Gitea 自动运行测试
## Key Technical Decisions
- **KTD1: Playwright 作为前端 E2E 主框架**。项目已安装 `@playwright/test@^1.59.0` 且配置完善双服务器自动启动、global-setup 创建测试用户),无需引入新框架。扩展新 spec 复用现有 helpers.ts。
- **KTD2: 后端 E2E 复用 `tests/e2e/conftest.py` 基础设施**。MockLLMProvider + 端口 18765 + `scripts/run_e2e.sh` 已成熟,新测试直接扩展。不引入 testcontainers项目已声明但未使用保持一致性
- **KTD3: CI 用 docker-compose.test.yml 启动依赖**。PostgreSQL pgvector (5434) + Redis (6381) 已配置CI 中 `docker-compose -f docker-compose.test.yml up -d` 即可。不引入 testcontainers 以保持与本地环境一致。
- **KTD4: 认证状态测试用 `page.reload()` + `evaluate` 验证 localStorage**。不 mock Tauri KeychainWeb 模式下走 localStorage fallback直接验证持久化行为。
- **KTD5: 数据一致性测试用 "agent 路径写入 + UI 路径读取" 双向验证**。先通过 API/WS 让 agent 创建日历事件,再通过 UI 验证事件可见。这是本次问题的核心回归测试。
---
## U1. 认证状态持久化 E2E
**Goal:** 验证登录状态跨 reload、跨服务器重启持久化捕获问题4reload 跳登录页)的回归。
**Requirements:** R1
**Dependencies:**
**Files:**
- `src/agentkit/server/frontend/e2e/auth-persistence.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/helpers.ts` (modify — 添加 `reloadAndWaitAuth` helper)
**Approach:**
- 测试1登录 → reload → 验证仍处于已认证状态(不跳 login
- 测试2登录 → 清除 localStorage → reload → 验证跳 login
- 测试3登录 → 服务器重启Playwright 无法直接重启服务器,改为验证 token 过期场景)→ 验证 refresh token 冷启动
- 测试4登录 → 访问受保护页面 → 验证 Authorization header 携带 access token
- 测试5登录 → 等待 access token 过期mock 时间或短 TTL→ 验证 silent refresh
**Patterns to follow:** `e2e/login.spec.ts``loginViaApi` + `loginAndHydrate` 模式
**Test scenarios:**
- Happy path: 登录后 reload 保持登录态
- Edge case: localStorage 为空时 reload 跳 login
- Error path: refresh token 无效时跳 login 并清除存储
- Integration: access token 过期时自动 refresh不中断用户操作
**Verification:** `npm run test:e2e -- --grep "auth-persistence"` 全部通过
---
## U2. 对话管理 CRUD E2E
**Goal:** 验证对话的创建、删除、切换、历史加载端到端流程捕获问题1对话无法删除的回归。
**Requirements:** R3
**Dependencies:** U1
**Files:**
- `src/agentkit/server/frontend/e2e/conversation-management.spec.ts` (create)
**Approach:**
- 测试1新建对话 → 发送消息 → 验证对话出现在列表
- 测试2删除对话 → 验证从列表消失 → reload → 验证不再出现(未被"复活"
- 测试3多对话切换 → 验证消息历史正确加载
- 测试4删除当前活跃对话 → 验证自动切换到下一个或新建
- 测试5删除所有对话 → 验证空状态显示
**Patterns to follow:** `e2e/chat.spec.ts``sendChatMessage` + `waitForLlmResponse` 模式
**Test scenarios:**
- Happy path: 创建 → 发消息 → 删除 → 验证消失
- Edge case: 删除进行中的对话pending 状态)
- Error path: 删除不存在的对话404→ UI 正确处理
- Integration: 多对话切换时消息历史隔离
**Verification:** `npm run test:e2e -- --grep "conversation-management"` 全部通过
---
## U3. 日历数据一致性 E2E
**Goal:** 验证 agent 通过 calendar 工具创建事件后UI 日历视图能显示该事件捕获问题2日历事件看不到的回归。
**Requirements:** R2
**Dependencies:** U1
**Files:**
- `src/agentkit/server/frontend/e2e/calendar-data-consistency.spec.ts` (create)
**Approach:**
- 测试1通过 chat 让 agent 创建日历事件("帮我创建下周一上午10点的项目会议")→ 切换到日历视图 → 验证事件可见
- 测试2通过 UI 创建事件 → 通过 API 查询 → 验证 user_id 一致
- 测试3通过 chat 创建事件 → 通过 API 查询 → 验证 user_id 不是 hallucinate 值("default"/"zhangsan"
- 测试4多事件场景 → 验证日历正确渲染所有事件
- 测试5删除事件 → 验证 UI 和 API 同步消失
**Patterns to follow:** `e2e/calendar.spec.ts` 的 E1-E8 模式 + `e2e/chat.spec.ts` 的 agent 交互
**Test scenarios:**
- Happy path: agent 创建 → UI 可见
- Data integrity: user_id 一致性agent 路径 vs UI 路径)
- Edge case: agent 创建事件但 LLM 未提供 user_id → 使用 default_user_id
- Integration: UI 创建 + agent 创建混合场景
**Verification:** `npm run test:e2e -- --grep "calendar-data-consistency"` 全部通过
---
## U4. 前端全视图 E2E 补充
**Goal:** 为 skills/documents/bitable/evolution/monitor/settings/admin 视图补充 E2E spec确保所有关键视图可访问且基本功能正常。
**Requirements:** R4
**Dependencies:** U1
**Files:**
- `src/agentkit/server/frontend/e2e/skills-view.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/documents-view.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/bitable-view.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/evolution-view.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/monitor-view.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/settings-view.spec.ts` (create)
- `src/agentkit/server/frontend/e2e/admin-view.spec.ts` (create)
**Approach:**
每个视图至少覆盖:
- 页面加载(无白屏、无 401
- 核心功能(如 skills 列表加载、documents 上传按钮可见等)
- 导航交互(侧边栏切换、标签页切换)
- 错误状态(空数据、加载失败)
**Patterns to follow:** `e2e/calendar.spec.ts` 的 E1面板加载模式
**Test scenarios:** 每个视图 3-5 个测试(加载、核心功能、空状态、错误处理)
**Verification:** `npm run test:e2e` 全部 spec 通过
---
## U5. 后端 API E2E 补充
**Goal:** 补充未覆盖的后端 REST 端点 E2E 测试experts/mcp/workflows/llm gateway 等)。
**Requirements:** R5
**Dependencies:**
**Files:**
- `tests/e2e/test_api_coverage.py` (create)
**Approach:**
- 遍历 `/api/v1/` 下所有路由前缀
- 对未覆盖的端点编写基础 E2E健康检查、认证要求、CRUD 基础)
- 重点覆盖:`/experts`、`/mcp`、`/workflows`、`/llm/chat`SSE、`/config`、`/system`
**Patterns to follow:** `tests/e2e/test_basic_api.py``api_client` fixture 模式
**Test scenarios:**
- Happy path: 每个端点的基础 GET/POST 返回预期状态码
- Auth: 受保护端点无 token 返回 401
- Error path: 无效参数返回 4xx
**Verification:** `python3 -m pytest tests/e2e/test_api_coverage.py -v` 通过
---
## U6. CI workflow 建立
**Goal:** 在 GitHub Actions 和 Gitea Actions 中建立测试 workflow自动运行后端 pytest + 前端 vitest + Playwright E2E。
**Requirements:** R6
**Dependencies:** U1, U2, U3, U4, U5
**Files:**
- `.github/workflows/test.yml` (create)
- `.gitea/workflows/test.yml` (create)
**Approach:**
- GitHub Actions workflow
- Trigger: push to main/develop, PR to main
- Jobs: backend-test (pytest) + frontend-unit (vitest) + frontend-e2e (playwright)
- Services: PostgreSQL (pgvector) + Redis via docker-compose.test.yml
- Cache: pip + npm 依赖缓存
- Gitea Actions workflow同上Gitea 兼容 GitHub Actions 语法)
**Patterns to follow:** 标准 GitHub Actions Python + Node.js workflow 模式
**Test scenarios:**
- Happy path: PR 触发 workflow所有测试通过
- Failure: 故意引入 bug验证测试失败并阻止合并
**Verification:** 推送分支 → CI 自动运行 → 全绿
---
## Scope Boundaries
### In scope
- 前端 Playwright E2E spec认证持久化、对话管理、日历一致性、全视图覆盖
- 后端 API E2E 补充(未覆盖端点)
- CI workflowGitHub Actions + Gitea
### Deferred to Follow-Up Work
- Tauri 桌面端 E2E需引入 tauri-driver当前无基础设施
- 真实 LLM E2E 扩展(成本高,保持现有 mock 策略)
- 性能/负载测试(本次聚焦功能正确性)
- 视觉回归测试Percy/Chromatic后续补充
### Non-goals
- 重写现有测试框架
- 引入 testcontainers保持与现有 docker-compose.test.yml 一致)
- 修改产品代码(测试发现的问题由 ce-debug 修复)
---
## Risks & Dependencies
| Risk | Mitigation |
|------|------------|
| Playwright E2E 执行慢(双服务器启动) | 已有 `reuseExistingServer: !CI` 配置,本地复用 |
| MockLLMProvider 响应不匹配新场景 | 扩展 `MOCK_LLM_RESPONSES` 字典,新增 calendar 场景 |
| CI 中 PostgreSQL pgvector 版本不匹配 | docker-compose.test.yml 已指定 `pgvector/pgvector:pg15` |
| calendar.spec.ts 已知 cold-start bugrefresh token | 新 spec 使用 UI 表单登录,避开 localStorage 注入 |
---
## System-Wide Impact
- **开发者工作流**PR 将自动触发 CI 测试,需要开发者在本地运行测试后再推送
- **部署流程**CI 绿灯成为部署前置条件
- **测试维护**:新增 spec 需要维护helpers.ts 扩展需保持向后兼容
---
## Open Questions
无 — 范围和 CI 策略已确认。
---
## Deferred to Implementation
- 各 spec 的具体选择器(需实际查看 DOM 结构)
- MockLLMProvider 的新场景响应内容
- CI workflow 的具体缓存键值
- 各视图 spec 的详细测试用例(需查看实际 UI