|
|
@ -40,6 +40,7 @@ |
|
|
- 数据库隔离:独立 SQLite 文件 `packages/drizzle-pkg/db.test.sqlite`,workers=1 避免并发 |
|
|
- 数据库隔离:独立 SQLite 文件 `packages/drizzle-pkg/db.test.sqlite`,workers=1 避免并发 |
|
|
- 验证码注入:业务代码分支方式,`server/service/captcha/challenge.ts` 中 `E2E_TEST_MODE` 门控返回固定验证码 |
|
|
- 验证码注入:业务代码分支方式,`server/service/captcha/challenge.ts` 中 `E2E_TEST_MODE` 门控返回固定验证码 |
|
|
- 环境变量:`.env.test` 文件,由 `global-setup.ts` 和 `playwright.config.ts` 内部代码解析注入 |
|
|
- 环境变量:`.env.test` 文件,由 `global-setup.ts` 和 `playwright.config.ts` 内部代码解析注入 |
|
|
|
|
|
- Mock LLM 服务器:global-setup 中内联启动,端口 3600,OpenAI 兼容 SSE 流式响应 |
|
|
|
|
|
|
|
|
### 运行命令 |
|
|
### 运行命令 |
|
|
|
|
|
|
|
|
@ -49,6 +50,49 @@ bun run test:e2e:headed # 有头模式运行 |
|
|
bun run test:e2e:ui # Playwright UI 模式 |
|
|
bun run test:e2e:ui # Playwright UI 模式 |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
> **注意**:Playwright 命令必须传 `--config=e2e/playwright.config.ts`,否则找不到 config 文件会跳过 globalSetup。package.json 脚本中已包含。 |
|
|
|
|
|
|
|
|
|
|
|
### 测试文件 |
|
|
|
|
|
|
|
|
|
|
|
| 文件 | 测试数 | 说明 | |
|
|
|
|
|
|------|--------|------| |
|
|
|
|
|
| `specs/smoke.spec.ts` | 5 | 冒烟测试:页面可访问、验证码 API、全局配置 API | |
|
|
|
|
|
| `specs/auth-login.spec.ts` | 7 | 登录流程:表单验证、成功登录、失败场景、登出 | |
|
|
|
|
|
| `specs/auth-register.spec.ts` | 6 | 注册流程:表单验证、成功注册、重复用户名、注册后登录 | |
|
|
|
|
|
| `specs/auth-guard.spec.ts` | 9 | 路由守卫:未登录重定向、已登录访问、白名单页面 | |
|
|
|
|
|
| `specs/agent-chat.spec.ts` | 10 | Agent 对话:欢迎页、输入框、发送消息、流式回复、连续对话 | |
|
|
|
|
|
|
|
|
|
|
|
### Mock LLM 架构 |
|
|
|
|
|
|
|
|
|
|
|
Agent 对话测试依赖 Mock LLM 服务器,在 `global-setup.ts` 中内联启动: |
|
|
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
global-setup.ts 流程: |
|
|
|
|
|
1. 加载 .env.test |
|
|
|
|
|
2. 删除旧测试数据库 |
|
|
|
|
|
3. build Nuxt 应用 |
|
|
|
|
|
4. 运行数据库迁移 |
|
|
|
|
|
5. 运行 seed(创建 bootstrap admin 用户) |
|
|
|
|
|
6. 启动 Mock LLM 服务器(端口 3600,OpenAI 兼容 SSE) |
|
|
|
|
|
7. 向测试数据库插入 LLM provider + model + userConfig |
|
|
|
|
|
8. 启动 preview 服务器(端口 3400) |
|
|
|
|
|
9. 等待服务器就绪 |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
**Mock LLM 服务器**(内联在 global-setup.ts 中): |
|
|
|
|
|
- 监听端口:`MOCK_LLM_PORT`(默认 3600) |
|
|
|
|
|
- 端点:`POST /v1/chat/completions` |
|
|
|
|
|
- 响应格式:OpenAI 兼容 SSE 流式(`data: {"choices":[{"delta":{"content":"x"}}]}`) |
|
|
|
|
|
- 固定回复内容:`你好!这是一个测试回复。`(逐字符流式输出,20ms 间隔) |
|
|
|
|
|
- 不校验 API key,不校验请求体 |
|
|
|
|
|
|
|
|
|
|
|
**数据库 seed**(步骤7,直接 SQL 插入): |
|
|
|
|
|
- `llm_providers` 表:id=1, user_id=1, name="mock-provider", slug="mock-provider", base_url="http://localhost:3600/v1", parse_mode="openai-compatible" |
|
|
|
|
|
- `llm_models` 表:id=1, provider_id=1, name="mock-model", model_id="mock-model", enabled=1, supports_tools=0 |
|
|
|
|
|
- `user_configs` 表:user_id=1, key="preferredLlmModelId", value="1", value_type="number" |
|
|
|
|
|
|
|
|
|
|
|
> **注意**:Mock LLM 逻辑内联在 global-setup.ts 中,不通过 import 外部 .ts 文件。原因是 Playwright + Node ESM 无法正确解析 `.ts` 扩展名导入。独立文件 `e2e/mock-llm-server.ts` 仍保留但不再被导入。 |
|
|
|
|
|
|
|
|
### 编写测试注意事项 |
|
|
### 编写测试注意事项 |
|
|
|
|
|
|
|
|
- 用户名规则:`/^[a-zA-Z0-9_]{3,20}$/`(3-20字符,仅字母数字下划线),生成动态用户名时注意长度 |
|
|
- 用户名规则:`/^[a-zA-Z0-9_]{3,20}$/`(3-20字符,仅字母数字下划线),生成动态用户名时注意长度 |
|
|
@ -56,3 +100,11 @@ bun run test:e2e:ui # Playwright UI 模式 |
|
|
- 已登录状态测试:通过 UI 登录设置 cookie,不要用 `request` context(cookie 不共享到 `page`) |
|
|
- 已登录状态测试:通过 UI 登录设置 cookie,不要用 `request` context(cookie 不共享到 `page`) |
|
|
- 避免使用 `waitForLoadState("networkidle")`,部分页面有持续网络请求会导致超时 |
|
|
- 避免使用 `waitForLoadState("networkidle")`,部分页面有持续网络请求会导致超时 |
|
|
- SSR 中间件重定向可能不带 `?redirect=` 参数,测试应兼容此情况 |
|
|
- SSR 中间件重定向可能不带 `?redirect=` 参数,测试应兼容此情况 |
|
|
|
|
|
- `execSync` 的 `stdio` 必须用 `"pipe"` 而非 `"inherit"`,否则在 Playwright 子进程中可能导致管道阻塞 |
|
|
|
|
|
- Agent 对话测试间会共享数据库 session,登录后需点击"新建会话"按钮(`.new-chat-btn`)避免跨测试 session 污染 |
|
|
|
|
|
- 示例卡片(`.example-card`)点击后直接发送消息,不是填充输入框 |
|
|
|
|
|
- Agent 消息 DOM:用户消息 `.agent-message.is-user .user-bubble`,助手消息 `.agent-message.is-assistant .agent-markdown` |
|
|
|
|
|
- Agent 输入 DOM:`textarea.agent-textarea`,发送按钮 `button.btn-send`,停止按钮 `button.btn-stop` |
|
|
|
|
|
- 登录页面 DOM:`#login-username`、`#login-password`、`#login-captcha`,提交 `button[type="submit"]` |
|
|
|
|
|
- 固定验证码:`FIXED_CAPTCHA` 常量在 `e2e/fixtures/test-users.ts` |
|
|
|
|
|
- 测试用户:`E2E_ADMIN`(username/password)在 `e2e/fixtures/test-users.ts` |