test: 14 个 Bug 自动 Playwright 测试用例 + 测试生成器
- bug-{id}.spec.ts: 按 Bug 标题推断模块/路由/检查项
- generate-bug-test.sh: CLI 工具,按需生成测试用例
- test-generator.ts: TypeScript 版生成器
- 每个 Bug 有独立的 @bug{id} @regression 标签
This commit is contained in:
47
openhis-ui-vue3/tests/e2e/specs/bug-466.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-467.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-610.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-611.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-613.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-614.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-615.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-616.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-625.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-626.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-627.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-628.spec.ts
Normal file
47
openhis-ui-vue3/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
openhis-ui-vue3/tests/e2e/specs/bug-629.spec.ts
Normal file
47
openhis-ui-vue3/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([]);
|
||||
});
|
||||
});
|
||||
47
openhis-ui-vue3/tests/e2e/specs/bug-630.spec.ts
Normal file
47
openhis-ui-vue3/tests/e2e/specs/bug-630.spec.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
|
||||
/**
|
||||
* Bug #630: Bug #630 待确认标题
|
||||
* 自动生成: 2026-06-01 09:36:18
|
||||
*/
|
||||
test.describe('🐛 Bug#630', () => {
|
||||
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('#630 Bug #630 待确认标题 @bug630 @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-630-result.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// 无 JS 错误
|
||||
expect(jsErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
98
openhis-ui-vue3/tests/e2e/utils/generate-bug-test.sh
Executable file
98
openhis-ui-vue3/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}"
|
||||
191
openhis-ui-vue3/tests/e2e/utils/test-generator.ts
Normal file
191
openhis-ui-vue3/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