import { test, expect, Browser } from '@playwright/test'; import { TEST_USERS, TEST_URLS } from '../utils/test-data'; test.describe('🔄 并发操作测试', () => { test('#437 多窗口同时操作手术计费 @bug437', async ({ browser }) => { // 打开两个浏览器上下文(模拟多标签页) const context1 = await browser.newContext(); const context2 = await browser.newContext(); const page1 = await context1.newPage(); const page2 = await context2.newPage(); // 两个页面都登录 for (const page of [page1, page2]) { await page.goto(TEST_URLS.login); await page.fill('input[placeholder*="用户名"], input[placeholder*="账号"]', TEST_USERS.admin.username); await page.fill('input[placeholder*="密码"]', TEST_USERS.admin.password); await page.click('button:has-text("登录")'); await page.waitForURL(/.*(dashboard|home|index).*/); } // 两个页面同时访问手术计费 await Promise.all([ page1.goto(TEST_URLS.surgeryBilling), page2.goto(TEST_URLS.surgeryBilling), ]); await Promise.all([ page1.waitForLoadState('networkidle'), page2.waitForLoadState('networkidle'), ]); // 同时在两个页面点击生成 const genBtn1 = page1.locator('button:has-text("生成")'); const genBtn2 = page2.locator('button:has-text("生成")'); if (await genBtn1.isVisible() && await genBtn2.isVisible()) { await Promise.all([ genBtn1.click().catch(() => {}), genBtn2.click().catch(() => {}), ]); await page1.waitForTimeout(3000); // 验证数据一致性:不应出现重复记录 const table1 = page1.locator('el-table__body tr, .el-table__row'); const table2 = page2.locator('el-table__body tr, .el-table__row'); const count1 = await table1.count(); const count2 = await table2.count(); // 两个页面看到的数据应该一致 expect(count1).toBe(count2); } await context1.close(); await context2.close(); }); });