# 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` 停止 |