Status: done
作为测试开发者, 我想要验证企业小程序人才列表页的完整功能, 以便确保用户能够正确查看、筛选和搜索人才信息,并且后台添加/编辑人员后能正确同步。
Given 企业用户已登录小程序 When 进入人才列表页 Then 测试应验证以下功能:
Given 人才列表页已加载 When 使用人才状态筛选器 Then 测试应验证以下场景:
Given 人才列表显示多个人才 When 查看人才卡片 Then 测试应验证以下字段:
Given 人才列表页已加载 When 使用人才搜索功能 Then 测试应验证以下场景:
Given 后台可以操作残疾人数据 When 在后台添加或编辑人员信息 Then 测试应验证以下场景:
Given 人才列表包含多个人才 When 人才数量超过单页显示数量 Then 测试应验证以下功能:
Given 人才列表已加载 When 用户与人才列表交互 Then 测试应验证以下功能:
Given 遵循项目测试规范 When 编写测试代码 Then 代码应符合以下标准:
talent-list-validation.spec.tspnpm typecheck 类型检查[ ] 任务 1: 创建人才列表验证测试文件 (AC: #8)
web/tests/e2e/specs/cross-platform/talent-list-validation.spec.ts[ ] 任务 2: 实现人才列表基础功能测试 (AC: #1, #7)
[ ] 任务 3: 实现人才状态筛选测试 (AC: #2)
[ ] 任务 4: 实现人才搜索测试 (AC: #4)
[ ] 任务 5: 实现后台添加/编辑人员后人才列表同步测试 (AC: #3, #5)
[ ] 任务 6: 实现分页功能测试 (AC: #6)(如适用)
pnpm typecheck 验证类型检查Epic 13: 跨端数据同步测试 (Epic E)
Epic 13 Story 依赖关系:
Story 13.1: 后台创建订单 → 企业小程序**订单列表**验证 ✅
Story 13.2: 后台编辑订单 → 企业小程序验证
Story 13.3: 后台添加人员 → 人才小程序**人才列表**验证
Story 13.4: 后台更新状态 → 双小程序验证
Story 13.5: 跨端测试稳定性验证
Story 13.6: 后台添加人员 → 企业小程序**首页 dashboard** 人才数据验证 ✅
Story 13.7: 企业小程序首页 **导航和交互**测试
Story 13.8: 企业小程序**订单列表页**完整验证
Story 13.9: 企业小程序**人才列表页**完整验证 ← 当前 Story
| Story | 验证目标 | 测试场景 |
|---|---|---|
| Story 13.3 | 后台添加人员 → 人才小程序人才列表验证 | 验证新增人员出现在列表中 |
| Story 13.6 | 后台添加人员 → 企业小程序首页人才卡片验证 | 验证首页人才卡片显示正确 |
| Story 13.9 | 企业小程序人才列表页完整功能验证 | 验证列表页所有功能:筛选、搜索、分页、字段显示、交互 |
Story 13.9 是 Story 13.3 的扩展和深化:
人才列表页结构(待验证):
┌─────────────────────────────────┐
│ 人才列表 (mini-talent-list) │
├─────────────────────────────────┤
│ 筛选区域: │
│ ┌─────────┬─────────┬─────────┐│
│ │状态筛选 │类型筛选 │等级筛选 ││
│ ├─────────┴─────────┴─────────┤│
│ │搜索框 │重置按钮 ││
│ └─────────────────────────────┘│
├─────────────────────────────────┤
│ 人才列表: │
│ ┌─────────────────────────────┐│
│ │ 人才卡片 1 ││
│ │ - 姓名 (张三) ││
│ │ - 残疾类型 (视力残疾) ││
│ │ - 等级 (一级) ││
│ │ - 性别/年龄 (男/30) ││
│ │ - 工作状态 (待就业) ││
│ └─────────────────────────────┘│
│ ┌─────────────────────────────┐│
│ │ 人才卡片 2 ││
│ │ - ... ││
│ └─────────────────────────────┘│
├─────────────────────────────────┤
│ 分页控件(如适用) │
└─────────────────────────────────┘
需要添加以下方法到 enterprise-mini.page.ts:
/**
* 获取人才列表
*/
async getTalentList(): Promise<TalentListItem[]> {
// 实现获取人才列表的逻辑
}
/**
* 按工作状态筛选人才
* @param workStatus 工作状态
*/
async filterByWorkStatus(workStatus: string): Promise<void> {
// 实现状态筛选逻辑
}
/**
* 按残疾类型筛选人才
* @param disabilityType 残疾类型
*/
async filterByDisabilityType(disabilityType: string): Promise<void> {
// 实现残疾类型筛选逻辑
}
/**
* 按残疾等级筛选人才
* @param disabilityLevel 残疾等级
*/
async filterByDisabilityLevel(disabilityLevel: string): Promise<void> {
// 实现残疾等级筛选逻辑
}
/**
* 搜索人才
* @param keyword 搜索关键词
*/
async searchTalents(keyword: string): Promise<void> {
// 实现搜索逻辑
}
/**
* 重置筛选和搜索
*/
async resetTalentFilters(): Promise<void> {
// 实现重置逻辑
}
/**
* 获取人才卡片详细信息
* @param talentName 人才姓名
*/
async getTalentCardInfo(talentName: string): Promise<TalentCardInfo> {
// 实现获取人才卡片信息的逻辑
}
人才卡片数据结构:
interface TalentCardInfo {
/** 人员 ID */
personId: string;
/** 姓名 */
name: string;
/** 残疾类型 */
disabilityType: '视力残疾' | '听力残疾' | '言语残疾' | '肢体残疾' | '智力残疾' | '精神残疾' | '多重残疾';
/** 残疾等级 */
disabilityLevel: '一级' | '二级' | '三级' | '四级';
/** 性别 */
gender: '男' | '女';
/** 年龄 */
age: number;
/** 工作状态 */
workStatus: '未就业' | '待就业' | '已就业' | '已离职';
/** 身份证号(脱敏) */
idCard?: string;
/** 联系电话(脱敏) */
phone?: string;
/** 所属订单 */
orderName?: string;
}
探索日期: 2026-01-14
源代码位置: mini-ui-packages/yongren-talent-management-ui/src/pages/TalentManagement/TalentManagement.tsx
发现的关键信息:
card (可点击)name-avatar {color} (颜色: blue, green, purple, orange, red, teal)enterpriseDisabilityClient.index.$get() API人才列表页选择器(源代码验证):
| 功能 | 选择器策略 |
|------|-----------|
| 人才列表容器 | .space-y-3 (父容器) |
| 人才卡片 | .card (可点击区域) |
| 姓名 | .font-semibold.text-gray-800 (卡片内第一行文本) |
| 残疾类型/等级/性别/年龄 | .text-xs.text-gray-500 (第二行文本,需解析) |
| 工作状态 | .text-xs.px-2.py-1.rounded-full (右上角标签) |
| 搜索框 | input[placeholder*="搜索"] |
| 工作状态筛选器 | 包含文本 "全部"/"在职"/"待入职"/"离职" 的 Text 元素 |
| 残疾类型筛选器 | 包含残疾类型名称的 Text 元素 |
| 分页-上一页 | 包含 "上一页" 文本的 View |
| 分页-下一页 | 包含 "下一页" 文本的 View |
| 当前页码 | 包含 "第 X 页" 文本的 Text |
数据字段映射:
| 显示字段 | 数据属性 | 格式 |
|---------|---------|------|
| 姓名 | name | 直接显示 |
| 残疾类型 | disabilityType | "未指定" 作为默认值 |
| 残疾等级 | disabilityLevel | "未分级" 作为默认值 |
| 性别 | gender | 直接显示 |
| 年龄 | birthDate | 计算得出,"未知岁" 作为默认 |
| 工作状态 | jobStatus | 中文标签(在职/待入职/离职) |
| 最新入职日期 | latestJoinDate | YYYY-MM-DD 格式,"未入职" 作为默认 |
| 薪资 | salaryDetail | 格式化为 "¥XXX" 或 "待定" |
前置条件:
测试数据准备:
// 创建不同状态的残疾人用于筛选测试
const persons = {
unemployed: await createDisabilityPerson({
workStatus: '未就业',
name: `未就业_${Date.now()}`,
disabilityType: '视力残疾',
disabilityLevel: '一级',
}),
pending: await createDisabilityPerson({
workStatus: '待就业',
name: `待就业_${Date.now()}`,
disabilityType: '听力残疾',
disabilityLevel: '二级',
}),
employed: await createDisabilityPerson({
workStatus: '已就业',
name: `已就业_${Date.now()}`,
disabilityType: '肢体残疾',
disabilityLevel: '三级',
}),
};
后台编辑后验证小程序同步:
test('后台修改人员姓名后小程序同步', async ({ disabilityPersonPage, enterpriseMiniPage }) => {
// 1. 后台创建残疾人
const originalName = `测试残疾人_${Date.now()}`;
await disabilityPersonPage.create({
name: originalName,
disabilityType: '视力残疾',
disabilityLevel: '一级',
});
// 2. 小程序验证残疾人显示
await enterpriseMiniPage.goto();
await enterpriseMiniPage.login(TEST_USER.phone, TEST_USER.password);
await enterpriseMiniPage.gotoTalentList();
let talentInfo = await enterpriseMiniPage.getTalentCardInfo(originalName);
expect(talentInfo.name).toBe(originalName);
// 3. 后台修改残疾人姓名
const updatedName = `${originalName}_更新`;
await disabilityPersonPage.edit(originalName, { name: updatedName });
// 4. 小程序验证残疾人姓名更新
await enterpriseMiniPage.waitForTalentUpdate(originalName, TIMEOUTS.SYNC);
talentInfo = await enterpriseMiniPage.getTalentCardInfo(updatedName);
expect(talentInfo.name).toBe(updatedName);
});
架构文档:
_bmad-output/planning-artifacts/epics.md#Epic 13_bmad-output/project-context.mddocs/standards/e2e-radix-testing.md相关 Story 文档:
9-5-crud-tests.md (残疾人管理 CRUD 测试)12-4-enterprise-mini-page-object.md (企业小程序 Page Object)12-5-enterprise-mini-login.md (企业小程序登录测试)13-3-person-add-sync.md (人员添加同步测试)13-6-dashboard-sync.md (首页看板数据联动测试)Story 13.9 development (2026-01-14)
Story 13.9 开发完成 (2026-01-14):
已完成任务:
实现的测试覆盖:
AC1 - 人才列表基础功能验证:
AC2 - 人才状态筛选功能验证:
AC4 - 人才搜索功能验证:
AC5 - 后台编辑同步验证:
AC6 - 分页功能验证:
AC7 - 人才列表交互功能验证:
代码质量:
pnpm typecheck 类型检查注意事项:
Created files:
/mnt/code/188-179-template-6/_bmad-output/implementation-artifacts/13-9-talent-list-validation.mdModified files:
/mnt/code/188-179-template-6/web/tests/e2e/pages/mini/enterprise-mini.page.ts
navigateToTalentList() - 导航到人才列表页getTalentList() - 获取人才列表getTalentCardInfo() - 获取指定人才卡片信息filterByWorkStatus() - 按工作状态筛选filterByDisabilityType() - 按残疾类型筛选searchTalents() - 搜索人才clearSearch() - 清除搜索resetTalentFilters() - 重置筛选getTalentListCount() - 获取人才总数getPaginationInfo() - 获取分页信息clickNextPage() - 点击下一页clickPreviousPage() - 点击上一页waitForTalentUpdate() - 等待人才更新waitForTalentListLoaded() - 等待列表加载New files:
/mnt/code/188-179-template-6/web/tests/e2e/specs/cross-platform/talent-list-validation.spec.ts
2026-01-14: Story 13.9 开发完成
2026-01-15: 代码审查完成 (bmad:bmm:workflows:code-review) - 第三次审查
2b6a7943, 4198141d, 22110852)order-detail-sync.spec.ts 在 git 中被修改但未在 Story File List 中记录admin123(第502行),应强制使用环境变量2026-01-15: 代码审查 MEDIUM 优先级问题修复完成并提交
88222f28TEST_ADMIN_PASSWORD 环境变量常量和验证validateEnvironmentVariables() 函数,同时验证企业密码和管理员密码web/tests/e2e/specs/cross-platform/talent-list-validation.spec.tsTEST_ADMIN_PASSWORD 环境变量才能运行