Files
ai-proj-helper/skills-dev/dev-test-plugin/skills/dev-test/e2e-testing.md
John Qiu 712063071c refactor: 通用技能按类别拆分为独立目录
skills/ → skills-dev(9), skills-req(10), skills-ops(4),
skills-integration(8), skills-biz(4), skills-workflow(7)

generate-marketplace.py 改为自动扫描所有 skills-* 目录。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 11:31:58 +10:30

170 lines
5.3 KiB
Markdown
Raw 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.
# E2E 测试 (Playwright)
## 通用 Playwright 配置
```typescript
// playwright.config.ts
import { defineConfig } from '@playwright/test'
export default defineConfig({
testDir: './tests/e2e',
timeout: 30000,
use: {
baseURL: 'http://localhost:3000',
screenshot: 'only-on-failure',
},
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'firefox', use: { browserName: 'firefox' } },
],
})
```
## 通用 E2E 测试示例
```typescript
// login.spec.ts
import { test, expect } from '@playwright/test'
test.describe('Login', () => {
test('successful login', async ({ page }) => {
await page.goto('/login')
await page.fill('[data-testid="username"]', 'testuser')
await page.fill('[data-testid="password"]', 'password')
await page.click('[data-testid="submit"]')
await expect(page).toHaveURL('/dashboard')
await expect(page.locator('.welcome')).toContainText('testuser')
})
test('invalid credentials', async ({ page }) => {
await page.goto('/login')
await page.fill('[data-testid="username"]', 'wrong')
await page.fill('[data-testid="password"]', 'wrong')
await page.click('[data-testid="submit"]')
await expect(page.locator('.error')).toBeVisible()
})
})
test.describe('Task Management', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/login')
await page.fill('[data-testid="username"]', 'testuser')
await page.fill('[data-testid="password"]', 'password')
await page.click('[data-testid="submit"]')
})
test('create task', async ({ page }) => {
await page.click('[data-testid="new-task"]')
await page.fill('[data-testid="task-title"]', 'E2E Test Task')
await page.click('[data-testid="save"]')
await expect(page.locator('text=E2E Test Task')).toBeVisible()
})
})
```
---
## Coolbuy PaaS E2E 集成测试
> Playwright 全链路 E2E 测试独立环境DB + 端口),可与 dev 服务并行运行。
### 环境架构
| 服务 | Dev 端口 | E2E 端口 | DB |
|------|---------|---------|-----|
| Auth Service | 7089 | 7189 | coolbuy_paas_e2e |
| Foundation Service | 7090 | 7190 | coolbuy_paas_e2e |
| ERP Service | 7091 | 7191 | coolbuy_paas_e2e |
| Web Frontend | 4000 | 4010 | - |
**E2E DB 初始化**(首次/重置):
```bash
psql -U coolbuy-dev -d postgres -c "DROP DATABASE IF EXISTS coolbuy_paas_e2e;"
psql -U coolbuy-dev -d postgres -c "CREATE DATABASE coolbuy_paas_e2e OWNER \"coolbuy-dev\";"
pg_dump -U coolbuy-dev coolbuy_paas_local | psql -U coolbuy-dev coolbuy_paas_e2e
```
### 启动 / 停止 E2E 服务
```bash
make e2e-start # 启动全部 E2E 服务auth/foundation/erp/web
make e2e-stop # 停止全部 E2E 服务
make e2e-reset # 重置 DB 后启动
make e2e # 启动服务 + 运行全部测试
```
脚本位置:`scripts/start-e2e-services.sh` / `scripts/stop-e2e-services.sh`
### 运行测试
```bash
cd web
# 全部测试(无头模式)
npx playwright test
# 带 UI 调试
npx playwright test --headed
# 单个文件
npx playwright test tests/product-crud.spec.ts
# 查看 HTML 报告(注意:会启动 HTTP server需 Ctrl+C 退出)
npx playwright show-report
```
### Auth 自动登录
`tests/auth.setup.ts` 优先点击快速登录按钮(`VITE_ENABLE_QUICK_LOGIN=true`),降级为表单登录:
```typescript
// 快速登录E2E 环境默认开启)
const quickLoginBtn = page.locator('button, a').filter({ hasText: /李宁|lining|ID:2/i }).first();
if (await quickLoginBtn.isVisible({ timeout: 3000 })) {
await quickLoginBtn.click();
} else {
// 降级:填写 lining_admin / admin123验证码任意 4 位SkipVerify=true
}
await page.waitForURL(/\/tenant/, { timeout: 15000 });
await page.context().storageState({ path: authFile });
```
Session 保存至 `.auth/user.json`,后续测试自动复用,无需重复登录。
### 配置文件
| 文件 | 说明 |
|------|------|
| `web/.env.e2e` | E2E 环境变量(端口 / 快速登录开关) |
| `web/playwright.config.ts` | baseURL=localhost:4010reporter=[html, list] |
| `auth-service/api/etc/auth-api-e2e.yaml` | E2E auth 配置SkipVerify=true |
| `foundation-service/api/etc/foundation-api-e2e.yaml` | E2E foundation 配置 |
| `erp-service/configs/config.e2e.yaml` | E2E ERP 配置 |
### 测试结果解读
当前 **113 tests — 103 ✅ / 10 ❌**,已知失败项:
| 失败原因 | 涉及测试 |
|---------|---------|
| `/tenant/order/business` 路由 404页面未实现 | 业务订单列表 × 3、订单模块导航 |
| 预警管理无搜索表单组件 | 预警管理搜索/筛选 |
| 库存管理页无 table/empty 状态 | 仓库管理-库存管理 |
| 待审批订单 networkidle 超时(>60s | 待审批订单列表 |
| 数据权限/字段权限页渲染异常 | 系统管理 × 2 |
| 业务 CRM 页渲染异常 | 业务 CRM |
### 常见问题
| 问题 | 解决 |
|------|------|
| `Executable doesn't exist` | `npx playwright install chromium` |
| 端口 4010 被占用 | `make e2e-stop` 后重试 |
| GORM migration 失败 | 检查 DB 是否有旧约束名,手动 DROP CONSTRAINT 后重启服务 |
| HTML 报告进程不退出 | Playwright 在 report 模式会启动 HTTP server`Ctrl+C` 停止 |