Approved
As a 超级管理员, I want 通过E2E测试验证租户后台统一广告管理的完整UI交互流程, so that 确保租户后台的广告管理功能在实际浏览器环境中能够正常工作,包括登录、导航、CRUD操作、表单验证等所有交互场景。
web/tests/e2e/specs/tenant-advertisement-ui.spec.ts[x] 任务1: 创建测试基础结构 (AC: 1, 2)
web/tests/e2e/specs/ 目录创建 tenant-advertisement-ui.spec.tsweb/tests/e2e/pages/tenant/tenant-login.page.tsweb/tests/e2e/pages/tenant/tenant-advertisement.page.tsweb/tests/e2e/fixtures/test-advertisements.json[x] 任务2: 实现登录流程测试 (AC: 2)
[x] 任务3: 实现导航测试 (AC: 3)
[x] 任务4: 实现广告列表测试 (AC: 4)
[x] 任务5: 实现创建广告测试 (AC: 5, 11, 12)
[x] 任务6: 实现编辑广告测试 (AC: 6)
[x] 任务7: 实现删除广告测试 (AC: 7)
[x] 任务8: 实现广告类型管理测试 (AC: 8)
[x] 任务9: 实现分页功能测试 (AC: 9)
[x] 任务10: 实现搜索功能测试 (AC: 10)
[x] 任务11: 实现表单验证测试 (AC: 11)
[x] 任务12: 实现图片选择器测试 (AC: 12)
[x] 任务13: 实现响应式布局测试 (AC: 13)
[x] 任务14: 更新E2E测试规范文档 (AC: 14)
docs/architecture/e2e-testing-standards.md 中添加UI交互测试示例测试成果:
web/tests/e2e/unified-advertisement-api.spec.ts API兼容性测试测试基础:
web/tests/e2e/playwright.config.ts(testDir: '.')cd web && pnpm test:e2e:chromium/api/v1/auth/login?tenantId=1 登录获取JWT token路由配置 [Source: web/src/client/tenant/routes.tsx]:
// 广告管理路由
{
path: 'unified-advertisements',
element: <UnifiedAdvertisementManagement />,
}
// 广告类型管理路由
{
path: 'unified-advertisement-types',
element: <UnifiedAdvertisementTypeManagement />,
}
菜单配置 [Source: web/src/client/tenant/menu.tsx]:
/tenant/unified-advertisements 和 /tenant/unified-advertisement-types统一广告管理UI包:
@d8d/unified-advertisement-management-ui@d8d/file-management-ui-mt 的文件选择器管理员API(需要JWT认证):
// 广告管理
GET /api/v1/admin/unified-advertisements // 列表
POST /api/v1/admin/unified-advertisements // 创建
PUT /api/v1/admin/unified-advertisements/:id // 更新
DELETE /api/v1/admin/unified-advertisements/:id // 删除
// 广告类型管理
GET /api/v1/admin/unified-advertisement-types // 列表
POST /api/v1/admin/unified-advertisement-types // 创建
PUT /api/v1/admin/unified-advertisement-types/:id // 更新
DELETE /api/v1/admin/unified-advertisement-types/:id // 删除
Playwright配置 [Source: web/tests/e2e/playwright.config.ts]:
export default defineConfig({
testDir: '.', // 当前目录,扫描.spec.ts文件
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
use: {
baseURL: process.env.E2E_BASE_URL || 'http://localhost:8080',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } },
],
});
登录页面对象示例 [Source: docs/architecture/e2e-testing-standards.md]:
// pages/tenant/tenant-login.page.ts
import { Page, expect } from '@playwright/test';
export class TenantLoginPage {
readonly page: Page;
readonly usernameInput = this.page.locator('input[name="username"]');
readonly passwordInput = this.page.locator('input[name="password"]');
readonly submitButton = this.page.locator('button[type="submit"]');
constructor(page: Page) {
this.page = page;
}
async goto() {
await this.page.goto('/tenant/login');
}
async login(username: string, password: string) {
await this.usernameInput.fill(username);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
广告管理页面对象示例:
// pages/tenant/tenant-advertisement.page.ts
import { Page, expect } from '@playwright/test';
export class TenantAdvertisementPage {
readonly page: Page;
readonly createButton = this.page.locator('[data-testid="create-advertisement-button"]');
readonly searchInput = this.page.locator('input[placeholder*="搜索"]');
readonly table = this.page.locator('[data-testid="advertisement-table"]');
constructor(page: Page) {
this.page = page;
}
async goto() {
await this.page.goto('/tenant/unified-advertisements');
}
async clickCreate() {
await this.createButton.click();
}
async search(keyword: string) {
await this.searchInput.fill(keyword);
await this.page.waitForTimeout(300); // 等待搜索防抖
}
}
使用 data-testid [Source: docs/architecture/ui-package-standards.md]:
data-testid 属性{action}-{element}-{purpose}data-testid="create-advertisement-button"data-testid="edit-advertisement-button-1"data-testid="delete-confirm-dialog-title"测试用户数据 [Source: docs/architecture/e2e-testing-standards.md]:
-- 测试租户
INSERT INTO tenant_mt (id, name, code, status, created_at, updated_at)
VALUES (1, '测试租户', 'test-tenant', 1, NOW(), NOW());
-- 测试超级管理员 (密码: admin123)
INSERT INTO users_mt (id, tenant_id, username, password, registration_source, is_disabled, is_deleted, created_at, updated_at)
VALUES (1, 1, 'admin', '$2b$10$x3t2kofPmACnk6y6lfL6ouU836LBEuZE9BinQ3ZzA4Xd04izyY42K', 'web', 0, 0, NOW(), NOW());
测试广告数据:
// fixtures/test-advertisements.json
{
"testAdvertisement": {
"title": "测试广告",
"typeId": 1,
"code": "TEST_AD",
"url": "https://example.com",
"sort": 1,
"status": 1,
"actionType": 1
},
"testAdvertisementType": {
"name": "测试类型",
"code": "TEST_TYPE",
"description": "测试广告类型",
"status": 1,
"sortOrder": 1
}
}
组件来源 [Source: packages/unified-advertisement-management-ui/src/components/]:
UnifiedAdvertisementManagement.tsx - 主管理组件AdvertisementList.tsx - 广告列表AdvertisementForm.tsx - 广告表单(创建/编辑)AdvertisementTypeManagement.tsx - 广告类型管理AdvertisementTypeForm.tsx - 广告类型表单表单字段:
设备配置 [Source: docs/architecture/e2e-testing-standards.md]:
# 运行所有E2E测试
cd web && pnpm test:e2e:chromium
# 运行特定测试文件
pnpm test:e2e tenant-advertisement-ui
# 调试模式
pnpm test:e2e:debug
# 查看测试列表
pnpm exec playwright test --config=tests/e2e/playwright.config.ts --list
page 对象进行真正的浏览器UI交互测试,而不是像故事010.006那样使用 request 对象data-testid 而不是文本选择器,避免国际化导致的测试不稳定waitForSelector 或 waitForTimeout 确保元素加载完成测试文件位置:
web/tests/e2e/specs/tenant-advertisement-ui.spec.tsweb/tests/e2e/pages/tenant/web/tests/e2e/fixtures/测试框架:
测试标准:
测试覆盖范围:
| Date | Version | Description | Author |
|---|---|---|---|
| 2026-01-03 | 1.0 | 初始故事创建 | Bob (Scrum Master) |
Claude Opus 4.5 (d8d-model) via Happy
测试状态: 测试已创建完成,部分测试可能需要根据实际环境进行调试(如应用初始化等待时间)
注意: 任务12(图片选择器测试)的完整实现需要在有测试文件数据的情况下进一步验证。
新增文件:
web/tests/e2e/specs/tenant-advertisement-ui.spec.ts - 租户后台广告管理UI交互E2E测试主文件web/tests/e2e/pages/tenant/tenant-login.page.ts - 租户后台登录页面对象web/tests/e2e/pages/tenant/tenant-advertisement.page.ts - 租户后台广告管理页面对象web/tests/e2e/fixtures/test-advertisements.json - 测试广告数据fixtures修改文件:
web/tests/e2e/playwright.config.ts - 增加了超时时间配置docs/architecture/e2e-testing-standards.md - 添加了租户后台UI交互测试示例QA代理待填写