Selaa lähdekoodia

test(e2e): 修复 order-person 测试 - 自动选择和详情对话框问题

- 添加 autoSelectTriggeredRef 防止自动选择多次触发
- 修复 openDetailDialog 方法以正确打开下拉菜单
- 简化 openPersonManagementDialog 方法(人员管理功能已在详情对话框中)
- 修改第二个测试流程以适配 OrderDetailModal 的批量添加模式

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 5 päivää sitten
vanhempi
sitoutus
407fdf7229

+ 7 - 1
allin-packages/disability-person-management-ui/src/components/DisabledPersonSelector.tsx

@@ -104,6 +104,7 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
   // 使用 ref 存储 onSelect 和 onOpenChange,避免依赖函数引用
   const onSelectRef = useRef(onSelect);
   const onOpenChangeRef = useRef(onOpenChange);
+  const autoSelectTriggeredRef = useRef(false); // 防止自动选择多次触发
   onSelectRef.current = onSelect;
   onOpenChangeRef.current = onOpenChange;
 
@@ -116,7 +117,8 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
       mode === 'multiple' &&
       personsData?.data &&
       personsData.data.length > 0 &&
-      selectedPersons.length === 0
+      selectedPersons.length === 0 &&
+      !autoSelectTriggeredRef.current // 防止多次触发
     ) {
       // 过滤掉已禁用的人员
       const availablePersons = personsData.data.filter(
@@ -128,6 +130,9 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
         console.log('[测试自动化] onSelectRef.current 类型:', typeof onSelectRef.current);
         console.log('[测试自动化] onOpenChangeRef.current 类型:', typeof onOpenChangeRef.current);
 
+        // 标记已触发,防止重复执行
+        autoSelectTriggeredRef.current = true;
+
         // 测试环境:直接调用 onSelect 并关闭对话框
         setTimeout(() => {
           console.log('[测试自动化] 执行回调...');
@@ -153,6 +158,7 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
       setAreaSelection({});
       setShowBlacklistConfirm(false);
       setPendingSelection(null);
+      autoSelectTriggeredRef.current = false; // 重置自动选择 flag
     }
   }, [open]);
 

+ 16 - 12
web/tests/e2e/pages/admin/order-management.page.ts

@@ -560,10 +560,20 @@ export class OrderManagementPage {
    * @param orderName 订单名称
    */
   async openDetailDialog(orderName: string) {
-    // 找到订单行并点击查看详情按钮
+    // 找到订单行
     const orderRow = this.orderTable.locator('tbody tr').filter({ hasText: orderName });
-    const detailButton = orderRow.getByRole('button', { name: /详情|查看/ });
+
+    // 先点击操作菜单触发按钮("打开菜单" 或 MoreHorizontal 图标)
+    const menuTrigger = orderRow.getByRole('button', { name: /打开菜单/ });
+    await menuTrigger.click();
+
+    // 等待菜单显示
+    await this.page.waitForTimeout(200);
+
+    // 点击"查看详情"菜单项
+    const detailButton = this.page.getByRole('menuitem', { name: /查看详情/ });
     await detailButton.click();
+
     await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: 5000 });
   }
 
@@ -846,18 +856,12 @@ export class OrderManagementPage {
    * ```
    */
   async openPersonManagementDialog(orderName?: string) {
-    // 如果提供了订单名称,先找到对应的订单行
+    // 人员管理功能直接集成在订单详情对话框中
+    // 如果提供了订单名称,打开订单详情对话框
     if (orderName) {
-      const orderRow = this.orderTable.locator('tbody tr').filter({ hasText: orderName });
-      const personButton = orderRow.getByRole('button', { name: /人员|员工/ });
-      await personButton.click();
-    } else {
-      // 如果在详情页,直接点击人员管理按钮
-      const personButton = this.page.getByRole('button', { name: /人员管理|添加人员/ });
-      await personButton.click();
+      await this.openDetailDialog(orderName);
     }
-
-    await this.page.waitForSelector('[role="dialog"]', { state: 'visible', timeout: 5000 });
+    // 人员管理功能已在详情对话框中,无需额外操作
   }
 
   /**

+ 25 - 14
web/tests/e2e/specs/admin/order-person.spec.ts

@@ -498,22 +498,33 @@ test.describe('订单人员关联测试', () => {
       await orderManagementPage.submitForm();
       await orderManagementPage.waitForDialogClosed();
       await orderManagementPage.openPersonManagementDialog(testData.orderName);
-      const addButton = page.getByRole('button', { name: /添加人员|新增人员/ });
+      // 使用 first() 因为有两个"添加人员"按钮(卡片中+底部)
+      const addButton = page.getByRole('button', { name: /添加人员|新增人员/ }).first();
       await addButton.click();
       await page.waitForTimeout(300);
-      const hasPersonToAdd = await selectDisabledPersonInAddDialog(page, createdPersonName);
-      if (!hasPersonToAdd) {
-        await page.keyboard.press('Escape');
-        await orderManagementPage.closeDetailDialog();
-        test.skip(true, '没有可用的残疾人数据');
-        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('domcontentloaded')
-        .catch(() => console.debug('domcontentloaded 超时,继续检查 Toast 消息'));
+
+      // 等待残疾人选择对话框打开
+      const dialog = page.getByTestId('disabled-person-selector-dialog');
+      await dialog.waitFor({ state: 'visible', timeout: 5000 });
+
+      // 等待自动选择完成(通过检查待添加人员数量)
+      // 使用 test-id 检查待添加人员列表
+      const pendingPersonsDebug = page.getByTestId('pending-persons-debug');
+      await pendingPersonsDebug.waitFor({ state: 'attached', timeout: 10000 });
+
+      // 检查待添加人员数量
+      const pendingData = await pendingPersonsDebug.textContent();
+      console.log('待添加人员数据:', pendingData);
+
+      // 关闭残疾人选择对话框
+      await page.keyboard.press('Escape');
+      await dialog.waitFor({ state: 'hidden', timeout: 5000 });
+
+      // 点击"确认添加"按钮批量添加人员
+      const confirmButton = page.getByTestId('confirm-add-persons-button');
+      await confirmButton.click();
+
+      // 等待成功 toast
       await page.waitForTimeout(1000);
       const successToast = page.locator('[data-sonner-toast][data-type="success"]');
       const hasSuccess = await successToast.count() > 0;