order-person.spec.ts 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191
  1. import { test, expect } from '../../utils/test-setup';
  2. import { readFileSync } from 'fs';
  3. import { join, dirname } from 'path';
  4. import { fileURLToPath } from 'url';
  5. import type { Page } from '@playwright/test';
  6. const __filename = fileURLToPath(import.meta.url);
  7. const __dirname = dirname(__filename);
  8. const testUsers = JSON.parse(readFileSync(join(__dirname, '../../fixtures/test-users.json'), 'utf-8'));
  9. // 存储 API 创建的测试数据
  10. let createdPersonName: string | null = null;
  11. let createdPlatformName: string | null = null;
  12. let createdCompanyName: string | null = null;
  13. // 获取认证 token
  14. async function getAuthToken(request: Parameters<typeof test>[0]['request']): Promise<string | null> {
  15. const loginResponse = await request.post('http://localhost:8080/api/v1/auth/login', {
  16. data: {
  17. username: testUsers.admin.username,
  18. password: testUsers.admin.password
  19. }
  20. });
  21. if (!loginResponse.ok()) {
  22. console.debug('API 登录失败:', await loginResponse.text());
  23. return null;
  24. }
  25. const loginData = await loginResponse.json();
  26. return loginData.data?.token || loginData.token || null;
  27. }
  28. // API 调用辅助函数 - 使用 API 直接创建残疾人数据
  29. async function createDisabledPersonViaAPI(
  30. request: Parameters<typeof test>[0]['request'],
  31. personData: {
  32. name: string;
  33. gender: string;
  34. idCard: string;
  35. disabilityId: string;
  36. disabilityType: string;
  37. disabilityLevel: string;
  38. idAddress: string;
  39. phone: string;
  40. province: string;
  41. city: string;
  42. }
  43. ): Promise<{ id: number; name: string } | null> {
  44. try {
  45. const token = await getAuthToken(request);
  46. if (!token) return null;
  47. const createResponse = await request.post('http://localhost:8080/api/v1/disability/createDisabledPerson', {
  48. headers: {
  49. 'Authorization': `Bearer ${token}`,
  50. 'Content-Type': 'application/json'
  51. },
  52. data: personData
  53. });
  54. if (!createResponse.ok()) {
  55. const errorText = await createResponse.text();
  56. console.debug('API 创建残疾人失败:', createResponse.status(), errorText);
  57. return null;
  58. }
  59. const result = await createResponse.json();
  60. console.debug('API 创建残疾人成功:', result.name);
  61. return { id: result.id, name: result.name };
  62. } catch (error) {
  63. console.debug('API 调用出错:', error);
  64. return null;
  65. }
  66. }
  67. // 创建测试平台
  68. async function createPlatformViaAPI(
  69. request: Parameters<typeof test>[0]['request']
  70. ): Promise<{ id: number; name: string } | null> {
  71. try {
  72. const token = await getAuthToken(request);
  73. if (!token) return null;
  74. const timestamp = Date.now();
  75. const platformData = {
  76. platformName: `测试平台_${timestamp}`,
  77. contactPerson: '测试联系人',
  78. contactPhone: '13800138000',
  79. contactEmail: 'test@example.com'
  80. };
  81. const createResponse = await request.post('http://localhost:8080/api/v1/platform/createPlatform', {
  82. headers: {
  83. 'Authorization': `Bearer ${token}`,
  84. 'Content-Type': 'application/json'
  85. },
  86. data: platformData
  87. });
  88. if (!createResponse.ok()) {
  89. const errorText = await createResponse.text();
  90. console.debug('API 创建平台失败:', createResponse.status(), errorText);
  91. return null;
  92. }
  93. const result = await createResponse.json();
  94. console.debug('API 创建平台成功:', result.id, result.platformName);
  95. return { id: result.id, name: result.platformName };
  96. } catch (error) {
  97. console.debug('创建平台 API 调用出错:', error);
  98. return null;
  99. }
  100. }
  101. // 创建测试公司
  102. async function createCompanyViaAPI(
  103. request: Parameters<typeof test>[0]['request'],
  104. platformId: number
  105. ): Promise<{ id: number; name: string } | null> {
  106. try {
  107. const token = await getAuthToken(request);
  108. if (!token) return null;
  109. const timestamp = Date.now();
  110. const companyName = `测试公司_${timestamp}`;
  111. const companyData = {
  112. companyName: companyName,
  113. platformId: platformId,
  114. contactPerson: '测试联系人',
  115. contactPhone: '13900139000',
  116. contactEmail: 'company@example.com'
  117. };
  118. const createResponse = await request.post('http://localhost:8080/api/v1/company/createCompany', {
  119. headers: {
  120. 'Authorization': `Bearer ${token}`,
  121. 'Content-Type': 'application/json'
  122. },
  123. data: companyData
  124. });
  125. if (!createResponse.ok()) {
  126. const errorText = await createResponse.text();
  127. console.debug('API 创建公司失败:', createResponse.status(), errorText);
  128. return null;
  129. }
  130. const createResult = await createResponse.json();
  131. if (!createResult.success) {
  132. console.debug('API 创建公司返回 success=false');
  133. return null;
  134. }
  135. // 创建成功后,通过平台ID查询公司列表来获取公司ID
  136. const listResponse = await request.get(`http://localhost:8080/api/v1/company/getCompaniesByPlatform/${platformId}`, {
  137. headers: {
  138. 'Authorization': `Bearer ${token}`
  139. }
  140. });
  141. if (!listResponse.ok()) {
  142. console.debug('API 获取公司列表失败');
  143. return null;
  144. }
  145. const companies = await listResponse.json();
  146. const createdCompany = companies.find((c: any) => c.companyName === companyName);
  147. if (createdCompany) {
  148. console.debug('API 创建公司成功:', createdCompany.id, createdCompany.companyName);
  149. return { id: createdCompany.id, name: createdCompany.companyName };
  150. }
  151. console.debug('未找到创建的公司');
  152. return null;
  153. } catch (error) {
  154. console.debug('创建公司 API 调用出错:', error);
  155. return null;
  156. }
  157. }
  158. async function selectDisabledPersonInAddDialog(
  159. page: Page,
  160. personName?: string
  161. ): Promise<boolean> {
  162. const selectPersonButton = page.getByRole('button', { name: '选择残疾人' });
  163. await selectPersonButton.click();
  164. // 等待残疾人选择器对话框出现(可能有多个对话框,找到最新的那个)
  165. const dialogs = page.locator('[role="dialog"]');
  166. await dialogs.last().waitFor({ state: 'visible', timeout: 10000 });
  167. // 获取最新的对话框作为操作上下文
  168. const dialog = dialogs.last();
  169. let hasData = false;
  170. try {
  171. if (personName) {
  172. // 等待对话框完全加载
  173. await page.waitForTimeout(500);
  174. // 使用搜索功能查找残疾人 - 在对话框内查找
  175. const searchInput = dialog.locator('[data-testid="search-name-input"]');
  176. await searchInput.waitFor({ state: 'visible', timeout: 5000 });
  177. await searchInput.fill(personName);
  178. console.debug('已输入搜索关键词: ' + personName);
  179. // 点击搜索按钮 - 在对话框内查找,使用 .first() 处理多个匹配
  180. const searchButton = dialog.getByTestId('search-button').first();
  181. await searchButton.click();
  182. console.debug('已点击搜索按钮');
  183. // 等待表格出现(使用 testid 定位)
  184. const table = dialog.locator('[data-testid="disabled-persons-table"]');
  185. await table.waitFor({ state: 'visible', timeout: 5000 }).catch(() => {
  186. console.debug('表格未显示');
  187. });
  188. // 等待表格数据加载完成 - 等待表格行出现
  189. await page.waitForTimeout(1500);
  190. // 获取所有表格行进行调试
  191. const allRows = dialog.locator('table tbody tr');
  192. const rowCount = await allRows.count();
  193. console.debug('表格行数:', rowCount);
  194. // 查找包含指定姓名的行 - 在对话框内查找
  195. const personRow = allRows.filter({ hasText: personName });
  196. const personRowCount = await personRow.count();
  197. console.debug('匹配的人名行数:', personRowCount);
  198. if (personRowCount > 0) {
  199. const targetRow = personRow.first();
  200. // 在测试环境中,Checkbox 使用原生 HTML input,直接勾选即可
  201. const checkbox = targetRow.getByRole('checkbox');
  202. await checkbox.waitFor({ state: 'visible', timeout: 5000 });
  203. await checkbox.check();
  204. console.debug('已勾选残疾人复选框');
  205. // 点击确认选择按钮
  206. const confirmButton = dialog.getByTestId('confirm-batch-button');
  207. await confirmButton.click();
  208. console.debug('已点击确认选择按钮');
  209. hasData = true;
  210. } else {
  211. console.debug('未找到残疾人: ' + personName);
  212. // 调试:打印表格内容
  213. const tableText = await table.textContent();
  214. console.debug('表格内容:', tableText?.substring(0, 200));
  215. }
  216. } else {
  217. // 等待表格数据加载
  218. await dialog.locator('table tbody tr').first().waitFor({ state: 'attached', timeout: 5000 }).catch(() => {
  219. console.debug('没有找到表格行');
  220. });
  221. await page.waitForTimeout(500);
  222. // 不指定人名时,勾选第一个可用行
  223. const firstRow = dialog.locator('table tbody tr').first();
  224. const checkbox = firstRow.getByRole('checkbox');
  225. await checkbox.waitFor({ state: 'visible', timeout: 5000 });
  226. await checkbox.check();
  227. console.debug('已勾选第一个残疾人');
  228. // 点击确认选择按钮
  229. const confirmButton = dialog.getByTestId('confirm-batch-button');
  230. await confirmButton.click();
  231. console.debug('已点击确认选择按钮');
  232. hasData = true;
  233. }
  234. } catch (error) {
  235. console.debug('选择残疾人时出错:', error);
  236. hasData = false;
  237. }
  238. if (!hasData) {
  239. // 点击取消按钮关闭对话框 - 在对话框内查找
  240. const cancelButton = dialog.getByTestId('cancel-button');
  241. await cancelButton.click().catch(() => {
  242. console.debug('无法点击取消按钮,尝试关闭对话框');
  243. page.keyboard.press('Escape');
  244. });
  245. }
  246. // 无论如何都等待一下让对话框有时间关闭
  247. await page.waitForTimeout(500);
  248. return hasData;
  249. }
  250. function generateUniqueTestData() {
  251. const timestamp = Date.now();
  252. const random = Math.floor(Math.random() * 10000);
  253. return {
  254. orderName: '测试订单_' + timestamp + '_' + random,
  255. personName: '测试残疾人_' + timestamp + '_' + random,
  256. hireDate: '2025-01-15',
  257. salary: 5000,
  258. };
  259. }
  260. // 等待订单行出现在表格中
  261. async function waitForOrderRow(page: Page, orderName: string, timeout = 15000) {
  262. const startTime = Date.now();
  263. while (Date.now() - startTime < timeout) {
  264. const table = page.locator('table');
  265. const orderRow = table.locator('tbody tr').filter({ hasText: orderName });
  266. const count = await orderRow.count();
  267. if (count > 0) {
  268. console.debug('找到订单行:', orderName);
  269. return true;
  270. }
  271. await page.waitForTimeout(500);
  272. }
  273. console.debug('等待订单行超时:', orderName);
  274. return false;
  275. }
  276. test.describe('订单人员关联测试', () => {
  277. test.beforeEach(async ({ adminLoginPage, orderManagementPage, request }) => {
  278. // 登录
  279. await adminLoginPage.goto();
  280. await adminLoginPage.login(testUsers.admin.username, testUsers.admin.password);
  281. await adminLoginPage.expectLoginSuccess();
  282. await orderManagementPage.goto();
  283. // 使用 API 创建平台和公司测试数据
  284. const createdPlatform = await createPlatformViaAPI(request);
  285. if (!createdPlatform) {
  286. console.debug('无法创建平台数据,测试可能被跳过');
  287. createdPlatformName = null;
  288. } else {
  289. createdPlatformName = createdPlatform.name;
  290. }
  291. if (createdPlatform) {
  292. const createdCompany = await createCompanyViaAPI(request, createdPlatform.id);
  293. if (!createdCompany) {
  294. console.debug('无法创建公司数据,测试可能被跳过');
  295. createdCompanyName = null;
  296. } else {
  297. createdCompanyName = createdCompany.name;
  298. }
  299. }
  300. // 使用 API 创建残疾人测试数据
  301. const timestamp = Date.now();
  302. const random = Math.floor(Math.random() * 10000);
  303. const personName = `测试残疾人_${timestamp}_${random}`;
  304. const personData = {
  305. name: personName,
  306. gender: '男',
  307. idCard: `110101199001011${String(random).padStart(4, '0')}`,
  308. disabilityId: `CJZ${timestamp}${random}`,
  309. disabilityType: '视力残疾',
  310. disabilityLevel: '一级',
  311. idAddress: '北京市东城区测试地址',
  312. phone: `138${String(random).padStart(8, '0')}`,
  313. province: '北京市',
  314. city: '北京市'
  315. };
  316. const createdPerson = await createDisabledPersonViaAPI(request, personData);
  317. if (!createdPerson) {
  318. console.debug('无法创建残疾人数据,测试可能被跳过');
  319. createdPersonName = null;
  320. } else {
  321. createdPersonName = createdPerson.name;
  322. console.debug('已创建残疾人:', createdPersonName);
  323. }
  324. });
  325. test.describe('添加人员到订单', () => {
  326. test('应该能打开订单人员管理对话框', async ({ orderManagementPage }) => {
  327. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  328. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  329. return;
  330. }
  331. const testData = generateUniqueTestData();
  332. await orderManagementPage.openCreateDialog();
  333. await orderManagementPage.page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  334. // 选择平台
  335. const platformTrigger = orderManagementPage.page.locator('[data-testid="platform-selector-create"]');
  336. if (await platformTrigger.count() > 0) {
  337. await platformTrigger.click();
  338. await orderManagementPage.page.waitForTimeout(800);
  339. const allOptions = orderManagementPage.page.getByRole('option');
  340. const count = await allOptions.count();
  341. console.debug(`平台选项数量: ${count}`);
  342. if (count > 0) {
  343. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  344. const optionCount = await platformOption.count();
  345. if (optionCount > 0) {
  346. await platformOption.click();
  347. } else {
  348. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  349. await allOptions.first().click();
  350. }
  351. } else {
  352. console.debug('平台选项列表为空');
  353. }
  354. await orderManagementPage.page.waitForTimeout(200);
  355. } else {
  356. console.debug('平台选择器未找到,跳过平台选择');
  357. }
  358. // 选择公司
  359. const companyTrigger = orderManagementPage.page.locator('[data-testid="company-selector-create"]');
  360. if (await companyTrigger.count() > 0) {
  361. await companyTrigger.click();
  362. await orderManagementPage.page.waitForTimeout(800);
  363. const allCompanyOptions = orderManagementPage.page.getByRole('option');
  364. const companyCount = await allCompanyOptions.count();
  365. console.debug(`公司选项数量: ${companyCount}`);
  366. if (companyCount > 0) {
  367. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  368. const optionCount = await companyOption.count();
  369. if (optionCount > 0) {
  370. await companyOption.click();
  371. } else {
  372. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  373. await allCompanyOptions.first().click();
  374. }
  375. } else {
  376. console.debug('公司选项列表为空');
  377. }
  378. await orderManagementPage.page.waitForTimeout(200);
  379. } else {
  380. console.debug('公司选择器未找到,跳过公司选择');
  381. }
  382. await orderManagementPage.page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  383. const hasPerson = await selectDisabledPersonInAddDialog(orderManagementPage.page, createdPersonName);
  384. if (!hasPerson) {
  385. await orderManagementPage.cancelDialog();
  386. test.skip(true, '没有可用的残疾人数据');
  387. return;
  388. }
  389. // 等待残疾人选择对话框关闭,检查是否显示了已选人员
  390. await orderManagementPage.page.waitForTimeout(1000);
  391. const selectedPersonsBadges = orderManagementPage.page.locator('[class*="badge"]').filter({ hasText: createdPersonName });
  392. const badgeCount = await selectedPersonsBadges.count();
  393. console.debug('已选人员徽章数量:', badgeCount);
  394. // 检查提交按钮是否存在且可点击
  395. const submitButton = orderManagementPage.page.getByRole('button', { name: /^(创建|更新|保存)$/ });
  396. const submitButtonCount = await submitButton.count();
  397. console.debug('提交按钮数量:', submitButtonCount);
  398. if (submitButtonCount === 0) {
  399. console.debug('提交按钮未找到,尝试查找所有按钮');
  400. const allButtons = orderManagementPage.page.locator('button').all();
  401. console.debug('页面按钮总数:', await orderManagementPage.page.locator('button').count());
  402. }
  403. await orderManagementPage.submitForm();
  404. await orderManagementPage.waitForDialogClosed();
  405. // 检查是否有错误或成功 Toast
  406. await orderManagementPage.page.waitForTimeout(1000);
  407. const errorToast = orderManagementPage.page.locator('[data-sonner-toast][data-type="error"]');
  408. const successToast = orderManagementPage.page.locator('[data-sonner-toast][data-type="success"]');
  409. const hasError = await errorToast.count() > 0;
  410. const hasSuccess = await successToast.count() > 0;
  411. if (hasError) {
  412. const errorMsg = await errorToast.textContent();
  413. console.debug('表单提交错误:', errorMsg);
  414. test.skip(true, '订单创建失败: ' + errorMsg);
  415. return;
  416. }
  417. if (!hasSuccess) {
  418. console.debug('没有成功 Toast,订单可能未创建');
  419. } else {
  420. const successMsg = await successToast.textContent();
  421. console.debug('订单创建成功:', successMsg);
  422. }
  423. // 等待订单行出现在表格中
  424. const orderFound = await waitForOrderRow(orderManagementPage.page, testData.orderName);
  425. if (!orderFound) {
  426. test.skip(true, '订单未创建成功,无法继续测试');
  427. return;
  428. }
  429. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  430. const dialog = orderManagementPage.page.locator('[role="dialog"]');
  431. await expect(dialog).toBeVisible();
  432. await orderManagementPage.closeDetailDialog();
  433. });
  434. test('应该能添加残疾人到订单', async ({ orderManagementPage, page }) => {
  435. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  436. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  437. return;
  438. }
  439. const testData = generateUniqueTestData();
  440. await orderManagementPage.openCreateDialog();
  441. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  442. // 选择平台
  443. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  444. if (await platformTrigger.count() > 0) {
  445. await platformTrigger.click();
  446. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  447. await page.waitForTimeout(800);
  448. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  449. const allOptions = page.getByRole('option');
  450. const count = await allOptions.count();
  451. console.debug(`平台选项数量: ${count}`);
  452. if (count > 0) {
  453. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  454. const optionCount = await platformOption.count();
  455. if (optionCount > 0) {
  456. await platformOption.click();
  457. } else {
  458. // 如果找不到特定平台,选择第一个可用的
  459. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  460. await allOptions.first().click();
  461. }
  462. } else {
  463. console.debug('平台选项列表为空');
  464. }
  465. await page.waitForTimeout(200);
  466. } else {
  467. console.debug('平台选择器未找到,跳过平台选择');
  468. }
  469. // 选择公司
  470. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  471. if (await companyTrigger.count() > 0) {
  472. await companyTrigger.click();
  473. await page.waitForTimeout(800);
  474. const allCompanyOptions = page.getByRole('option');
  475. const companyCount = await allCompanyOptions.count();
  476. console.debug(`公司选项数量: ${companyCount}`);
  477. if (companyCount > 0) {
  478. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  479. const optionCount = await companyOption.count();
  480. if (optionCount > 0) {
  481. await companyOption.click();
  482. } else {
  483. // 如果找不到特定公司,选择第一个可用的
  484. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  485. await allCompanyOptions.first().click();
  486. }
  487. } else {
  488. console.debug('公司选项列表为空');
  489. }
  490. await page.waitForTimeout(200);
  491. } else {
  492. console.debug('公司选择器未找到,跳过公司选择');
  493. }
  494. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  495. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  496. if (!hasPerson) {
  497. await orderManagementPage.cancelDialog();
  498. test.skip(true, '没有可用的残疾人数据');
  499. return;
  500. }
  501. await orderManagementPage.submitForm();
  502. await orderManagementPage.waitForDialogClosed();
  503. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  504. const addButton = page.getByRole('button', { name: /添加人员|新增人员/ });
  505. await addButton.click();
  506. await page.waitForTimeout(300);
  507. const hasPersonToAdd = await selectDisabledPersonInAddDialog(page, createdPersonName);
  508. if (!hasPersonToAdd) {
  509. await page.keyboard.press('Escape');
  510. await orderManagementPage.closeDetailDialog();
  511. test.skip(true, '没有可用的残疾人数据');
  512. return;
  513. }
  514. await page.getByLabel(/入职日期/).fill(testData.hireDate);
  515. await page.getByLabel(/薪资|工资/).fill(String(testData.salary));
  516. const submitButton = page.getByRole('button', { name: /^(添加|确定|保存)$/ });
  517. await submitButton.click();
  518. await page.waitForLoadState('domcontentloaded')
  519. .catch(() => console.debug('domcontentloaded 超时,继续检查 Toast 消息'));
  520. await page.waitForTimeout(1000);
  521. const successToast = page.locator('[data-sonner-toast][data-type="success"]');
  522. const hasSuccess = await successToast.count() > 0;
  523. expect(hasSuccess).toBe(true);
  524. await orderManagementPage.closeDetailDialog();
  525. });
  526. test('添加的人员应该出现在订单详情中', async ({ orderManagementPage, page }) => {
  527. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  528. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  529. return;
  530. }
  531. const testData = generateUniqueTestData();
  532. await orderManagementPage.openCreateDialog();
  533. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  534. // 选择平台
  535. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  536. if (await platformTrigger.count() > 0) {
  537. await platformTrigger.click();
  538. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  539. await page.waitForTimeout(800);
  540. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  541. const allOptions = page.getByRole('option');
  542. const count = await allOptions.count();
  543. console.debug(`平台选项数量: ${count}`);
  544. if (count > 0) {
  545. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  546. const optionCount = await platformOption.count();
  547. if (optionCount > 0) {
  548. await platformOption.click();
  549. } else {
  550. // 如果找不到特定平台,选择第一个可用的
  551. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  552. await allOptions.first().click();
  553. }
  554. } else {
  555. console.debug('平台选项列表为空');
  556. }
  557. await page.waitForTimeout(200);
  558. } else {
  559. console.debug('平台选择器未找到,跳过平台选择');
  560. }
  561. // 选择公司
  562. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  563. if (await companyTrigger.count() > 0) {
  564. await companyTrigger.click();
  565. await page.waitForTimeout(800);
  566. const allCompanyOptions = page.getByRole('option');
  567. const companyCount = await allCompanyOptions.count();
  568. console.debug(`公司选项数量: ${companyCount}`);
  569. if (companyCount > 0) {
  570. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  571. const optionCount = await companyOption.count();
  572. if (optionCount > 0) {
  573. await companyOption.click();
  574. } else {
  575. // 如果找不到特定公司,选择第一个可用的
  576. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  577. await allCompanyOptions.first().click();
  578. }
  579. } else {
  580. console.debug('公司选项列表为空');
  581. }
  582. await page.waitForTimeout(200);
  583. } else {
  584. console.debug('公司选择器未找到,跳过公司选择');
  585. }
  586. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  587. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  588. if (!hasPerson) {
  589. await orderManagementPage.cancelDialog();
  590. test.skip(true, '没有可用的残疾人数据');
  591. return;
  592. }
  593. await orderManagementPage.submitForm();
  594. await orderManagementPage.waitForDialogClosed();
  595. await orderManagementPage.openDetailDialog(testData.orderName);
  596. const personList = await orderManagementPage.getPersonListFromDetail();
  597. expect(personList.length).toBeGreaterThan(0);
  598. await orderManagementPage.closeDetailDialog();
  599. });
  600. });
  601. test.describe('管理工作状态', () => {
  602. test('应该能修改人员工作状态:未就业 → 待就业', async ({ orderManagementPage, page }) => {
  603. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  604. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  605. return;
  606. }
  607. const testData = generateUniqueTestData();
  608. await orderManagementPage.openCreateDialog();
  609. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  610. // 选择平台
  611. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  612. if (await platformTrigger.count() > 0) {
  613. await platformTrigger.click();
  614. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  615. await page.waitForTimeout(800);
  616. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  617. const allOptions = page.getByRole('option');
  618. const count = await allOptions.count();
  619. console.debug(`平台选项数量: ${count}`);
  620. if (count > 0) {
  621. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  622. const optionCount = await platformOption.count();
  623. if (optionCount > 0) {
  624. await platformOption.click();
  625. } else {
  626. // 如果找不到特定平台,选择第一个可用的
  627. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  628. await allOptions.first().click();
  629. }
  630. } else {
  631. console.debug('平台选项列表为空');
  632. }
  633. await page.waitForTimeout(200);
  634. } else {
  635. console.debug('平台选择器未找到,跳过平台选择');
  636. }
  637. // 选择公司
  638. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  639. if (await companyTrigger.count() > 0) {
  640. await companyTrigger.click();
  641. await page.waitForTimeout(800);
  642. const allCompanyOptions = page.getByRole('option');
  643. const companyCount = await allCompanyOptions.count();
  644. console.debug(`公司选项数量: ${companyCount}`);
  645. if (companyCount > 0) {
  646. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  647. const optionCount = await companyOption.count();
  648. if (optionCount > 0) {
  649. await companyOption.click();
  650. } else {
  651. // 如果找不到特定公司,选择第一个可用的
  652. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  653. await allCompanyOptions.first().click();
  654. }
  655. } else {
  656. console.debug('公司选项列表为空');
  657. }
  658. await page.waitForTimeout(200);
  659. } else {
  660. console.debug('公司选择器未找到,跳过公司选择');
  661. }
  662. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  663. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  664. if (!hasPerson) {
  665. await orderManagementPage.cancelDialog();
  666. test.skip(true, '没有可用的残疾人数据');
  667. return;
  668. }
  669. await orderManagementPage.submitForm();
  670. await orderManagementPage.waitForDialogClosed();
  671. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  672. const initialPersonList = await orderManagementPage.getPersonListFromDetail();
  673. await orderManagementPage.updatePersonWorkStatus(initialPersonList[0].name, 'pending');
  674. const successToast = page.locator('[data-sonner-toast][data-type="success"]');
  675. const hasSuccess = await successToast.count() > 0;
  676. expect(hasSuccess).toBe(true);
  677. await orderManagementPage.closeDetailDialog();
  678. });
  679. test('应该能修改人员工作状态:待就业 → 已就业', async ({ orderManagementPage, page }) => {
  680. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  681. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  682. return;
  683. }
  684. const testData = generateUniqueTestData();
  685. await orderManagementPage.openCreateDialog();
  686. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  687. // 选择平台
  688. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  689. if (await platformTrigger.count() > 0) {
  690. await platformTrigger.click();
  691. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  692. await page.waitForTimeout(800);
  693. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  694. const allOptions = page.getByRole('option');
  695. const count = await allOptions.count();
  696. console.debug(`平台选项数量: ${count}`);
  697. if (count > 0) {
  698. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  699. const optionCount = await platformOption.count();
  700. if (optionCount > 0) {
  701. await platformOption.click();
  702. } else {
  703. // 如果找不到特定平台,选择第一个可用的
  704. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  705. await allOptions.first().click();
  706. }
  707. } else {
  708. console.debug('平台选项列表为空');
  709. }
  710. await page.waitForTimeout(200);
  711. } else {
  712. console.debug('平台选择器未找到,跳过平台选择');
  713. }
  714. // 选择公司
  715. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  716. if (await companyTrigger.count() > 0) {
  717. await companyTrigger.click();
  718. await page.waitForTimeout(800);
  719. const allCompanyOptions = page.getByRole('option');
  720. const companyCount = await allCompanyOptions.count();
  721. console.debug(`公司选项数量: ${companyCount}`);
  722. if (companyCount > 0) {
  723. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  724. const optionCount = await companyOption.count();
  725. if (optionCount > 0) {
  726. await companyOption.click();
  727. } else {
  728. // 如果找不到特定公司,选择第一个可用的
  729. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  730. await allCompanyOptions.first().click();
  731. }
  732. } else {
  733. console.debug('公司选项列表为空');
  734. }
  735. await page.waitForTimeout(200);
  736. } else {
  737. console.debug('公司选择器未找到,跳过公司选择');
  738. }
  739. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  740. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  741. if (!hasPerson) {
  742. await orderManagementPage.cancelDialog();
  743. test.skip(true, '没有可用的残疾人数据');
  744. return;
  745. }
  746. await orderManagementPage.submitForm();
  747. await orderManagementPage.waitForDialogClosed();
  748. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  749. const personList = await orderManagementPage.getPersonListFromDetail();
  750. await orderManagementPage.updatePersonWorkStatus(personList[0].name, 'employed');
  751. const successToast = page.locator('[data-sonner-toast][data-type="success"]');
  752. const hasSuccess = await successToast.count() > 0;
  753. expect(hasSuccess).toBe(true);
  754. await orderManagementPage.closeDetailDialog();
  755. });
  756. test('应该能修改人员工作状态:已就业 → 已离职', async ({ orderManagementPage, page }) => {
  757. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  758. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  759. return;
  760. }
  761. const testData = generateUniqueTestData();
  762. await orderManagementPage.openCreateDialog();
  763. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  764. // 选择平台
  765. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  766. if (await platformTrigger.count() > 0) {
  767. await platformTrigger.click();
  768. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  769. await page.waitForTimeout(800);
  770. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  771. const allOptions = page.getByRole('option');
  772. const count = await allOptions.count();
  773. console.debug(`平台选项数量: ${count}`);
  774. if (count > 0) {
  775. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  776. const optionCount = await platformOption.count();
  777. if (optionCount > 0) {
  778. await platformOption.click();
  779. } else {
  780. // 如果找不到特定平台,选择第一个可用的
  781. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  782. await allOptions.first().click();
  783. }
  784. } else {
  785. console.debug('平台选项列表为空');
  786. }
  787. await page.waitForTimeout(200);
  788. } else {
  789. console.debug('平台选择器未找到,跳过平台选择');
  790. }
  791. // 选择公司
  792. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  793. if (await companyTrigger.count() > 0) {
  794. await companyTrigger.click();
  795. await page.waitForTimeout(800);
  796. const allCompanyOptions = page.getByRole('option');
  797. const companyCount = await allCompanyOptions.count();
  798. console.debug(`公司选项数量: ${companyCount}`);
  799. if (companyCount > 0) {
  800. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  801. const optionCount = await companyOption.count();
  802. if (optionCount > 0) {
  803. await companyOption.click();
  804. } else {
  805. // 如果找不到特定公司,选择第一个可用的
  806. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  807. await allCompanyOptions.first().click();
  808. }
  809. } else {
  810. console.debug('公司选项列表为空');
  811. }
  812. await page.waitForTimeout(200);
  813. } else {
  814. console.debug('公司选择器未找到,跳过公司选择');
  815. }
  816. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  817. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  818. if (!hasPerson) {
  819. await orderManagementPage.cancelDialog();
  820. test.skip(true, '没有可用的残疾人数据');
  821. return;
  822. }
  823. await orderManagementPage.submitForm();
  824. await orderManagementPage.waitForDialogClosed();
  825. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  826. const personList = await orderManagementPage.getPersonListFromDetail();
  827. await orderManagementPage.updatePersonWorkStatus(personList[0].name, 'resigned');
  828. const successToast = page.locator('[data-sonner-toast][data-type="success"]');
  829. const hasSuccess = await successToast.count() > 0;
  830. expect(hasSuccess).toBe(true);
  831. await orderManagementPage.closeDetailDialog();
  832. });
  833. });
  834. test.describe('设置实际入职日期', () => {
  835. test('应该能设置人员的实际入职日期', async ({ orderManagementPage, page }) => {
  836. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  837. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  838. return;
  839. }
  840. const testData = generateUniqueTestData();
  841. const actualHireDate = '2025-02-01';
  842. await orderManagementPage.openCreateDialog();
  843. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  844. // 选择平台
  845. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  846. if (await platformTrigger.count() > 0) {
  847. await platformTrigger.click();
  848. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  849. await page.waitForTimeout(800);
  850. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  851. const allOptions = page.getByRole('option');
  852. const count = await allOptions.count();
  853. console.debug(`平台选项数量: ${count}`);
  854. if (count > 0) {
  855. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  856. const optionCount = await platformOption.count();
  857. if (optionCount > 0) {
  858. await platformOption.click();
  859. } else {
  860. // 如果找不到特定平台,选择第一个可用的
  861. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  862. await allOptions.first().click();
  863. }
  864. } else {
  865. console.debug('平台选项列表为空');
  866. }
  867. await page.waitForTimeout(200);
  868. } else {
  869. console.debug('平台选择器未找到,跳过平台选择');
  870. }
  871. // 选择公司
  872. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  873. if (await companyTrigger.count() > 0) {
  874. await companyTrigger.click();
  875. await page.waitForTimeout(800);
  876. const allCompanyOptions = page.getByRole('option');
  877. const companyCount = await allCompanyOptions.count();
  878. console.debug(`公司选项数量: ${companyCount}`);
  879. if (companyCount > 0) {
  880. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  881. const optionCount = await companyOption.count();
  882. if (optionCount > 0) {
  883. await companyOption.click();
  884. } else {
  885. // 如果找不到特定公司,选择第一个可用的
  886. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  887. await allCompanyOptions.first().click();
  888. }
  889. } else {
  890. console.debug('公司选项列表为空');
  891. }
  892. await page.waitForTimeout(200);
  893. } else {
  894. console.debug('公司选择器未找到,跳过公司选择');
  895. }
  896. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  897. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  898. if (!hasPerson) {
  899. await orderManagementPage.cancelDialog();
  900. test.skip(true, '没有可用的残疾人数据');
  901. return;
  902. }
  903. await orderManagementPage.submitForm();
  904. await orderManagementPage.waitForDialogClosed();
  905. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  906. const personList = await orderManagementPage.getPersonListFromDetail();
  907. const personRow = page.locator('[role="dialog"]').locator('table tbody tr').filter({ hasText: personList[0].name }).first();
  908. const editButton = personRow.getByRole('button', { name: /编辑|修改/ });
  909. await editButton.click();
  910. await page.waitForTimeout(300);
  911. const actualHireDateInput = page.getByLabel(/实际入职日期/);
  912. await actualHireDateInput.fill(actualHireDate);
  913. const submitButton = page.getByRole('button', { name: /^(更新|保存|确定)$/ });
  914. await submitButton.click();
  915. await page.waitForLoadState('domcontentloaded')
  916. .catch(() => console.debug('domcontentloaded 超时,继续检查 Toast 消息'));
  917. await page.waitForTimeout(1000);
  918. const successToast = page.locator('[data-sonner-toast][data-type="success"]');
  919. const hasSuccess = await successToast.count() > 0;
  920. expect(hasSuccess).toBe(true);
  921. await orderManagementPage.closeDetailDialog();
  922. });
  923. });
  924. test.describe('人员离职', () => {
  925. test('应该能设置人员为已离职状态并设置离职日期', async ({ orderManagementPage, page }) => {
  926. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  927. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  928. return;
  929. }
  930. const testData = generateUniqueTestData();
  931. const resignDate = '2025-03-15';
  932. await orderManagementPage.openCreateDialog();
  933. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  934. // 选择平台
  935. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  936. if (await platformTrigger.count() > 0) {
  937. await platformTrigger.click();
  938. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  939. await page.waitForTimeout(800);
  940. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  941. const allOptions = page.getByRole('option');
  942. const count = await allOptions.count();
  943. console.debug(`平台选项数量: ${count}`);
  944. if (count > 0) {
  945. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  946. const optionCount = await platformOption.count();
  947. if (optionCount > 0) {
  948. await platformOption.click();
  949. } else {
  950. // 如果找不到特定平台,选择第一个可用的
  951. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  952. await allOptions.first().click();
  953. }
  954. } else {
  955. console.debug('平台选项列表为空');
  956. }
  957. await page.waitForTimeout(200);
  958. } else {
  959. console.debug('平台选择器未找到,跳过平台选择');
  960. }
  961. // 选择公司
  962. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  963. if (await companyTrigger.count() > 0) {
  964. await companyTrigger.click();
  965. await page.waitForTimeout(800);
  966. const allCompanyOptions = page.getByRole('option');
  967. const companyCount = await allCompanyOptions.count();
  968. console.debug(`公司选项数量: ${companyCount}`);
  969. if (companyCount > 0) {
  970. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  971. const optionCount = await companyOption.count();
  972. if (optionCount > 0) {
  973. await companyOption.click();
  974. } else {
  975. // 如果找不到特定公司,选择第一个可用的
  976. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  977. await allCompanyOptions.first().click();
  978. }
  979. } else {
  980. console.debug('公司选项列表为空');
  981. }
  982. await page.waitForTimeout(200);
  983. } else {
  984. console.debug('公司选择器未找到,跳过公司选择');
  985. }
  986. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  987. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  988. if (!hasPerson) {
  989. await orderManagementPage.cancelDialog();
  990. test.skip(true, '没有可用的残疾人数据');
  991. return;
  992. }
  993. await orderManagementPage.submitForm();
  994. await orderManagementPage.waitForDialogClosed();
  995. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  996. const personList = await orderManagementPage.getPersonListFromDetail();
  997. const personRow = page.locator('[role="dialog"]').locator('table tbody tr').filter({ hasText: personList[0].name }).first();
  998. const editButton = personRow.getByRole('button', { name: /编辑|修改/ });
  999. await editButton.click();
  1000. await page.waitForTimeout(300);
  1001. await page.getByLabel(/工作状态/).click();
  1002. await page.getByRole('option', { name: '已离职' }).click();
  1003. const resignDateInput = page.getByLabel(/离职日期/);
  1004. await resignDateInput.fill(resignDate);
  1005. const submitButton = page.getByRole('button', { name: /^(更新|保存|确定)$/ });
  1006. await submitButton.click();
  1007. await page.waitForLoadState('domcontentloaded')
  1008. .catch(() => console.debug('domcontentloaded 超时,继续检查 Toast 消息'));
  1009. await page.waitForTimeout(1000);
  1010. const successToast = page.locator('[data-sonner-toast][data-type="success"]');
  1011. const hasSuccess = await successToast.count() > 0;
  1012. expect(hasSuccess).toBe(true);
  1013. await orderManagementPage.closeDetailDialog();
  1014. });
  1015. test('离职后人员状态应显示为已离职', async ({ orderManagementPage, page }) => {
  1016. if (!createdPersonName || !createdPlatformName || !createdCompanyName) {
  1017. test.skip(true, '缺少测试数据(残疾人、平台或公司)');
  1018. return;
  1019. }
  1020. const testData = generateUniqueTestData();
  1021. await orderManagementPage.openCreateDialog();
  1022. await page.getByLabel(/订单名称|名称/).fill(testData.orderName);
  1023. // 选择平台
  1024. const platformTrigger = page.locator('[data-testid="platform-selector-create"]');
  1025. if (await platformTrigger.count() > 0) {
  1026. await platformTrigger.click();
  1027. // 等待选项列表加载,可能需要时间因为新创建的数据需要刷新
  1028. await page.waitForTimeout(800);
  1029. // 使用更宽松的选择方式 - 先查找所有选项,再筛选
  1030. const allOptions = page.getByRole('option');
  1031. const count = await allOptions.count();
  1032. console.debug(`平台选项数量: ${count}`);
  1033. if (count > 0) {
  1034. const platformOption = allOptions.filter({ hasText: createdPlatformName }).first();
  1035. const optionCount = await platformOption.count();
  1036. if (optionCount > 0) {
  1037. await platformOption.click();
  1038. } else {
  1039. // 如果找不到特定平台,选择第一个可用的
  1040. console.debug(`未找到平台 ${createdPlatformName},选择第一个可用平台`);
  1041. await allOptions.first().click();
  1042. }
  1043. } else {
  1044. console.debug('平台选项列表为空');
  1045. }
  1046. await page.waitForTimeout(200);
  1047. } else {
  1048. console.debug('平台选择器未找到,跳过平台选择');
  1049. }
  1050. // 选择公司
  1051. const companyTrigger = page.locator('[data-testid="company-selector-create"]');
  1052. if (await companyTrigger.count() > 0) {
  1053. await companyTrigger.click();
  1054. await page.waitForTimeout(800);
  1055. const allCompanyOptions = page.getByRole('option');
  1056. const companyCount = await allCompanyOptions.count();
  1057. console.debug(`公司选项数量: ${companyCount}`);
  1058. if (companyCount > 0) {
  1059. const companyOption = allCompanyOptions.filter({ hasText: createdCompanyName }).first();
  1060. const optionCount = await companyOption.count();
  1061. if (optionCount > 0) {
  1062. await companyOption.click();
  1063. } else {
  1064. // 如果找不到特定公司,选择第一个可用的
  1065. console.debug(`未找到公司 ${createdCompanyName},选择第一个可用公司`);
  1066. await allCompanyOptions.first().click();
  1067. }
  1068. } else {
  1069. console.debug('公司选项列表为空');
  1070. }
  1071. await page.waitForTimeout(200);
  1072. } else {
  1073. console.debug('公司选择器未找到,跳过公司选择');
  1074. }
  1075. await page.getByLabel(/预计开始日期|开始日期/).fill('2025-01-15');
  1076. const hasPerson = await selectDisabledPersonInAddDialog(page, createdPersonName);
  1077. if (!hasPerson) {
  1078. await orderManagementPage.cancelDialog();
  1079. test.skip(true, '没有可用的残疾人数据');
  1080. return;
  1081. }
  1082. await orderManagementPage.submitForm();
  1083. await orderManagementPage.waitForDialogClosed();
  1084. await orderManagementPage.openPersonManagementDialog(testData.orderName);
  1085. const personList = await orderManagementPage.getPersonListFromDetail();
  1086. const personRow = page.locator('[role="dialog"]').locator('table tbody tr').filter({ hasText: personList[0].name }).first();
  1087. const editButton = personRow.getByRole('button', { name: /编辑|修改/ });
  1088. await editButton.click();
  1089. await page.waitForTimeout(300);
  1090. await page.getByLabel(/工作状态/).click();
  1091. await page.getByRole('option', { name: '已离职' }).click();
  1092. const submitButton = page.getByRole('button', { name: /^(更新|保存|确定)$/ });
  1093. await submitButton.click();
  1094. await page.waitForLoadState('domcontentloaded')
  1095. .catch(() => console.debug('domcontentloaded 超时,继续检查 Toast 消息'));
  1096. await page.waitForTimeout(1000);
  1097. const updatedPersonList = await orderManagementPage.getPersonListFromDetail();
  1098. const resignedPerson = updatedPersonList.find(p => p.name === personList[0].name);
  1099. expect(resignedPerson).toBeDefined();
  1100. expect(resignedPerson?.workStatus).toBe('已离职');
  1101. await orderManagementPage.closeDetailDialog();
  1102. });
  1103. });
  1104. });