feat: 完善系统配置审计通知功能并优化异常处理

- 新增异常处理体系(BaseException及其子类)
- 优化密码、邮箱、用户名等基础类型
- 添加字典管理、登录日志、操作日志的E2E测试
- 完善API集成测试和安全测试
- 添加性能测试配置和脚本
- 优化OpenAPI配置和全局异常处理器
This commit is contained in:
张翔
2026-03-24 14:05:35 +08:00
parent be5d5ede90
commit e4721053bd
47 changed files with 3006 additions and 816 deletions
+149 -260
View File
@@ -1,306 +1,195 @@
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { DashboardPage } from './pages/DashboardPage';
import { NotificationPage } from './pages/NotificationPage';
test.describe('通知功能 E2E 测试', () => {
test.describe('通知公告E2E测试', () => {
let loginPage: LoginPage;
let dashboardPage: DashboardPage;
let notificationPage: NotificationPage;
let noticePage: NotificationPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
dashboardPage = new DashboardPage(page);
notificationPage = new NotificationPage(page);
noticePage = new NotificationPage(page);
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await expect(page).toHaveURL(/.*dashboard/);
});
test('NOTIFY-001: 管理员查看通知列表', async ({ page }) => {
await test.step('管理员登录', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await expect(page).toHaveURL(/.*dashboard/);
test.afterEach(async ({ page }) => {
await loginPage.logout();
});
test('通知公告页面导航', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
await expect(page).toHaveURL(/.*notice/);
});
await test.step('导航到通知管理页面', async () => {
await page.goto('/notice');
await page.waitForLoadState('networkidle');
});
await test.step('验证通知列表页面加载', async () => {
await expect(notificationPage.table).toBeVisible();
const rowCount = await notificationPage.getTableRowCount();
expect(rowCount).toBeGreaterThanOrEqual(0);
});
await test.step('验证通知表格包含必要列', async () => {
await expect(notificationPage.table).toContainText('通知标题');
await expect(notificationPage.table).toContainText('通知类型');
await expect(notificationPage.table).toContainText('状态');
await expect(notificationPage.table).toContainText('创建时间');
await test.step('验证页面元素可见', async () => {
await expect(noticePage.table).toBeVisible();
await expect(noticePage.addButton).toBeVisible();
await expect(noticePage.searchInput).toBeVisible();
});
});
test('NOTIFY-002: 管理员新增通知', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
test('创建通知公告', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('新增通知', async () => {
const testTitle = `测试通知_${Date.now()}`;
const testContent = `这是一测试通知内容,创建时间:${new Date().toLocaleString()}`;
await test.step('创建新通知公告', async () => {
const title = `测试通知_${Date.now()}`;
const content = `这是一测试通知内容_${Date.now()}`;
await notificationPage.addNotification(testTitle, testContent);
await page.waitForTimeout(1000);
await noticePage.addNotification(title, content);
await expect(notificationPage.table).toBeVisible();
await noticePage.verifyTableContains(title);
});
});
test('NOTIFY-003: 管理员修改通知', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
test('编辑通知公告', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('修改通知', async () => {
const rows = await notificationPage.table.locator('.el-table__row').count();
await test.step('编辑现有通知公告', async () => {
const title = '系统维护通知';
const newContent = `系统将于今晚进行维护,请提前保存工作_${Date.now()}`;
await noticePage.editNotification(title, newContent);
await noticePage.verifyTableContains(title);
});
});
test('删除通知公告', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('删除通知公告', async () => {
const title = `测试通知_${Date.now()}`;
const content = `这是一条测试通知内容_${Date.now()}`;
await noticePage.addNotification(title, content);
await noticePage.verifyTableContains(title);
await noticePage.deleteNotification(title);
await noticePage.verifyTableNotContains(title);
});
});
test('搜索通知公告', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('搜索通知公告', async () => {
const title = '系统维护通知';
await noticePage.searchNotification(title);
await noticePage.verifyTableContains(title);
});
await test.step('清除搜索', async () => {
await noticePage.clearSearch();
const rowCount = await noticePage.getTableRowCount();
expect(rowCount).toBeGreaterThan(0);
});
});
test('通知公告分页功能', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('验证表格数据加载', async () => {
const rowCount = await noticePage.getTableRowCount();
expect(rowCount).toBeGreaterThan(0);
});
});
test('通知公告响应式布局', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('验证桌面端布局', async () => {
await page.setViewportSize({ width: 1280, height: 720 });
await expect(noticePage.table).toBeVisible();
await expect(noticePage.addButton).toBeVisible();
});
await test.step('验证平板端布局', async () => {
await page.setViewportSize({ width: 768, height: 1024 });
await expect(noticePage.table).toBeVisible();
await expect(noticePage.addButton).toBeVisible();
});
await test.step('验证移动端布局', async () => {
await page.setViewportSize({ width: 375, height: 667 });
await expect(noticePage.table).toBeVisible();
});
});
test('通知公告权限验证', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('验证添加按钮可见性', async () => {
await expect(noticePage.addButton).toBeVisible();
});
await test.step('验证编辑和删除按钮可见性', async () => {
const rows = await noticePage.table.locator('.el-table__row').count();
if (rows > 0) {
const firstRow = notificationPage.table.locator('.el-table__row').first();
const title = await firstRow.locator('td').nth(1).textContent();
if (title && title.includes('测试通知')) {
const newContent = `更新后的通知内容,时间:${new Date().toLocaleString()}`;
await notificationPage.editNotification(title, newContent);
await page.waitForTimeout(1000);
await expect(notificationPage.table).toBeVisible();
}
await expect(noticePage.table).toBeVisible();
}
});
});
test('NOTIFY-004: 管理员删除通知', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
test('通知公告状态管理', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('删除通知', async () => {
const testRow = notificationPage.table.locator('tr').filter({ hasText: '测试通知' }).first();
const testRowCount = await testRow.count();
await test.step('创建已发布通知', async () => {
const title = `已发布通知_${Date.now()}`;
const content = `这是一条已发布的通知_${Date.now()}`;
if (testRowCount > 0) {
const title = await testRow.locator('td').nth(1).textContent();
if (title) {
await notificationPage.deleteNotification(title);
await page.waitForTimeout(1000);
await expect(notificationPage.table).toBeVisible();
}
}
});
});
test('NOTIFY-005: 管理员搜索通知', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
await noticePage.addNotification(title, content, '1', '0');
await noticePage.verifyTableContains(title);
});
await test.step('搜索通知', async () => {
await notificationPage.searchNotification('测试');
await page.waitForTimeout(1000);
});
await test.step('清除搜索条件', async () => {
await notificationPage.clearSearch();
const rowCount = await notificationPage.getTableRowCount();
expect(rowCount).toBeGreaterThanOrEqual(0);
});
});
test('NOTIFY-006: 验证通知权限控制', async ({ page }) => {
await test.step('普通用户登录', async () => {
await loginPage.goto();
await loginPage.login('user', 'user123');
await expect(page).toHaveURL(/.*dashboard/);
});
await test.step('尝试访问通知管理页面', async () => {
await page.goto('/notice');
await page.waitForLoadState('networkidle');
await test.step('创建草稿通知', async () => {
const title = `草稿通知_${Date.now()}`;
const content = `这是一条草稿通知_${Date.now()}`;
const currentURL = page.url();
if (currentURL.includes('/notice')) {
await expect(notificationPage.table).toBeVisible();
} else {
await expect(page).toHaveURL(/.*dashboard/);
}
await noticePage.addNotification(title, content, '1', '1');
await noticePage.verifyTableContains(title);
});
});
test('NOTIFY-007: 验证通知状态管理', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
test('通知公告内容验证', async ({ page }) => {
await test.step('导航到通知公告页面', async () => {
await noticePage.goto();
});
await test.step('验证通知状态显示', async () => {
await expect(notificationPage.table).toContainText('状态');
const rows = await notificationPage.table.locator('.el-table__row').count();
expect(rows).toBeGreaterThanOrEqual(0);
});
});
test('NOTIFY-008: 验证通知类型分类', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('验证通知类型显示', async () => {
await expect(notificationPage.table).toContainText('通知类型');
const rows = await notificationPage.table.locator('.el-table__row').count();
expect(rows).toBeGreaterThanOrEqual(0);
});
});
test('NOTIFY-009: 验证通知创建时间显示', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('验证创建时间显示', async () => {
await expect(notificationPage.table).toContainText('创建时间');
const rows = await notificationPage.table.locator('.el-table__row').count();
expect(rows).toBeGreaterThanOrEqual(0);
});
});
test('NOTIFY-010: 验证通知操作按钮可见性', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('验证新增按钮可见', async () => {
await expect(notificationPage.addButton).toBeVisible();
});
await test.step('验证搜索框可见', async () => {
await expect(notificationPage.searchInput).toBeVisible();
});
});
test('NOTIFY-011: 验证通知内容完整性', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('验证通知内容显示', async () => {
const rows = await notificationPage.table.locator('.el-table__row').count();
if (rows > 0) {
const firstRow = notificationPage.table.locator('.el-table__row').first();
await expect(firstRow).toBeVisible();
}
});
});
test('NOTIFY-012: 验证通知标题必填验证', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('点击新增按钮', async () => {
await notificationPage.addButton.click();
await page.waitForTimeout(500);
});
await test.step('不填写标题直接保存', async () => {
await notificationPage.saveButton.click();
await page.waitForTimeout(500);
await test.step('验证通知标题长度限制', async () => {
const longTitle = '这是一个非常非常长的通知标题,用于测试系统对长标题的处理能力,确保系统能够正确显示和存储长标题';
const content = '测试内容';
const errorMessage = page.locator('.el-message--error');
const errorCount = await errorMessage.count();
expect(errorCount).toBeGreaterThan(0);
});
});
test('NOTIFY-013: 验证通知内容必填验证', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
await noticePage.addNotification(longTitle, content);
await noticePage.verifyTableContains(longTitle.substring(0, 50));
});
await test.step('点击新增按钮', async () => {
await notificationPage.addButton.click();
await page.waitForTimeout(500);
});
await test.step('填写标题但不填写内容', async () => {
await notificationPage.titleInput.fill('测试标题');
await notificationPage.saveButton.click();
await page.waitForTimeout(500);
await test.step('验证通知内容格式', async () => {
const title = `格式测试通知_${Date.now()}`;
const content = '支持富文本格式:<b>粗体</b>、<i>斜体</i>、<u>下划线</u>';
const errorMessage = page.locator('.el-message--error');
const errorCount = await errorMessage.count();
expect(errorCount).toBeGreaterThan(0);
await noticePage.addNotification(title, content);
await noticePage.verifyTableContains(title);
});
});
test('NOTIFY-014: 验证通知删除确认', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('删除通知并确认', async () => {
const testRow = notificationPage.table.locator('tr').filter({ hasText: '测试通知' }).first();
const testRowCount = await testRow.count();
if (testRowCount > 0) {
const title = await testRow.locator('td').nth(1).textContent();
if (title) {
await notificationPage.deleteNotification(title);
await page.waitForTimeout(1000);
await expect(notificationPage.table).toBeVisible();
}
}
});
});
test('NOTIFY-015: 验证通知列表排序', async ({ page }) => {
await test.step('管理员登录并导航到通知管理', async () => {
await loginPage.goto();
await loginPage.login('admin', 'admin123');
await notificationPage.goto();
});
await test.step('验证通知按创建时间排序', async () => {
const firstRow = notificationPage.table.locator('.el-table__row').first();
await expect(firstRow).toBeVisible();
const rows = await notificationPage.table.locator('.el-table__row').count();
expect(rows).toBeGreaterThanOrEqual(0);
});
});
});
});