1
0
Files
nex/openspec/specs/e2e-testing/spec.md
lanyuanxiaoyao f488b9cc15 fix(e2e): 修复对话框关闭问题,完善 E2E 测试
- 修复 TDesign Dialog onConfirm 不自动关闭的问题
- 使用 useEffect 监听 mutation 状态自动关闭对话框
- 测试使用 waitForResponse 等待 API 响应
- 添加 clearDatabase 函数确保测试隔离
- 归档 e2e-real-backend 变更到 archive/2026-04-22
- 同步 e2e-testing spec 到主 specs
2026-04-22 10:32:57 +08:00

7.9 KiB
Raw Blame History

ADDED Requirements

Requirement: E2E 测试基础设施

前端 E2E 测试 SHALL 自动启动隔离的 Go 后端实例,提供真实 API 交互能力。

Scenario: 双 webServer 自动启动

  • WHEN 执行 bun run test:e2e
  • THEN Playwright SHALL 按 webServer 数组顺序先启动 Go 后端(端口 19026再启动 Vite 前端(端口 5173
  • THEN Go 后端 SHALL 使用临时目录中的独立数据库文件和日志目录
  • THEN Go 后端启动命令 SHALL 包含 --server-port 19026--database-path--log-path--log-level warn 参数
  • THEN Go 后端 cwd SHALL 指向 backend/ 目录
  • THEN webServer 等待超时 SHALL 为 60000ms
  • THEN 两个 webServer SHALL 设置 reuseExistingServer: false

Scenario: 环境变量传递

  • WHEN Playwright 配置加载
  • THEN playwright.config.ts SHALL 设置 process.env.NEX_BACKEND_PORT'19026'
  • THEN process.env.NEX_E2E_TEMP_DIR SHALL 设置为临时目录路径
  • THEN Vite dev server 子进程 SHALL 自动继承上述环境变量
  • THEN E2E 测试文件 SHALL 通过 process.env 读取后端端口和临时目录信息

Scenario: Vite proxy 动态化

  • WHEN vite.config.ts 配置 proxy target
  • THEN proxy target SHALL 读取 process.env.NEX_BACKEND_PORT,回退到 '9826'
  • THEN 日常 bun run dev无环境变量proxy target SHALL 为 http://localhost:9826
  • THEN E2E 测试时 proxy target SHALL 为 http://localhost:19026

Requirement: 临时文件隔离

E2E 测试 SHALL 使用临时目录隔离所有文件,测试结束后自动清理。

Scenario: 临时目录创建

  • WHEN Playwright 配置加载
  • THEN SHALL 使用 fs.mkdtempSync(path.join(os.tmpdir(), 'nex-e2e-')) 创建临时目录
  • THEN 临时目录 SHALL 包含 test.db(数据库)和 log/(日志)子路径

Scenario: 临时目录清理

  • WHEN Playwright 所有测试完成
  • THEN globalTeardown SHALL 使用 fs.rm(dir, { recursive: true, force: true }) 删除临时目录
  • THEN 清理 SHALL 在 webServer 进程关闭之后执行

Requirement: 统计数据 seed

E2E 测试 SHALL 能通过 sql.js 直接操作 SQLite 文件 seed 历史统计数据。

Scenario: SQLite 统计数据插入

  • WHEN 统计页面测试需要历史数据
  • THEN SHALL 使用 sql.js 打开临时数据库文件
  • THEN SHALL 通过 INSERT INTO usage_stats 插入指定日期和请求量的统计数据
  • THEN SHALL 将修改后的数据库写回文件(db.export()fs.writeFileSync
  • THEN seed 操作 SHALL 在 API 创建供应商和模型之后串行执行
  • THEN seed 完成后 SHALL 关闭 sql.js 数据库连接

Requirement: E2E 共享工具模块

E2E 测试 SHALL 提供共享工具模块(e2e/fixtures.ts)封装常用操作。

Scenario: 共享常量

  • WHEN 测试文件需要后端 API 地址
  • THEN fixtures SHALL export API_BASE 常量,值为 http://localhost:${process.env.NEX_BACKEND_PORT}

Scenario: API seed 工具

  • WHEN 测试需要通过 API 准备数据
  • THEN fixtures SHALL export seedProvider(request, data) 函数,通过 request.post 创建供应商
  • THEN fixtures SHALL export seedModel(request, data) 函数,通过 request.post 创建模型

Scenario: SQLite seed 工具

  • WHEN 测试需要 seed 统计数据
  • THEN fixtures SHALL export seedUsageStats(statsData) 函数,通过 sql.js 插入 usage_stats 记录

Requirement: 供应商管理 E2E 测试

E2E 测试 SHALL 验证供应商的完整 CRUD 用户流程。

Scenario: 创建供应商并验证

  • WHEN 用户通过 UI 填写供应商表单并提交
  • THEN 对话框 SHALL 关闭
  • THEN 新供应商 SHALL 出现在表格中
  • THEN 表格 SHALL 显示正确的 id、name、base_url、协议、enabled 状态

Scenario: 编辑供应商并验证

  • WHEN 用户点击编辑按钮、修改名称并提交
  • THEN 对话框 SHALL 关闭
  • THEN 表格中该供应商的名称 SHALL 更新为新值

Scenario: 删除供应商并验证

  • WHEN 用户点击删除按钮并确认
  • THEN 确认框 SHALL 消失
  • THEN 该供应商 SHALL 从表格中消失

Requirement: 模型管理 E2E 测试

E2E 测试 SHALL 验证模型的完整 CRUD 用户流程。

Scenario: 前置数据准备

  • WHEN 模型测试开始前
  • THEN SHALL 通过 API seed 一个供应商(不通过 UI

Scenario: 创建模型并验证

  • WHEN 用户展开供应商行、填写模型表单并提交
  • THEN 对话框 SHALL 关闭
  • THEN 新模型 SHALL 出现在展开行的模型表格中
  • THEN 模型表格 SHALL 显示统一模型 IDprovider_id/model_name 格式)

Scenario: 编辑模型并验证

  • WHEN 用户点击模型编辑按钮、修改并提交
  • THEN 对话框 SHALL 关闭
  • THEN 模型表格 SHALL 显示更新后的数据

Scenario: 删除模型并验证

  • WHEN 用户点击模型删除按钮并确认
  • THEN 该模型 SHALL 从模型表格中消失

Requirement: 统计页面 E2E 测试

E2E 测试 SHALL 验证统计页面的数据展示和筛选功能。

Scenario: 统计数据准备

  • WHEN 统计测试开始前
  • THEN SHALL 通过 API seed 供应商和模型
  • THEN SHALL 通过 sql.js seed 多日历史统计数据(覆盖不同供应商、不同模型、不同日期)

Scenario: 统计概览验证

  • WHEN 加载统计页面
  • THEN 统计摘要卡片 SHALL 显示正确的总请求量
  • THEN 统计摘要卡片 SHALL 显示正确的活跃模型数和活跃供应商数
  • THEN 统计表格 SHALL 显示 seed 的数据行

Scenario: 统计筛选验证

  • WHEN 用户选择供应商筛选条件
  • THEN 统计表格 SHALL 只显示该供应商的数据
  • WHEN 用户输入模型名称筛选条件
  • THEN 统计表格 SHALL 只显示匹配模型的数据

Requirement: 导航 E2E 测试

E2E 测试 SHALL 验证页面导航和侧边栏功能。

Scenario: 侧边栏渲染

  • WHEN 加载任意页面
  • THEN 侧边栏 SHALL 显示应用名称和导航菜单项

Scenario: 页面切换

  • WHEN 用户点击侧边栏导航菜单项
  • THEN 页面 SHALL 切换到对应路由并显示正确内容
  • THEN 当前菜单项 SHALL 高亮

Scenario: URL 持久化

  • WHEN 用户在统计页面刷新浏览器
  • THEN 页面 SHALL 保持在统计页面

Requirement: 表单验证 E2E 测试

E2E 测试 SHALL 验证表单的校验行为。

Scenario: 供应商表单必填校验

  • WHEN 用户打开添加供应商对话框并直接点击保存
  • THEN SHALL 显示所有必填字段的验证错误提示

Scenario: URL 格式校验

  • WHEN 用户在 base_url 字段输入无效 URL 并提交
  • THEN SHALL 显示 URL 格式错误提示

Scenario: 对话框行为

  • WHEN 用户打开对话框后点击取消
  • THEN 对话框 SHALL 关闭且表单重置
  • WHEN 用户再次打开对话框
  • THEN 表单字段 SHALL 为空

Requirement: E2E 测试文件组织

E2E 测试 SHALL 按 7 个 spec 文件组织。

Scenario: 文件结构

  • WHEN 查看 e2e/ 目录
  • THEN SHALL 包含以下测试文件:providers.spec.tsmodels.spec.tsstats.spec.tsnavigation.spec.tsvalidation.spec.ts
  • THEN SHALL 包含以下辅助文件:fixtures.tsglobal-setup.tsglobal-teardown.ts
  • THEN SHALL NOT 包含已删除的文件:stats-cards.spec.tssidebar.spec.tscrud.spec.ts

Requirement: 新增依赖

E2E 测试 SHALL 引入 sql.js 作为 devDependency。

Scenario: sql.js 依赖

  • WHEN 安装前端依赖
  • THEN package.json 的 devDependencies SHALL 包含 sql.js
  • THEN package.json 的 devDependencies SHALL 包含 @types/sql.js
  • THEN sql.js SHALL 仅在 E2E 测试的 seed 逻辑中使用,不影响生产代码