|
|
@@ -0,0 +1,350 @@
|
|
|
+import { test, expect } from '../../utils/test-setup';
|
|
|
+import { readFileSync } from 'fs';
|
|
|
+import { join, dirname } from 'path';
|
|
|
+import { fileURLToPath } from 'url';
|
|
|
+
|
|
|
+const __filename = fileURLToPath(import.meta.url);
|
|
|
+const __dirname = dirname(__filename);
|
|
|
+const testUsers = JSON.parse(readFileSync(join(__dirname, '../../fixtures/test-users.json'), 'utf-8'));
|
|
|
+
|
|
|
+async function selectDisabledPersonInAddDialog(
|
|
|
+ page: Parameters<typeof test>[0]['prototype'],
|
|
|
+ personName?: string
|
|
|
+): Promise<boolean> {
|
|
|
+ const selectPersonButton = page.getByRole('button', { name: '选择残疾人' });
|
|
|
+ await selectPersonButton.click();
|
|
|
+ await page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: 5000 });
|
|
|
+ let hasData = false;
|
|
|
+ try {
|
|
|
+ if (personName) {
|
|
|
+ const personRow = page.locator('table tbody tr').filter({ hasText: personName }).first();
|
|
|
+ const rowCount = await personRow.count();
|
|
|
+ if (rowCount > 0) {
|
|
|
+ const checkbox = personRow.locator('input[type="checkbox"]').first();
|
|
|
+ await checkbox.check();
|
|
|
+ console.debug('已选择残疾人: ' + personName);
|
|
|
+ hasData = true;
|
|
|
+ } else {
|
|
|
+ console.debug('未找到残疾人: ' + personName);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const firstCheckbox = page.locator('table tbody tr').first().locator('input[type="checkbox"]').first();
|
|
|
+ await firstCheckbox.waitFor({ state: 'visible', timeout: 3000 });
|
|
|
+ await firstCheckbox.check();
|
|
|
+ console.debug('已选择第一个残疾人');
|
|
|
+ hasData = true;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.debug('没有可用的残疾人数据');
|
|
|
+ hasData = false;
|
|
|
+ }
|
|
|
+ if (hasData) {
|
|
|
+ const confirmButton = page.getByRole('button', { name: /^(确定|确认|选择)$/ });
|
|
|
+ await confirmButton.click().catch(() => {
|
|
|
+ console.debug('没有找到确认按钮,尝试关闭对话框');
|
|
|
+ page.keyboard.press('Escape');
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ await page.keyboard.press('Escape').catch(() => {
|
|
|
+ console.debug('无法关闭对话框,可能已经自动关闭');
|
|
|
+ });
|
|
|
+ }
|
|
|
+ await page.waitForTimeout(500);
|
|
|
+ return hasData;
|
|
|
+}
|
|
|
+
|
|
|
+function generateUniqueTestData() {
|
|
|
+ const timestamp = Date.now();
|
|
|
+ const random = Math.floor(Math.random() * 10000);
|
|
|
+ return {
|
|
|
+ orderName: '测试订单_' + timestamp + '_' + random,
|
|
|
+ personName: '测试残疾人_' + timestamp + '_' + random,
|
|
|
+ hireDate: '2025-01-15',
|
|
|
+ salary: 5000,
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+test.describe('订单人员关联测试', () => {
|
|
|
+ test.beforeEach(async ({ adminLoginPage, orderManagementPage }) => {
|
|
|
+ await adminLoginPage.goto();
|
|
|
+ await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
|
|
|
+ await adminLoginPage.expectLoginSuccess();
|
|
|
+ await orderManagementPage.goto();
|
|
|
+ });
|
|
|
+
|
|
|
+ test.describe('添加人员到订单', () => {
|
|
|
+ test('应该能打开订单人员管理对话框', async ({ orderManagementPage }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await orderManagementPage.page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await orderManagementPage.page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ const hasDisabledPerson = await selectDisabledPersonInAddDialog(orderManagementPage.page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const dialog = orderManagementPage.page.locator('[role="dialog"]');
|
|
|
+ await expect(dialog).toBeVisible();
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+
|
|
|
+ test('应该能添加残疾人到订单', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ const hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const addButton = page.getByRole('button', { name: /添加人员|新增人员/ });
|
|
|
+ await addButton.click();
|
|
|
+ await page.waitForTimeout(300);
|
|
|
+ const selected = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!selected) {
|
|
|
+ await page.keyboard.press('Escape');
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await page.getByLabel(/入职日期/).fill(testData.hireDate);
|
|
|
+ await page.getByLabel(/薪资|工资/).fill(String(testData.salary));
|
|
|
+ const submitButton = page.getByRole('button', { name: /^(添加|确定|保存)$/ });
|
|
|
+ await submitButton.click();
|
|
|
+ await page.waitForLoadState('networkidle');
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
+ const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ const hasSuccess = await successToast.count() > 0;
|
|
|
+ expect(hasSuccess).toBe(true);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+
|
|
|
+ test('添加的人员应该出现在订单详情中', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ const hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openDetailDialog(testData.orderName);
|
|
|
+ const personList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ expect(personList.length).toBeGreaterThan(0);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ test.describe('管理工作状态', () => {
|
|
|
+ test('应该能修改人员工作状态:未就业 → 待就业', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ let hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const initialPersonList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ if (initialPersonList.length === 0 || !initialPersonList[0].name) {
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.updatePersonWorkStatus(initialPersonList[0].name, 'pending');
|
|
|
+ const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ const hasSuccess = await successToast.count() > 0;
|
|
|
+ expect(hasSuccess).toBe(true);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+
|
|
|
+ test('应该能修改人员工作状态:待就业 → 已就业', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ let hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const personList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ if (personList.length === 0 || !personList[0].name) {
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.updatePersonWorkStatus(personList[0].name, 'employed');
|
|
|
+ const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ const hasSuccess = await successToast.count() > 0;
|
|
|
+ expect(hasSuccess).toBe(true);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+
|
|
|
+ test('应该能修改人员工作状态:已就业 → 已离职', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ let hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const personList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ if (personList.length === 0 || !personList[0].name) {
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.updatePersonWorkStatus(personList[0].name, 'resigned');
|
|
|
+ const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ const hasSuccess = await successToast.count() > 0;
|
|
|
+ expect(hasSuccess).toBe(true);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ test.describe('设置实际入职日期', () => {
|
|
|
+ test('应该能设置人员的实际入职日期', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ const actualHireDate = '2025-02-01';
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ let hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const personList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ if (personList.length === 0 || !personList[0].name) {
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const personRow = page.locator('[role="dialog"]').locator('table tbody tr').filter({ hasText: personList[0].name }).first();
|
|
|
+ const editButton = personRow.getByRole('button', { name: /编辑|修改/ });
|
|
|
+ await editButton.click();
|
|
|
+ await page.waitForTimeout(300);
|
|
|
+ const actualHireDateInput = page.getByLabel(/实际入职日期/);
|
|
|
+ await actualHireDateInput.fill(actualHireDate);
|
|
|
+ const submitButton = page.getByRole('button', { name: /^(更新|保存|确定)$/ });
|
|
|
+ await submitButton.click();
|
|
|
+ await page.waitForLoadState('networkidle');
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
+ const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ const hasSuccess = await successToast.count() > 0;
|
|
|
+ expect(hasSuccess).toBe(true);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ test.describe('人员离职', () => {
|
|
|
+ test('应该能设置人员为已离职状态并设置离职日期', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ const resignDate = '2025-03-15';
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ let hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const personList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ if (personList.length === 0 || !personList[0].name) {
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const personRow = page.locator('[role="dialog"]').locator('table tbody tr').filter({ hasText: personList[0].name }).first();
|
|
|
+ const editButton = personRow.getByRole('button', { name: /编辑|修改/ });
|
|
|
+ await editButton.click();
|
|
|
+ await page.waitForTimeout(300);
|
|
|
+ await page.getByLabel(/工作状态/).click();
|
|
|
+ await page.getByRole('option', { name: '已离职' }).click();
|
|
|
+ const resignDateInput = page.getByLabel(/离职日期/);
|
|
|
+ await resignDateInput.fill(resignDate);
|
|
|
+ const submitButton = page.getByRole('button', { name: /^(更新|保存|确定)$/ });
|
|
|
+ await submitButton.click();
|
|
|
+ await page.waitForLoadState('networkidle');
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
+ const successToast = page.locator('[data-sonner-toast][data-type="success"]');
|
|
|
+ const hasSuccess = await successToast.count() > 0;
|
|
|
+ expect(hasSuccess).toBe(true);
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+
|
|
|
+ test('离职后人员状态应显示为已离职', async ({ orderManagementPage, page }) => {
|
|
|
+ const testData = generateUniqueTestData();
|
|
|
+ await orderManagementPage.openCreateDialog();
|
|
|
+ await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
|
|
|
+ await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
|
|
|
+ let hasDisabledPerson = await selectDisabledPersonInAddDialog(page);
|
|
|
+ if (!hasDisabledPerson) {
|
|
|
+ await orderManagementPage.cancelDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await orderManagementPage.submitForm();
|
|
|
+ await orderManagementPage.waitForDialogClosed();
|
|
|
+ await orderManagementPage.openPersonManagementDialog(testData.orderName);
|
|
|
+ const personList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ if (personList.length === 0 || !personList[0].name) {
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ test.skip();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const personRow = page.locator('[role="dialog"]').locator('table tbody tr').filter({ hasText: personList[0].name }).first();
|
|
|
+ const editButton = personRow.getByRole('button', { name: /编辑|修改/ });
|
|
|
+ await editButton.click();
|
|
|
+ await page.waitForTimeout(300);
|
|
|
+ await page.getByLabel(/工作状态/).click();
|
|
|
+ await page.getByRole('option', { name: '已离职' }).click();
|
|
|
+ const submitButton = page.getByRole('button', { name: /^(更新|保存|确定)$/ });
|
|
|
+ await submitButton.click();
|
|
|
+ await page.waitForLoadState('networkidle');
|
|
|
+ await page.waitForTimeout(1000);
|
|
|
+ const updatedPersonList = await orderManagementPage.getPersonListFromDetail();
|
|
|
+ const resignedPerson = updatedPersonList.find(p => p.name === personList[0].name);
|
|
|
+ expect(resignedPerson).toBeDefined();
|
|
|
+ expect(resignedPerson?.workStatus).toBe('已离职');
|
|
|
+ await orderManagementPage.closeDetailDialog();
|
|
|
+ });
|
|
|
+ });
|
|
|
+});
|