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>
170 lines
5.3 KiB
Markdown
170 lines
5.3 KiB
Markdown
# 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:4010,reporter=[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` 停止 |
|