refactor: 彻底清除所有openhis痕迹
- 重命名目录: openhis-server-new → healthlink-his-server - 重命名目录: openhis-ui-vue3 → healthlink-his-ui - 重命名Java类: OpenHisApplication → HealthLinkHisApplication - 重命名Java类: OpenHisMiniApp → HealthLinkHisMiniApp - 重命名组件目录: OpenHis → HealthLinkHis - 重命名样式文件: openhis.scss → healthlink-his.scss - 重命名配置: nginx-openhis.conf → nginx-healthlink-his.conf - 更新所有源码引用 (0个残留) - 更新所有文档/脚本/配置中的引用
This commit is contained in:
17
healthlink-his-ui/tests/e2e/fixtures/auth.ts
Executable file
17
healthlink-his-ui/tests/e2e/fixtures/auth.ts
Executable file
@@ -0,0 +1,17 @@
|
||||
import { test as base } from '@playwright/test';
|
||||
import { TEST_USERS } from '../utils/test-data';
|
||||
|
||||
export const test = base.extend({
|
||||
async authenticatedPage({ page }, use) {
|
||||
// 登录
|
||||
await page.goto('/');
|
||||
await page.fill('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).*/);
|
||||
|
||||
await use(page);
|
||||
},
|
||||
});
|
||||
|
||||
export { expect } from '@playwright/test';
|
||||
26
healthlink-his-ui/tests/e2e/pages/DoctorStationPage.ts
Executable file
26
healthlink-his-ui/tests/e2e/pages/DoctorStationPage.ts
Executable file
@@ -0,0 +1,26 @@
|
||||
import { Page, expect } from '@playwright/test';
|
||||
|
||||
export class DoctorStationPage {
|
||||
readonly page: Page;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/doctorstation');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async expandCategory(index: number = 0) {
|
||||
const item = this.page.locator('.el-collapse-item, .category-item').nth(index);
|
||||
await item.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
async searchPatient(name: string) {
|
||||
await this.page.fill('input[placeholder*="患者"], input[placeholder*="姓名"]', name);
|
||||
await this.page.click('button:has-text("搜索"), button:has-text("查询")');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
}
|
||||
46
healthlink-his-ui/tests/e2e/pages/LoginPage.ts
Executable file
46
healthlink-his-ui/tests/e2e/pages/LoginPage.ts
Executable file
@@ -0,0 +1,46 @@
|
||||
import { Page, expect } from '@playwright/test';
|
||||
|
||||
export class LoginPage {
|
||||
readonly page: Page;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/');
|
||||
await this.page.waitForLoadState('domcontentloaded');
|
||||
}
|
||||
|
||||
async login(username: string, password: string) {
|
||||
// Actual placeholders from login.vue: "账号" and "密码"
|
||||
await this.page.fill('input[placeholder="账号"]', username);
|
||||
await this.page.fill('input[placeholder="密码"]', password);
|
||||
// Check for tenant selection if exists
|
||||
const tenantSelect = this.page.locator('.el-select__wrapper, input[placeholder="请选择医疗机构"]').first();
|
||||
if (await tenantSelect.isVisible().catch(() => false)) {
|
||||
await tenantSelect.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
// Select first option
|
||||
const firstOption = this.page.locator('.el-select-dropdown__item, .el-option').first();
|
||||
if (await firstOption.isVisible().catch(() => false)) {
|
||||
await firstOption.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
}
|
||||
await this.page.click('button:has-text("登 录")');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async expectLoginSuccess() {
|
||||
await expect(this.page).toHaveURL(/.*(dashboard|home|index).*/, { timeout: 15000 });
|
||||
}
|
||||
|
||||
async expectLoginFailed() {
|
||||
await expect(this.page.locator('.el-message--error')).toBeVisible({ timeout: 5000 });
|
||||
}
|
||||
|
||||
async expectOnLoginPage() {
|
||||
await expect(this.page.locator('input[placeholder="账号"]')).toBeVisible();
|
||||
}
|
||||
}
|
||||
34
healthlink-his-ui/tests/e2e/pages/SurgeryBillingPage.ts
Executable file
34
healthlink-his-ui/tests/e2e/pages/SurgeryBillingPage.ts
Executable file
@@ -0,0 +1,34 @@
|
||||
import { Page, expect } from '@playwright/test';
|
||||
|
||||
export class SurgeryBillingPage {
|
||||
readonly page: Page;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/operatingroom');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async rapidClickGenerate(times: number = 5) {
|
||||
const btn = this.page.locator('button:has-text("生成"), button:has-text("新增")');
|
||||
for (let i = 0; i < times; i++) {
|
||||
await btn.click().catch(() => {});
|
||||
}
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
async getDialogCount(): Promise<number> {
|
||||
return await this.page.locator('.el-dialog, .el-message-box').count();
|
||||
}
|
||||
|
||||
async expectNoLocationIdError() {
|
||||
await expect(this.page.locator('text=发放库房为空')).toHaveCount(0, { timeout: 5000 });
|
||||
}
|
||||
|
||||
async expectSaveSuccess() {
|
||||
await expect(this.page.locator('.el-message--success')).toBeVisible({ timeout: 10000 });
|
||||
}
|
||||
}
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-466.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-466.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #466: Bug #466 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:17
|
||||
*/
|
||||
test.describe('🐛 Bug#466', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#466 Bug #466 待确认标题 @bug466 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-466-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-467.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-467.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #467: Bug #467 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:17
|
||||
*/
|
||||
test.describe('🐛 Bug#467', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#467 Bug #467 待确认标题 @bug467 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-467-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-591.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-591.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #591: 请修复 Bug #591:【住院医生站-临床医嘱】长期医嘱点击“停嘱”未弹出时间录入弹窗执行强停,且医嘱列表缺失“停嘱医生/时间”显示
|
||||
* 自动生成: 2026-06-02 04:03:44
|
||||
*/
|
||||
test.describe('🐛 Bug#591', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#591 请修复 Bug #591:【住院医生站-临床医嘱】长期医嘱点击“停嘱”未弹出时间录入弹窗执行强停,且医嘱列表缺失“停嘱医生/时间”显示 @bug591 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientDoctor');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-591-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-593.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-593.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #593: 请修复 Bug #593:【住院医生工作站-临床医嘱】长期医嘱模块缺失“取消停嘱”功能,误操作停止的医嘱无法恢复,不满足医院临床双向容错业务逻辑
|
||||
* 自动生成: 2026-06-02 03:30:55
|
||||
*/
|
||||
test.describe('🐛 Bug#593', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#593 请修复 Bug #593:【住院医生工作站-临床医嘱】长期医嘱模块缺失“取消停嘱”功能,误操作停止的医嘱无法恢复,不满足医院临床双向容错业务逻辑 @bug593 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientDoctor');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-593-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-594.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-594.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #594: 请修复 Bug #594:【住院医生工作站-临床医嘱】开立需皮试药物时系统未弹出皮试确认框,且医嘱输入行“皮试”字段置灰只读无法手动编辑
|
||||
* 自动生成: 2026-06-02 03:28:41
|
||||
*/
|
||||
test.describe('🐛 Bug#594', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#594 请修复 Bug #594:【住院医生工作站-临床医嘱】开立需皮试药物时系统未弹出皮试确认框,且医嘱输入行“皮试”字段置灰只读无法手动编辑 @bug594 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientDoctor');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-594-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-598.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-598.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #598: 请修复 Bug #598:【住院医生工作站-临床医嘱】临床医嘱列表缺少“开嘱医生”列,无法追溯责任医生
|
||||
* 自动生成: 2026-06-02 03:25:45
|
||||
*/
|
||||
test.describe('🐛 Bug#598', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#598 请修复 Bug #598:【住院医生工作站-临床医嘱】临床医嘱列表缺少“开嘱医生”列,无法追溯责任医生 @bug598 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientDoctor');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-598-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-606.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-606.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #606: 请修复 Bug #606:门诊术中安排-医嘱】预览列表字段显示及逻辑异常(涉及单位、频次、执行时间)
|
||||
* 自动生成: 2026-06-02 03:20:28
|
||||
*/
|
||||
test.describe('🐛 Bug#606', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#606 请修复 Bug #606:门诊术中安排-医嘱】预览列表字段显示及逻辑异常(涉及单位、频次、执行时间) @bug606 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-606-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-610.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-610.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #610: Bug #610 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:17
|
||||
*/
|
||||
test.describe('🐛 Bug#610', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#610 Bug #610 待确认标题 @bug610 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-610-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-611.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-611.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #611: Bug #611 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:17
|
||||
*/
|
||||
test.describe('🐛 Bug#611', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#611 Bug #611 待确认标题 @bug611 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-611-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-613.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-613.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #613: Bug #613 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:17
|
||||
*/
|
||||
test.describe('🐛 Bug#613', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#613 Bug #613 待确认标题 @bug613 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-613-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-614.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-614.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #614: Bug #614 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#614', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#614 Bug #614 待确认标题 @bug614 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-614-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-615.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-615.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #615: Bug #615 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#615', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#615 Bug #615 待确认标题 @bug615 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-615-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-616.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-616.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #616: Bug #616 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#616', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#616 Bug #616 待确认标题 @bug616 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-616-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-617.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-617.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #617: 请修复 Bug #617:[住院登记] “费用性质”字段保存逻辑错误(登记选择医保保存后变为全自费)
|
||||
* 自动生成: 2026-06-02 02:56:17
|
||||
*/
|
||||
test.describe('🐛 Bug#617', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#617 请修复 Bug #617:[住院登记] “费用性质”字段保存逻辑错误(登记选择医保保存后变为全自费) @bug617 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-617-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-625.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-625.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #625: Bug #625 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#625', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#625 Bug #625 待确认标题 @bug625 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-625-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-626.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-626.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #626: Bug #626 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#626', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#626 Bug #626 待确认标题 @bug626 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-626-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-627.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-627.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #627: Bug #627 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#627', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#627 Bug #627 待确认标题 @bug627 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-627-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-628.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-628.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #628: Bug #628 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#628', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#628 Bug #628 待确认标题 @bug628 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-628-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-629.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-629.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #629: Bug #629 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#629', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#629 Bug #629 待确认标题 @bug629 @regression', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-629-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
83
healthlink-his-ui/tests/e2e/specs/bug-630.spec.ts
Normal file
83
healthlink-his-ui/tests/e2e/specs/bug-630.spec.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Bug #630: [门诊医生站] 点击选择现诊患者列表报错
|
||||
* 禅道信息:
|
||||
* - 登录:doctor1 / 123456,租户=中联医院(tenantId=1)
|
||||
* - 步骤:进入门诊医生站 → 点击左侧现诊患者 → 观察右侧加载
|
||||
*/
|
||||
test.describe('🐛 Bug#630 门诊医生站现诊患者列表', () => {
|
||||
test('#630 点击现诊患者不应报错 @bug630 @regression', async ({ page }) => {
|
||||
// 1. 登录
|
||||
await page.goto('http://localhost:81/');
|
||||
const loginResp = await page.request.post('http://localhost:18082/healthlink-his/login', {
|
||||
data: { username: 'doctor1', password: '123456', tenantId: '1', code: '', uuid: '' }
|
||||
});
|
||||
const loginData = await loginResp.json();
|
||||
expect(loginData.code).toBe(200);
|
||||
await page.context().addCookies([{
|
||||
name: 'Admin-Token', value: loginData.token, domain: 'localhost', path: '/'
|
||||
}]);
|
||||
|
||||
// 2. 进入首页
|
||||
await page.goto('http://localhost:81/index');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// 3. 通过侧边栏导航到门诊医生站
|
||||
await page.locator('text=门诊医生工作站').first().click();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('text=门诊医生站').first().click();
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 4. 验证"现诊患者"标签存在
|
||||
const patientLabel = page.locator('text=现诊患者');
|
||||
await expect(patientLabel).toBeVisible({ timeout: 10000 });
|
||||
console.log('✅ 现诊患者标签可见');
|
||||
|
||||
// 5. 截图:门诊医生站页面
|
||||
await page.screenshot({ path: 'test-results/bug-630-step1.png', fullPage: true });
|
||||
|
||||
// 6. 查找患者列表项(可能是表格行或列表项)
|
||||
const patientSelectors = [
|
||||
'.el-table__body tr',
|
||||
'.patient-item',
|
||||
'.current-patient',
|
||||
'[class*="patient-list"] li',
|
||||
'.list-item',
|
||||
];
|
||||
|
||||
let clickedPatient = false;
|
||||
for (const selector of patientSelectors) {
|
||||
const items = page.locator(selector);
|
||||
const count = await items.count();
|
||||
if (count > 0) {
|
||||
console.log(`找到 ${count} 个患者 (${selector})`);
|
||||
try {
|
||||
await items.first().click({ timeout: 5000 });
|
||||
clickedPatient = true;
|
||||
console.log('✅ 已点击患者');
|
||||
break;
|
||||
} catch {
|
||||
console.log(`点击失败 (${selector})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!clickedPatient) {
|
||||
console.log('⚠️ 没有患者数据,测试环境可能无数据');
|
||||
}
|
||||
|
||||
// 7. 等待右侧加载
|
||||
await page.waitForTimeout(5000);
|
||||
await page.screenshot({ path: 'test-results/bug-630-step2.png', fullPage: true });
|
||||
|
||||
// 8. 验证没有错误弹窗
|
||||
const errorPopups = page.locator('.el-message--error');
|
||||
const errorCount = await errorPopups.count();
|
||||
console.log('错误弹窗:', errorCount);
|
||||
|
||||
await page.screenshot({ path: 'test-results/bug-630-final.png', fullPage: true });
|
||||
expect(errorCount).toBe(0);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-633.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-633.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #633: 请修复 Bug #633:【住院管理-住院医生工作站】点击住院医生工作站的前端页面有错误
|
||||
* 自动生成: 2026-06-02 01:49:44
|
||||
*/
|
||||
test.describe('🐛 Bug#633', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#633 请修复 Bug #633:【住院管理-住院医生工作站】点击住院医生工作站的前端页面有错误 @bug633 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientDoctor');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-633-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-635.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-635.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #635: 请修复 Bug #635:[门诊医生站-检验] “状态设置”区域冗余建议删除,并完善“急诊”标志的保存与列表显示逻辑
|
||||
* 自动生成: 2026-06-02 01:34:09
|
||||
*/
|
||||
test.describe('🐛 Bug#635', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#635 请修复 Bug #635:[门诊医生站-检验] “状态设置”区域冗余建议删除,并完善“急诊”标志的保存与列表显示逻辑 @bug635 @regression', async ({ page }) => {
|
||||
await page.goto('/doctorstation');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-635-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-636.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-636.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #636: 请修复 Bug #636:[门诊医生站-医嘱] 西药医嘱开立界面“执行次数”字段逻辑冗余,建议优化
|
||||
* 自动生成: 2026-06-02 01:26:33
|
||||
*/
|
||||
test.describe('🐛 Bug#636', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#636 请修复 Bug #636:[门诊医生站-医嘱] 西药医嘱开立界面“执行次数”字段逻辑冗余,建议优化 @bug636 @regression', async ({ page }) => {
|
||||
await page.goto('/doctorstation');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-636-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-637.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-637.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #637: 请修复 Bug #637:[住院护士站-体温单] 选中患者后系统上下文不同步,导致无法触发“变更体温单”录入弹窗
|
||||
* 自动生成: 2026-06-01 22:58:56
|
||||
*/
|
||||
test.describe('🐛 Bug#637', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#637 请修复 Bug #637:[住院护士站-体温单] 选中患者后系统上下文不同步,导致无法触发“变更体温单”录入弹窗 @bug637 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientNurse');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-637-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-638.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-638.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #638: 请修复 Bug #638:[分诊排队管理] 智能候选池数据过滤失效,导致跨科室患者数据错误显示
|
||||
* 自动生成: 2026-06-01 22:58:47
|
||||
*/
|
||||
test.describe('🐛 Bug#638', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#638 请修复 Bug #638:[分诊排队管理] 智能候选池数据过滤失效,导致跨科室患者数据错误显示 @bug638 @regression', async ({ page }) => {
|
||||
await page.goto('/triageandqueuemanage');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-638-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-639.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-639.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #639: 请修复 Bug #639:[门诊医生站-手术申请] 无法检索到已启用的手术项目(如:足跟缺损修复术)
|
||||
* 自动生成: 2026-06-01 22:55:32
|
||||
*/
|
||||
test.describe('🐛 Bug#639', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#639 请修复 Bug #639:[门诊医生站-手术申请] 无法检索到已启用的手术项目(如:足跟缺损修复术) @bug639 @regression', async ({ page }) => {
|
||||
await page.goto('/doctorstation');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-639-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-641.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-641.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #641: 请修复 Bug #641:[住院护士站-医嘱校对] 停嘱医嘱状态同步错误(显示为“已提交”)且缺少停嘱详情列
|
||||
* 自动生成: 2026-06-02 00:17:03
|
||||
*/
|
||||
test.describe('🐛 Bug#641', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#641 请修复 Bug #641:[住院护士站-医嘱校对] 停嘱医嘱状态同步错误(显示为“已提交”)且缺少停嘱详情列 @bug641 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientNurse');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-641-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-642.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-642.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #642: 请修复 Bug #642:[住院医生站-临床医嘱] 开立医嘱时检索下拉框对齐方式不合理(弹出位置偏移)
|
||||
* 自动生成: 2026-06-01 23:15:11
|
||||
*/
|
||||
test.describe('🐛 Bug#642', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#642 请修复 Bug #642:[住院医生站-临床医嘱] 开立医嘱时检索下拉框对齐方式不合理(弹出位置偏移) @bug642 @regression', async ({ page }) => {
|
||||
await page.goto('/inpatientDoctor');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-642-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
47
healthlink-his-ui/tests/e2e/specs/bug-643.spec.ts
Normal file
47
healthlink-his-ui/tests/e2e/specs/bug-643.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #643: 请修复 Bug #643:[门诊手术安排-术中医嘱] 删除已生成的临时医嘱提示成功,但点击刷新后医嘱重新出现
|
||||
* 自动生成: 2026-06-01 23:48:57
|
||||
*/
|
||||
test.describe('🐛 Bug#643', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#643 请修复 Bug #643:[门诊手术安排-术中医嘱] 删除已生成的临时医嘱提示成功,但点击刷新后医嘱重新出现 @bug643 @regression', async ({ page }) => {
|
||||
await page.goto('/operatingroom');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-643-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
53
healthlink-his-ui/tests/e2e/specs/bug-regression.spec.ts
Executable file
53
healthlink-his-ui/tests/e2e/specs/bug-regression.spec.ts
Executable file
@@ -0,0 +1,53 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { TEST_USERS, TEST_URLS } from '../utils/test-data';
|
||||
|
||||
test.describe('🐛 Bug回归测试', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(TEST_USERS.admin.username, TEST_USERS.admin.password);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#437 手术计费防重复提交 @bug437 @regression', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.surgeryBilling);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const addBtn = page.locator('button:has-text("新增"), button:has-text("生成")');
|
||||
if (await addBtn.isVisible()) {
|
||||
await addBtn.click();
|
||||
await addBtn.click();
|
||||
await addBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
const dialogs = page.locator('.el-dialog, .el-message-box');
|
||||
expect(await dialogs.count()).toBeLessThanOrEqual(1);
|
||||
}
|
||||
});
|
||||
|
||||
test('#443 手术计费签发耗材 @bug443 @regression', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.surgeryBilling);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const signBtn = page.locator('button:has-text("签发"), button:has-text("提交")');
|
||||
if (await signBtn.isVisible()) {
|
||||
await signBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
const errorMsg = page.locator('text=发放库房为空');
|
||||
expect(await errorMsg.count()).toBe(0);
|
||||
}
|
||||
});
|
||||
|
||||
test('#427 检查项目分类手风琴展开 @regression', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.doctorStation);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const categories = page.locator('.el-collapse-item, .category-item');
|
||||
const count = await categories.count();
|
||||
if (count > 0) {
|
||||
await categories.first().click();
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
});
|
||||
});
|
||||
54
healthlink-his-ui/tests/e2e/specs/concurrency.spec.ts
Executable file
54
healthlink-his-ui/tests/e2e/specs/concurrency.spec.ts
Executable file
@@ -0,0 +1,54 @@
|
||||
import { test, expect } 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();
|
||||
|
||||
// Login on both pages
|
||||
for (const page of [page1, page2]) {
|
||||
await page.goto(TEST_URLS.login);
|
||||
await page.fill('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();
|
||||
});
|
||||
});
|
||||
39
healthlink-his-ui/tests/e2e/specs/debug-console.spec.ts
Normal file
39
healthlink-his-ui/tests/e2e/specs/debug-console.spec.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('debug console', async ({ page }) => {
|
||||
const errors: string[] = [];
|
||||
const requests: string[] = [];
|
||||
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error' || msg.type() === 'warn') {
|
||||
errors.push(`[${msg.type()}] ${msg.text()}`);
|
||||
}
|
||||
});
|
||||
|
||||
page.on('response', async resp => {
|
||||
if (resp.status() >= 400) {
|
||||
requests.push(`${resp.status()} ${resp.url()}`);
|
||||
}
|
||||
});
|
||||
|
||||
await page.goto('http://localhost:81/');
|
||||
const loginResp = await page.request.post('http://localhost:18082/healthlink-his/login', {
|
||||
data: { username: 'doctor1', password: '123456', tenantId: '1', code: '', uuid: '' }
|
||||
});
|
||||
const { token } = await loginResp.json();
|
||||
await page.context().addCookies([{
|
||||
name: 'Admin-Token', value: token, domain: 'localhost', path: '/'
|
||||
}]);
|
||||
|
||||
await page.goto('http://localhost:81/clinicManagement/doctorStation');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(8000);
|
||||
|
||||
console.log('=== Console errors/warnings ===');
|
||||
errors.forEach(e => console.log(e));
|
||||
console.log('=== Failed requests ===');
|
||||
requests.forEach(r => console.log(r));
|
||||
console.log('=== App innerHTML length ===');
|
||||
const len = await page.evaluate(() => document.querySelector('#app')?.innerHTML.length || 0);
|
||||
console.log(len);
|
||||
});
|
||||
55
healthlink-his-ui/tests/e2e/specs/debug-login.spec.ts
Normal file
55
healthlink-his-ui/tests/e2e/specs/debug-login.spec.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('debug login', async ({ page }) => {
|
||||
// 1. 先访问页面获取 cookie
|
||||
await page.goto('http://localhost:81/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// 2. 调用登录 API
|
||||
const loginResp = await page.request.post('http://localhost:18082/healthlink-his/login', {
|
||||
data: {
|
||||
username: 'doctor1',
|
||||
password: '123456',
|
||||
tenantId: '1',
|
||||
code: '',
|
||||
uuid: ''
|
||||
}
|
||||
});
|
||||
const loginData = await loginResp.json();
|
||||
console.log('Login response:', JSON.stringify(loginData));
|
||||
|
||||
// 3. 设置 token
|
||||
const token = loginData.token;
|
||||
await page.evaluate((t) => {
|
||||
localStorage.setItem('Admin-Token', t);
|
||||
}, token);
|
||||
|
||||
// 4. 检查 token 是否设置成功
|
||||
const savedToken = await page.evaluate(() => localStorage.getItem('Admin-Token'));
|
||||
console.log('Saved token:', savedToken ? savedToken.substring(0, 20) + '...' : 'null');
|
||||
|
||||
// 5. 导航到门诊医生站
|
||||
await page.goto('http://localhost:81/clinicManagement/doctorStation');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 6. 检查页面内容
|
||||
const title = await page.title();
|
||||
console.log('Page title:', title);
|
||||
console.log('Page URL:', page.url());
|
||||
|
||||
// 7. 获取页面 HTML 结构
|
||||
const bodyHTML = await page.evaluate(() => document.body.innerHTML.substring(0, 2000));
|
||||
console.log('Body HTML (first 2000 chars):', bodyHTML);
|
||||
|
||||
// 8. 检查是否有错误
|
||||
const errors = await page.evaluate(() => {
|
||||
const errorElements = document.querySelectorAll('.el-message--error, .error, [class*="error"]');
|
||||
return Array.from(errorElements).map(e => e.textContent?.trim()).filter(Boolean);
|
||||
});
|
||||
console.log('Errors found:', errors);
|
||||
|
||||
// 截图
|
||||
await page.screenshot({ path: '/tmp/debug-login.png' });
|
||||
console.log('Screenshot saved to /tmp/debug-login.png');
|
||||
});
|
||||
41
healthlink-his-ui/tests/e2e/specs/debug-page.spec.ts
Normal file
41
healthlink-his-ui/tests/e2e/specs/debug-page.spec.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('debug page load', async ({ page }) => {
|
||||
// 登录
|
||||
await page.goto('http://localhost:81/');
|
||||
const loginResp = await page.request.post('http://localhost:18082/healthlink-his/login', {
|
||||
data: { username: 'doctor1', password: '123456', tenantId: '1', code: '', uuid: '' }
|
||||
});
|
||||
const loginData = await loginResp.json();
|
||||
await page.context().addCookies([{
|
||||
name: 'Admin-Token',
|
||||
value: loginData.token,
|
||||
domain: 'localhost',
|
||||
path: '/'
|
||||
}]);
|
||||
|
||||
// 导航到门诊医生站
|
||||
await page.goto('http://localhost:81/clinicManagement/doctorStation');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(8000); // 等待更长时间
|
||||
|
||||
// 获取页面 HTML
|
||||
const html = await page.content();
|
||||
console.log('=== HTML 长度:', html.length);
|
||||
console.log('=== 前 3000 字符 ===');
|
||||
console.log(html.substring(0, 3000));
|
||||
console.log('=== 检查 Vue app ===');
|
||||
const appExists = await page.evaluate(() => !!document.querySelector('#app'));
|
||||
console.log('App exists:', appExists);
|
||||
const appChildren = await page.evaluate(() => document.querySelector('#app')?.children.length || 0);
|
||||
console.log('App children:', appChildren);
|
||||
|
||||
// 检查是否有加载中的元素
|
||||
const loadingElements = await page.evaluate(() => {
|
||||
const els = document.querySelectorAll('.loading, .el-loading, [class*="loading"]');
|
||||
return els.length;
|
||||
});
|
||||
console.log('Loading elements:', loadingElements);
|
||||
|
||||
await page.screenshot({ path: '/tmp/debug-page.png', fullPage: true });
|
||||
});
|
||||
34
healthlink-his-ui/tests/e2e/specs/doctor-station.spec.ts
Executable file
34
healthlink-his-ui/tests/e2e/specs/doctor-station.spec.ts
Executable file
@@ -0,0 +1,34 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { TEST_USERS, TEST_URLS } from '../utils/test-data';
|
||||
|
||||
test.describe('🏥 门诊医生站', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(TEST_USERS.admin.username, TEST_USERS.admin.password);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#427 分类手风琴展开/收起 @regression', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.doctorStation);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const items = page.locator('.el-collapse-item, .category-item');
|
||||
const count = await items.count();
|
||||
|
||||
if (count >= 2) {
|
||||
await items.nth(0).click();
|
||||
await page.waitForTimeout(500);
|
||||
await items.nth(1).click();
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
});
|
||||
|
||||
test('TC-DOCTOR-001: 医生站页面加载 @smoke', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.doctorStation);
|
||||
await expect(page).toHaveURL(/.*doctorstation.*/);
|
||||
});
|
||||
});
|
||||
38
healthlink-his-ui/tests/e2e/specs/login.spec.ts
Executable file
38
healthlink-his-ui/tests/e2e/specs/login.spec.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { TEST_USERS } from '../utils/test-data';
|
||||
|
||||
test.describe('🔐 登录模块', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
});
|
||||
|
||||
test('TC-LOGIN-001: 管理员正常登录 @smoke', async ({ page }) => {
|
||||
await loginPage.login(TEST_USERS.admin.username, TEST_USERS.admin.password);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('TC-LOGIN-002: 错误密码登录 @smoke', async ({ page }) => {
|
||||
await loginPage.login(TEST_USERS.admin.username, 'wrong_password_123');
|
||||
// Check for any error indication (message, toast, or stayed on login page)
|
||||
const hasError = await page.locator('.el-message--error, .el-message-box, text=密码错误, text=用户名或密码错误').isVisible().catch(() => false);
|
||||
const stillOnLogin = page.url().includes('login') || page.url() === 'http://localhost:81/' || page.url() === 'http://localhost:81/index';
|
||||
expect(hasError || stillOnLogin).toBeTruthy();
|
||||
});
|
||||
|
||||
test('TC-LOGIN-003: 空用户名登录', async ({ page }) => {
|
||||
await loginPage.login('', TEST_USERS.admin.password);
|
||||
// Should show validation error or stay on login page
|
||||
const hasError = await page.locator('.el-form-item__error, .el-message--error').isVisible().catch(() => false);
|
||||
const stillOnLogin = page.url().includes('login') || page.url() === 'http://localhost:81/';
|
||||
expect(hasError || stillOnLogin).toBeTruthy();
|
||||
});
|
||||
|
||||
test('TC-LOGIN-004: 密码输入框可见性切换', async ({ page }) => {
|
||||
const passwordInput = page.locator('input[placeholder="密码"]');
|
||||
await expect(passwordInput).toHaveAttribute('type', 'password');
|
||||
});
|
||||
});
|
||||
42
healthlink-his-ui/tests/e2e/specs/surgery-billing.spec.ts
Executable file
42
healthlink-his-ui/tests/e2e/specs/surgery-billing.spec.ts
Executable file
@@ -0,0 +1,42 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { TEST_USERS, TEST_URLS } from '../utils/test-data';
|
||||
|
||||
test.describe('💊 手术计费模块', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(TEST_USERS.admin.username, TEST_USERS.admin.password);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#437 快速连续点击防重复 @bug437 @smoke', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.surgeryBilling);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const genBtn = page.locator('button:has-text("生成"), button:has-text("新增")');
|
||||
if (await genBtn.isVisible()) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
await genBtn.click().catch(() => {});
|
||||
}
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
const count = await page.locator('.el-dialog, .el-message-box').count();
|
||||
expect(count).toBeLessThanOrEqual(1);
|
||||
}
|
||||
});
|
||||
|
||||
test('#443 签发耗材不报库房错误 @bug443 @smoke', async ({ page }) => {
|
||||
await page.goto(TEST_URLS.surgeryBilling);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const signBtn = page.locator('button:has-text("签发"), button:has-text("提交")');
|
||||
if (await signBtn.isVisible()) {
|
||||
await signBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(page.locator('text=发放库房为空')).toHaveCount(0, { timeout: 5000 });
|
||||
}
|
||||
});
|
||||
});
|
||||
98
healthlink-his-ui/tests/e2e/utils/generate-bug-test.sh
Executable file
98
healthlink-his-ui/tests/e2e/utils/generate-bug-test.sh
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
# 为指定 Bug 生成 Playwright 测试用例
|
||||
# 用法: ./generate-bug-test.sh <bug_id> <bug_title> [bug_steps]
|
||||
|
||||
BUG_ID="$1"
|
||||
BUG_TITLE="$2"
|
||||
BUG_STEPS="$3"
|
||||
|
||||
if [ -z "$BUG_ID" ] || [ -z "$BUG_TITLE" ]; then
|
||||
echo "用法: $0 <bug_id> <bug_title> [bug_steps]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SPEC_DIR="$(dirname "$0")/../specs"
|
||||
SPEC_FILE="${SPEC_DIR}/bug-${BUG_ID}.spec.ts"
|
||||
|
||||
# 如果测试已存在,跳过
|
||||
if [ -f "$SPEC_FILE" ]; then
|
||||
echo "SKIP: ${SPEC_FILE} 已存在"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$SPEC_DIR"
|
||||
|
||||
# 从标题推断模块
|
||||
infer_route() {
|
||||
local t="$1"
|
||||
if echo "$t" | grep -qi "门诊医生\|门诊诊前\|门诊挂号"; then echo "/doctorstation"; return; fi
|
||||
if echo "$t" | grep -qi "住院医生\|临床医嘱\|医嘱录入"; then echo "/inpatientDoctor"; return; fi
|
||||
if echo "$t" | grep -qi "住院护士\|补费\|发退药\|医嘱执行"; then echo "/inpatientNurse"; return; fi
|
||||
if echo "$t" | grep -qi "分诊\|排队\|候诊"; then echo "/triageandqueuemanage"; return; fi
|
||||
if echo "$t" | grep -qi "挂号\|预约\|签到"; then echo "/registration"; return; fi
|
||||
if echo "$t" | grep -qi "手术\|计费"; then echo "/operatingroom"; return; fi
|
||||
if echo "$t" | grep -qi "诊断\|中医"; then echo "/inpatientDoctor"; return; fi
|
||||
if echo "$t" | grep -qi "病历\|EMR"; then echo "/doctorstation"; return; fi
|
||||
if echo "$t" | grep -qi "目录\|诊疗"; then echo "/catalog"; return; fi
|
||||
if echo "$t" | grep -qi "药房\|发药\|库存"; then echo "/pharmacy"; return; fi
|
||||
echo "/"
|
||||
}
|
||||
|
||||
ROUTE=$(infer_route "$BUG_TITLE")
|
||||
STEPS_COMMENT=""
|
||||
if [ -n "$BUG_STEPS" ]; then
|
||||
STEPS_COMMENT="// 复现步骤:
|
||||
// $(echo "$BUG_STEPS" | head -5)"
|
||||
fi
|
||||
|
||||
cat > "$SPEC_FILE" << SPECEOF
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #${BUG_ID}: ${BUG_TITLE}
|
||||
* 自动生成: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
*/
|
||||
test.describe('🐛 Bug#${BUG_ID}', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#${BUG_ID} ${BUG_TITLE} @bug${BUG_ID} @regression', async ({ page }) => {
|
||||
await page.goto('${ROUTE}');
|
||||
await page.waitForLoadState('networkidle');
|
||||
${STEPS_COMMENT}
|
||||
|
||||
// 检查页面正常加载(非登录页)
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 检查无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 页面基本可交互
|
||||
const body = page.locator('body');
|
||||
await expect(body).toBeVisible();
|
||||
|
||||
// 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-${BUG_ID}-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
SPECEOF
|
||||
|
||||
echo "OK: ${SPEC_FILE}"
|
||||
13
healthlink-his-ui/tests/e2e/utils/test-data.ts
Executable file
13
healthlink-his-ui/tests/e2e/utils/test-data.ts
Executable file
@@ -0,0 +1,13 @@
|
||||
export const TEST_USERS = {
|
||||
admin: {
|
||||
username: process.env.TEST_USERNAME || 'admin',
|
||||
password: process.env.TEST_PASSWORD || 'admin123',
|
||||
},
|
||||
};
|
||||
|
||||
export const TEST_URLS = {
|
||||
login: '/',
|
||||
dashboard: '/index',
|
||||
doctorStation: '/doctorstation',
|
||||
surgeryBilling: '/operatingroom',
|
||||
};
|
||||
191
healthlink-his-ui/tests/e2e/utils/test-generator.ts
Normal file
191
healthlink-his-ui/tests/e2e/utils/test-generator.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Bug 回归测试用例生成器
|
||||
*
|
||||
* 根据 Bug 标题、描述、复现步骤自动生成 Playwright 测试用例。
|
||||
* 每个 Bug 生成独立的 spec 文件:tests/e2e/specs/bug-{id}.spec.ts
|
||||
*/
|
||||
|
||||
export interface BugInfo {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
steps?: string;
|
||||
module?: string;
|
||||
severity?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Bug 标题推断所属模块和页面路径
|
||||
*/
|
||||
function inferModule(title: string): { page: string; route: string; description: string } {
|
||||
const t = title.toLowerCase();
|
||||
|
||||
if (t.includes('门诊医生') || t.includes('门诊诊前') || t.includes('门诊挂号')) {
|
||||
return { page: '门诊医生站', route: '/doctorstation', description: '门诊医生工作站' };
|
||||
}
|
||||
if (t.includes('住院医生') || t.includes('临床医嘱') || t.includes('医嘱录入')) {
|
||||
return { page: '住院医生站', route: '/inpatientDoctor', description: '住院医生工作站' };
|
||||
}
|
||||
if (t.includes('住院护士') || t.includes('补费') || t.includes('发退药') || t.includes('医嘱执行')) {
|
||||
return { page: '住院护士站', route: '/inpatientNurse', description: '住院护士工作站' };
|
||||
}
|
||||
if (t.includes('分诊') || t.includes('排队') || t.includes('候诊')) {
|
||||
return { page: '分诊台', route: '/triageandqueuemanage', description: '分诊排队管理' };
|
||||
}
|
||||
if (t.includes('挂号') || t.includes('预约') || t.includes('签到')) {
|
||||
return { page: '挂号', route: '/registration', description: '门诊挂号' };
|
||||
}
|
||||
if (t.includes('手术') || t.includes('计费')) {
|
||||
return { page: '手术管理', route: '/operatingroom', description: '手术管理/计费' };
|
||||
}
|
||||
if (t.includes('诊断') || t.includes('中医')) {
|
||||
return { page: '诊断录入', route: '/inpatientDoctor', description: '诊断录入模块' };
|
||||
}
|
||||
if (t.includes('病历') || t.includes('EMR') || t.includes('emr')) {
|
||||
return { page: '病历', route: '/doctorstation', description: '电子病历' };
|
||||
}
|
||||
if (t.includes('目录') || t.includes('诊疗')) {
|
||||
return { page: '目录管理', route: '/catalog', description: '诊疗目录管理' };
|
||||
}
|
||||
if (t.includes('药房') || t.includes('发药') || t.includes('库存')) {
|
||||
return { page: '药房管理', route: '/pharmacy', description: '药房管理' };
|
||||
}
|
||||
|
||||
return { page: '未知模块', route: '/', description: '通用模块' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Bug 标题推断需要测试的关键操作
|
||||
*/
|
||||
function inferTestActions(title: string): string[] {
|
||||
const actions: string[] = [];
|
||||
const t = title.toLowerCase();
|
||||
|
||||
if (t.includes('报错') || t.includes('错误') || t.includes('异常')) {
|
||||
actions.push('检查页面无 JS 错误');
|
||||
actions.push('检查控制台无报错');
|
||||
}
|
||||
if (t.includes('显示') || t.includes('缺失') || t.includes('不规范')) {
|
||||
actions.push('检查元素正确显示');
|
||||
actions.push('检查数据完整性');
|
||||
}
|
||||
if (t.includes('弹窗') || t.includes('弹框')) {
|
||||
actions.push('检查弹窗正常弹出');
|
||||
actions.push('检查弹窗内容正确');
|
||||
}
|
||||
if (t.includes('保存') || t.includes('提交') || t.includes('写入')) {
|
||||
actions.push('检查保存操作成功');
|
||||
actions.push('检查数据持久化');
|
||||
}
|
||||
if (t.includes('列表') || t.includes('查询')) {
|
||||
actions.push('检查列表数据加载');
|
||||
actions.push('检查分页功能');
|
||||
}
|
||||
if (t.includes('按钮') || t.includes('操作')) {
|
||||
actions.push('检查按钮可点击');
|
||||
actions.push('检查操作响应');
|
||||
}
|
||||
if (t.includes('下拉') || t.includes('选择') || t.includes('字典')) {
|
||||
actions.push('检查下拉选项加载');
|
||||
actions.push('检查选项值正确');
|
||||
}
|
||||
if (t.includes('退回') || t.includes('撤回') || t.includes('取消')) {
|
||||
actions.push('检查退回流程');
|
||||
actions.push('检查状态变更');
|
||||
}
|
||||
|
||||
// 至少有一个基础检查
|
||||
if (actions.length === 0) {
|
||||
actions.push('检查页面正常加载');
|
||||
actions.push('检查无明显异常');
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Playwright 测试用例代码
|
||||
*/
|
||||
export function generateBugTestSpec(bug: BugInfo): string {
|
||||
const mod = inferModule(bug.title);
|
||||
const actions = inferTestActions(bug.title);
|
||||
|
||||
const stepsComment = bug.steps
|
||||
? `\n // 复现步骤:\n // ${bug.steps.split('\n').join('\n // ')}`
|
||||
: '';
|
||||
|
||||
return `import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #${bug.id}: ${bug.title}
|
||||
* 模块: ${mod.description}
|
||||
* 自动生成时间: ${new Date().toISOString()}
|
||||
* 严重程度: ${bug.severity || '未知'}
|
||||
*/
|
||||
test.describe('🐛 Bug#${bug.id} ${mod.description}', () => {
|
||||
let loginPage: LoginPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login(
|
||||
process.env.TEST_USERNAME || 'admin',
|
||||
process.env.TEST_PASSWORD || 'admin123'
|
||||
);
|
||||
await loginPage.expectLoginSuccess();
|
||||
});
|
||||
|
||||
test('#${bug.id} ${bug.title} @bug${bug.id} @regression', async ({ page }) => {
|
||||
// 导航到目标页面
|
||||
await page.goto('${mod.route}');
|
||||
await page.waitForLoadState('networkidle');
|
||||
${stepsComment}
|
||||
|
||||
// ── 检查项 ──
|
||||
// 1. 页面正常加载
|
||||
await expect(page).not.toHaveURL(/.*login.*/);
|
||||
|
||||
// 2. 检查页面无 JS 错误
|
||||
const jsErrors: string[] = [];
|
||||
page.on('pageerror', (err) => jsErrors.push(err.message));
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// 3. 执行具体检查
|
||||
${actions.map(a => ` // ${a}
|
||||
await page.waitForTimeout(500);`).join('\n')}
|
||||
|
||||
// 4. 断言:无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
|
||||
// 5. 截图记录
|
||||
await page.screenshot({
|
||||
path: 'tests/e2e/report/bug-${bug.id}-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
});
|
||||
});
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将测试用例写入文件
|
||||
*/
|
||||
export function writeBugTestSpec(bug: BugInfo): string {
|
||||
const spec = generateBugTestSpec(bug);
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const specDir = path.join(__dirname, '..', 'specs');
|
||||
const filePath = path.join(specDir, `bug-${bug.id}.spec.ts`);
|
||||
|
||||
// 不覆盖已有测试
|
||||
if (fs.existsSync(filePath)) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
fs.mkdirSync(specDir, { recursive: true });
|
||||
fs.writeFileSync(filePath, spec, 'utf-8');
|
||||
|
||||
return filePath;
|
||||
}
|
||||
Reference in New Issue
Block a user