| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- import { TIMEOUTS } from '../../utils/timeouts';
- import { test, expect } from '../../utils/test-setup';
- import type { Page } from '@playwright/test';
- import { AdminLoginPage } from '../../pages/admin/login.page';
- import { DisabilityPersonManagementPage } from '../../pages/admin/disability-person.page';
- import { EnterpriseMiniPage } from '../../pages/mini/enterprise-mini.page';
- /**
- * 跨系统数据一致性验证测试 (Story 13.12 任务 12-15)
- *
- * 测试目标:验证后台操作后,小程序数据统计页的数据是否正确更新
- *
- * 测试场景:
- * 1. 后台添加人员 → 小程序统计更新验证
- * 2. 修改人员状态 → 统计数据变化验证
- * 3. 数据删除后的统计更新
- *
- * 测试要点:
- * - 使用两个独立的 browser context(后台和小程序)
- * - 记录数据变化前后的统计值
- * - 验证数据同步的准确性
- */
- // 测试常量
- const TEST_SYNC_TIMEOUT = 10000; // 数据同步等待时间(ms)
- const TEST_POLL_INTERVAL = 500; // 轮询检查间隔(ms)
- // 小程序登录凭据
- const ENTERPRISE_LOGIN_PHONE = '13800001111';
- const ENTERPRISE_LOGIN_PASSWORD = 'password123';
- // 后台登录凭据
- const ADMIN_USERNAME = 'admin';
- const ADMIN_PASSWORD = 'admin123';
- /**
- * 后台登录辅助函数
- */
- async function loginAdmin(page: Page) {
- const adminLoginPage = new AdminLoginPage(page);
- await adminLoginPage.goto();
- await adminLoginPage.login(ADMIN_USERNAME, ADMIN_PASSWORD);
- await adminLoginPage.expectLoginSuccess();
- console.debug('[后台] 登录成功');
- }
- /**
- * 小程序登录辅助函数
- */
- async function loginEnterpriseMini(miniPage: EnterpriseMiniPage) {
- await miniPage.goto();
- await miniPage.login(ENTERPRISE_LOGIN_PHONE, ENTERPRISE_LOGIN_PASSWORD);
- await miniPage.expectLoginSuccess();
- return miniPage;
- }
- // 测试状态管理
- interface TestState {
- initialEmploymentCount: number | null;
- updatedEmploymentCount: number | null;
- personId: number | null;
- personName: string | null;
- syncTime: number | null;
- }
- const testState: TestState = {
- initialEmploymentCount: null,
- updatedEmploymentCount: null,
- personId: null,
- personName: null,
- syncTime: null,
- };
- // 生成唯一的测试数据
- function generateTestPerson() {
- const timestamp = Date.now();
- return {
- name: `统计测试_${timestamp}`,
- gender: '男',
- idCard: `110101199001011${String(timestamp).slice(-2)}`,
- disabilityId: `1234567890${String(timestamp).slice(-4)}`,
- disabilityType: '肢体残疾',
- disabilityLevel: '一级',
- phone: `138${String(timestamp).slice(-8)}`,
- idAddress: `广东省广州市测试路${timestamp % 100}号`,
- province: '广东省',
- city: '广州市',
- };
- }
- test.describe('跨系统数据一致性验证 - Story 13.12 (任务 12-15)', () => {
- // 在所有测试后清理测试数据
- test.afterAll(async ({ adminPage }) => {
- // 清理测试数据
- if (testState.personId && testState.personName) {
- try {
- await loginAdmin(adminPage);
- const personPage = new DisabilityPersonManagementPage(adminPage);
- await personPage.goto();
- // 搜索并删除测试人员
- await personPage.searchByName(testState.personName);
- await personPage.page.waitForTimeout(TIMEOUTS.SHORT);
- // 检查是否找到该人员
- const exists = await personPage.personExists(testState.personName);
- if (exists) {
- await personPage.deleteDisabilityPerson(testState.personName);
- console.debug(`[清理] 已删除测试人员: ${testState.personName}`);
- }
- } catch (error) {
- console.debug(`[清理] 删除测试人员失败: ${error}`);
- }
- }
- // 重置测试状态
- testState.initialEmploymentCount = null;
- testState.updatedEmploymentCount = null;
- testState.personId = null;
- testState.personName = null;
- testState.syncTime = null;
- console.debug('[清理] 测试数据已清理');
- });
- test.describe.serial('任务 12: 后台添加人员 → 小程序统计更新验证', () => {
- test('步骤 1: 获取小程序初始统计数据', async ({ enterpriseMiniPage: page }) => {
- const miniPage = await loginEnterpriseMini(page);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- // 记录初始在职人数
- const initialCount = await miniPage.getEmploymentCount();
- testState.initialEmploymentCount = initialCount;
- console.debug(`[小程序] 初始在职人数: ${initialCount ?? '无数据'}`);
- });
- test('步骤 2: 后台添加在职人员', async ({ adminPage }) => {
- await loginAdmin(adminPage);
- const personPage = new DisabilityPersonManagementPage(adminPage);
- await personPage.goto();
- // 生成测试人员数据
- const testPerson = generateTestPerson();
- testState.personName = testPerson.name;
- // 打开创建对话框
- await personPage.openCreateDialog();
- await adminPage.waitForTimeout(TIMEOUTS.MEDIUM);
- // 填写表单
- await personPage.fillBasicForm(testPerson);
- // 提交表单
- const result = await personPage.submitForm();
- // 验证创建成功
- expect(result.hasSuccess || !result.hasError).toBe(true);
- console.debug(`[后台] 创建人员成功: ${testPerson.name}`);
- // 等待人员记录出现
- const personExists = await personPage.waitForPersonExists(testPerson.name, {
- timeout: TIMEOUTS.TABLE_LOAD,
- });
- expect(personExists).toBe(true);
- // 搜索人员获取 ID
- await personPage.searchByName(testPerson.name);
- await adminPage.waitForTimeout(TIMEOUTS.MEDIUM);
- console.debug(`[后台] 人员已添加: ${testPerson.name}`);
- });
- test('步骤 3: 验证小程序统计数据更新', async ({ enterpriseMiniPage: page }) => {
- const miniPage = await loginEnterpriseMini(page);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- // 记录同步开始时间
- const syncStartTime = Date.now();
- // 轮询检查统计数据是否更新
- let updatedCount: number | null = null;
- let found = false;
- for (let elapsed = 0; elapsed <= TEST_SYNC_TIMEOUT; elapsed += TEST_POLL_INTERVAL) {
- // 强制刷新统计数据
- await miniPage.forceRefreshStatistics();
- await miniPage.waitForStatisticsDataLoaded();
- updatedCount = await miniPage.getEmploymentCount();
- // 检查数据是否更新(在职人数应该增加)
- if (testState.initialEmploymentCount !== null &&
- updatedCount !== null &&
- updatedCount > testState.initialEmploymentCount) {
- found = true;
- testState.syncTime = Date.now() - syncStartTime;
- console.debug(`[小程序] 统计数据已更新,耗时: ${testState.syncTime}ms`);
- break;
- }
- await page.page.waitForTimeout(TEST_POLL_INTERVAL);
- }
- testState.updatedEmploymentCount = updatedCount;
- // 验证数据已更新
- expect(found, `在职人数应该从 ${testState.initialEmploymentCount} 增加`).toBe(true);
- expect(updatedCount).toBeGreaterThan(testState.initialEmploymentCount ?? 0);
- console.debug(`[验证] 初始在职人数: ${testState.initialEmploymentCount}`);
- console.debug(`[验证] 更新后在职人数: ${updatedCount}`);
- console.debug(`[验证] 在职人数增加: ${(updatedCount ?? 0) - (testState.initialEmploymentCount ?? 0)}`);
- });
- });
- test.describe.serial('任务 13: 修改人员状态 → 统计数据变化验证', () => {
- test('步骤 1: 获取小程序当前统计数据', async ({ enterpriseMiniPage: miniPage }) => {
- await loginEnterpriseMini(miniPage);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- const currentCount = await miniPage.getEmploymentCount();
- testState.initialEmploymentCount = currentCount;
- console.debug(`[小程序] 当前在职人数: ${currentCount ?? '无数据'}`);
- });
- test('步骤 2: 后台修改人员状态为未在职', async ({ adminPage }) => {
- if (!testState.personName) {
- console.debug('[跳过] 未找到测试人员,跳过状态修改测试');
- test.skip();
- return;
- }
- await loginAdmin(adminPage);
- const personPage = new DisabilityPersonManagementPage(adminPage);
- await personPage.goto();
- // 搜索测试人员
- await personPage.searchByName(testState.personName);
- await adminPage.waitForTimeout(TIMEOUTS.MEDIUM);
- // 打开编辑对话框
- await personPage.openEditDialog(testState.personName);
- await adminPage.waitForTimeout(TIMEOUTS.MEDIUM);
- // 修改人员工作状态为"未在职"(离职)
- const result = await personPage.updateWorkStatus(false);
- // 验证修改成功
- expect(result.hasSuccess || !result.hasError).toBe(true);
- console.debug(`[后台] 已修改人员状态为未在职: ${testState.personName}`);
- });
- test('步骤 3: 验证小程序在职人数减少', async ({ enterpriseMiniPage: miniPage }) => {
- if (!testState.personName) {
- test.skip();
- return;
- }
- await loginEnterpriseMini(miniPage);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- // 记录同步开始时间
- const syncStartTime = Date.now();
- // 轮询检查统计数据是否更新
- let updatedCount: number | null = null;
- let found = false;
- for (let elapsed = 0; elapsed <= TEST_SYNC_TIMEOUT; elapsed += TEST_POLL_INTERVAL) {
- // 强制刷新统计数据
- await miniPage.forceRefreshStatistics();
- await miniPage.waitForStatisticsDataLoaded();
- updatedCount = await miniPage.getEmploymentCount();
- // 检查数据是否更新(在职人数应该减少)
- if (testState.initialEmploymentCount !== null &&
- updatedCount !== null &&
- updatedCount < testState.initialEmploymentCount) {
- found = true;
- testState.syncTime = Date.now() - syncStartTime;
- console.debug(`[小程序] 统计数据已更新,耗时: ${testState.syncTime}ms`);
- break;
- }
- await miniPage.page.waitForTimeout(TEST_POLL_INTERVAL);
- }
- testState.updatedEmploymentCount = updatedCount;
- // 验证数据已更新
- expect(found, `在职人数应该从 ${testState.initialEmploymentCount} 减少`).toBe(true);
- if (testState.initialEmploymentCount !== null) {
- expect(updatedCount).toBeLessThan(testState.initialEmploymentCount);
- }
- console.debug(`[验证] 修改前在职人数: ${testState.initialEmploymentCount}`);
- console.debug(`[验证] 修改后在职人数: ${updatedCount}`);
- console.debug(`[验证] 在职人数减少: ${(testState.initialEmploymentCount ?? 0) - (updatedCount ?? 0)}`);
- });
- });
- test.describe.serial('任务 14: 边界条件测试', () => {
- test('无数据场景:切换到无数据的年份', async ({ enterpriseMiniPage: miniPage }) => {
- await loginEnterpriseMini(miniPage);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- // 切换到较早的年份(可能无数据)
- await miniPage.selectYear(2020);
- await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
- // 验证页面不会崩溃
- const cards = await miniPage.getStatisticsCards();
- expect(cards.length).toBeGreaterThan(0);
- // 验证显示无数据状态
- const employmentCount = await miniPage.getEmploymentCount();
- expect(employmentCount === null || employmentCount === 0).toBeTruthy();
- console.debug('[验证] 无数据场景测试通过');
- });
- test('跨年跨月:切换年份和月份', async ({ enterpriseMiniPage: miniPage }) => {
- await loginEnterpriseMini(miniPage);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- // 切换到下一年
- const nextYear = new Date().getFullYear() + 1;
- await miniPage.selectYear(nextYear);
- await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
- // 切换到1月
- await miniPage.selectMonth(1);
- await miniPage.page.waitForTimeout(TIMEOUTS.MEDIUM);
- // 验证页面正常显示
- const cards = await miniPage.getStatisticsCards();
- expect(cards.length).toBeGreaterThan(0);
- console.debug('[验证] 跨年跨月测试通过');
- });
- });
- test.describe.serial('任务 15: 数据一致性验证方法测试', () => {
- test('验证 validateStatisticsAccuracy 方法', async ({ enterpriseMiniPage: miniPage }) => {
- await loginEnterpriseMini(miniPage);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- // 获取当前实际数据
- const actualEmploymentCount = await miniPage.getEmploymentCount();
- const actualAverageSalary = await miniPage.getAverageSalary();
- console.debug('[任务 15.1] 实际数据:', {
- employmentCount: actualEmploymentCount,
- averageSalary: actualAverageSalary,
- });
- // 测试验证方法 - 应该与实际数据匹配
- if (actualEmploymentCount !== null) {
- const result1 = await miniPage.validateStatisticsAccuracy({
- employmentCount: actualEmploymentCount,
- });
- expect(result1.passed).toBe(true);
- expect(result1.details.employmentCount?.match).toBe(true);
- }
- if (actualAverageSalary !== null) {
- const result2 = await miniPage.validateStatisticsAccuracy({
- averageSalary: actualAverageSalary,
- });
- expect(result2.passed).toBe(true);
- expect(result2.details.averageSalary?.match).toBe(true);
- }
- // 测试验证方法 - 应该与错误数据不匹配
- const result3 = await miniPage.validateStatisticsAccuracy({
- employmentCount: 999999, // 明显错误的值
- });
- expect(result3.passed).toBe(false);
- expect(result3.details.employmentCount?.match).toBe(false);
- console.debug('[任务 15] ✓ 数据一致性验证方法测试通过');
- });
- });
- test.describe.serial('综合测试:完整的跨系统数据验证流程', () => {
- test('后台操作 → 小程序统计验证的完整流程', async ({ adminPage, enterpriseMiniPage: miniPage }) => {
- // 此测试验证完整的跨系统数据同步流程
- // 1. 获取初始统计
- await loginEnterpriseMini(miniPage);
- await miniPage.navigateToStatisticsPage();
- await miniPage.waitForStatisticsDataLoaded();
- const initialStats = {
- employmentCount: await miniPage.getEmploymentCount(),
- averageSalary: await miniPage.getAverageSalary(),
- employmentRate: await miniPage.getEmploymentRate(),
- };
- console.debug('[综合测试] 步骤 1: 初始统计数据:', initialStats);
- // 2. 后台操作(这里只是示例,实际需要添加或修改数据)
- await loginAdmin(adminPage);
- const personPage = new DisabilityPersonManagementPage(adminPage);
- await personPage.goto();
- console.debug('[综合测试] 步骤 2: 后台操作完成');
- // 3. 验证小程序统计更新
- await miniPage.forceRefreshStatistics();
- await miniPage.waitForStatisticsDataLoaded();
- const updatedStats = {
- employmentCount: await miniPage.getEmploymentCount(),
- averageSalary: await miniPage.getAverageSalary(),
- employmentRate: await miniPage.getEmploymentRate(),
- };
- console.debug('[综合测试] 步骤 3: 更新后统计数据:', updatedStats);
- // 4. 验证数据一致性
- const validation = await miniPage.validateStatisticsAccuracy({
- employmentCount: updatedStats.employmentCount ?? undefined,
- averageSalary: updatedStats.averageSalary ?? undefined,
- });
- expect(validation.passed).toBe(true);
- console.debug('[综合测试] ✓ 完整的跨系统数据验证流程通过');
- });
- });
- });
|