refactor(审计日志): 优化审计日志架构和 E2E 测试质量
架构改进: - 引入审计日志服务层,实现业务逻辑与数据访问分离 - 添加 Spring Data 审计注解,自动填充创建人、创建时间等字段 - 修复切面范围,避免 Repository 和 Dao 层重复记录 代码优化: - 移除构造函数中的冗余 info 日志,降低生产环境日志量 - 恢复 SQL 文件格式,提高可读性 - 优化 E2E 测试等待策略,移除硬编码等待时间,提高测试稳定性 影响范围: - 后端:审计日志模块(Service、Repository、Aspect、Entity) - 前端:E2E 测试文件(4 个 workflow 测试) - 数据库:审计日志表结构
This commit was merged in pull request #2.
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { SystemConfigPage } from '../pages/SystemConfigPage';
|
||||
|
||||
test.describe('系统配置工作流', () => {
|
||||
let configPage: SystemConfigPage;
|
||||
const timestamp = Date.now();
|
||||
const configKey = `test_config_${timestamp}`;
|
||||
const configName = `测试配置_${timestamp}`;
|
||||
const configValue = `测试值_${timestamp}`;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
configPage = new SystemConfigPage(page);
|
||||
});
|
||||
|
||||
test('查看系统配置列表', async ({ page }) => {
|
||||
await test.step('导航到系统配置页面', async () => {
|
||||
await configPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格显示', async () => {
|
||||
await expect(configPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证数据加载', async () => {
|
||||
const rowCount = await configPage.getTableRowCount();
|
||||
console.log(`系统配置列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('新增系统配置', async ({ page }) => {
|
||||
await test.step('导航到系统配置页面', async () => {
|
||||
await configPage.goto();
|
||||
});
|
||||
|
||||
await test.step('点击新增配置按钮', async () => {
|
||||
await configPage.addButton.click();
|
||||
await configPage.dialog.waitFor({ state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写配置表单', async () => {
|
||||
await configPage.configNameInput.fill(configName);
|
||||
await configPage.configKeyInput.fill(configKey);
|
||||
await configPage.configValueInput.fill(configValue);
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await configPage.saveButton.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('验证创建成功', async () => {
|
||||
await expect(configPage.dialog).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`配置 ${configName} 创建完成`);
|
||||
});
|
||||
});
|
||||
|
||||
test('编辑系统配置', async ({ page }) => {
|
||||
await test.step('导航到系统配置页面', async () => {
|
||||
await configPage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(configPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击编辑按钮', async () => {
|
||||
const rows = await configPage.getTableRowCount();
|
||||
if (rows > 0) {
|
||||
const firstRow = configPage.table.locator('tr').first();
|
||||
const editBtn = firstRow.getByRole('button', { name: '编辑' });
|
||||
if (await editBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await editBtn.click();
|
||||
await configPage.dialog.waitFor({ state: 'visible', timeout: 5000 });
|
||||
|
||||
await test.step('修改配置值', async () => {
|
||||
const newValue = `更新值_${timestamp}`;
|
||||
await configPage.configValueInput.clear();
|
||||
await configPage.configValueInput.fill(newValue);
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await configPage.saveButton.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('验证更新成功', async () => {
|
||||
await expect(configPage.dialog).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`配置已更新`);
|
||||
});
|
||||
} else {
|
||||
console.log('未找到编辑按钮,跳过编辑测试');
|
||||
}
|
||||
} else {
|
||||
console.log('当前没有配置记录,跳过编辑测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('删除系统配置', async ({ page }) => {
|
||||
await test.step('导航到系统配置页面', async () => {
|
||||
await configPage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(configPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击删除按钮', async () => {
|
||||
const rows = await configPage.getTableRowCount();
|
||||
if (rows > 0) {
|
||||
const firstRow = configPage.table.locator('tr').first();
|
||||
const deleteBtn = firstRow.getByRole('button', { name: '删除' });
|
||||
if (await deleteBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await deleteBtn.click();
|
||||
const confirmBtn = page.locator('.el-message-box');
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 3000 });
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
const confirmBtn = page.locator('.el-message-box').getByRole('button', { name: '确定' });
|
||||
if (await confirmBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const messageBox = page.locator('.el-message-box');
|
||||
await expect(messageBox).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`配置已删除`);
|
||||
});
|
||||
} else {
|
||||
console.log('未找到删除按钮,跳过删除测试');
|
||||
}
|
||||
} else {
|
||||
console.log('当前没有配置记录,跳过删除测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,138 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { DictionaryManagementPage } from '../pages/DictionaryManagementPage';
|
||||
|
||||
test.describe('字典管理工作流', () => {
|
||||
let dictPage: DictionaryManagementPage;
|
||||
const timestamp = Date.now();
|
||||
const dictType = `test_dict_${timestamp}`;
|
||||
const dictName = `测试字典_${timestamp}`;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
dictPage = new DictionaryManagementPage(page);
|
||||
});
|
||||
|
||||
test('查看字典列表', async ({ page }) => {
|
||||
await test.step('导航到字典管理页面', async () => {
|
||||
await dictPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格显示', async () => {
|
||||
await expect(dictPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证数据加载', async () => {
|
||||
const rowCount = await dictPage.getDictCount();
|
||||
console.log(`字典列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('新增字典', async ({ page }) => {
|
||||
await test.step('导航到字典管理页面', async () => {
|
||||
await dictPage.goto();
|
||||
});
|
||||
|
||||
await test.step('点击新增字典按钮', async () => {
|
||||
await dictPage.createDictButton.click();
|
||||
await dictPage.dialog.waitFor({ state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写字典表单', async () => {
|
||||
await dictPage.dictNameInput.fill(dictName);
|
||||
await dictPage.dictTypeInput.fill(dictType);
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await dictPage.saveButton.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('验证创建成功', async () => {
|
||||
await expect(dictPage.dialog).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`字典 ${dictName} 创建完成`);
|
||||
});
|
||||
});
|
||||
|
||||
test('编辑字典', async ({ page }) => {
|
||||
await test.step('导航到字典管理页面', async () => {
|
||||
await dictPage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(dictPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击编辑按钮', async () => {
|
||||
const rows = await dictPage.getDictCount();
|
||||
if (rows > 0) {
|
||||
const firstRow = dictPage.table.locator('tr').first();
|
||||
const editBtn = firstRow.getByRole('button', { name: '编辑' });
|
||||
if (await editBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await editBtn.click();
|
||||
await dictPage.dialog.waitFor({ state: 'visible', timeout: 5000 });
|
||||
|
||||
await test.step('修改字典名称', async () => {
|
||||
const newName = `更新字典_${timestamp}`;
|
||||
await dictPage.dictNameInput.clear();
|
||||
await dictPage.dictNameInput.fill(newName);
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await dictPage.saveButton.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('验证更新成功', async () => {
|
||||
await expect(dictPage.dialog).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`字典已更新`);
|
||||
});
|
||||
} else {
|
||||
console.log('未找到编辑按钮,跳过编辑测试');
|
||||
}
|
||||
} else {
|
||||
console.log('当前没有字典记录,跳过编辑测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('删除字典', async ({ page }) => {
|
||||
await test.step('导航到字典管理页面', async () => {
|
||||
await dictPage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(dictPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击删除按钮', async () => {
|
||||
const rows = await dictPage.getDictCount();
|
||||
if (rows > 0) {
|
||||
const firstRow = dictPage.table.locator('tr').first();
|
||||
const deleteBtn = firstRow.getByRole('button', { name: '删除' });
|
||||
if (await deleteBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await deleteBtn.click();
|
||||
const confirmBtn = page.locator('.el-message-box');
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 3000 });
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
const confirmBtn = page.locator('.el-message-box').getByRole('button', { name: '确定' });
|
||||
if (await confirmBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const messageBox = page.locator('.el-message-box');
|
||||
await expect(messageBox).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`字典已删除`);
|
||||
});
|
||||
} else {
|
||||
console.log('未找到删除按钮,跳过删除测试');
|
||||
}
|
||||
} else {
|
||||
console.log('当前没有字典记录,跳过删除测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { ExceptionLogPage } from '../pages/ExceptionLogPage';
|
||||
|
||||
test.describe('异常日志工作流', () => {
|
||||
let exceptionLogPage: ExceptionLogPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
exceptionLogPage = new ExceptionLogPage(page);
|
||||
});
|
||||
|
||||
test('查看异常日志列表', async ({ page }) => {
|
||||
await test.step('导航到异常日志页面', async () => {
|
||||
await exceptionLogPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格显示', async () => {
|
||||
await expect(exceptionLogPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证数据加载', async () => {
|
||||
const rowCount = await exceptionLogPage.getLogCount();
|
||||
console.log(`异常日志列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('搜索异常日志', async ({ page }) => {
|
||||
await test.step('导航到异常日志页面', async () => {
|
||||
await exceptionLogPage.goto();
|
||||
});
|
||||
|
||||
await test.step('输入搜索关键词', async () => {
|
||||
const searchKeyword = 'NullPointerException';
|
||||
await exceptionLogPage.search(searchKeyword);
|
||||
});
|
||||
|
||||
await test.step('验证搜索结果', async () => {
|
||||
await page.waitForLoadState('networkidle');
|
||||
const rowCount = await exceptionLogPage.getLogCount();
|
||||
console.log(`搜索结果包含 ${rowCount} 条记录`);
|
||||
});
|
||||
});
|
||||
|
||||
test('查看异常日志详情', async ({ page }) => {
|
||||
await test.step('导航到异常日志页面', async () => {
|
||||
await exceptionLogPage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(exceptionLogPage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击查看详情按钮', async () => {
|
||||
const detailButton = page.locator('button:has-text("详情")').or(page.locator('.detail-button')).first();
|
||||
if (await detailButton.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await detailButton.click();
|
||||
|
||||
await test.step('验证详情对话框显示', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
await expect(dialog).toBeVisible({ timeout: 5000 });
|
||||
console.log('异常日志详情对话框已打开');
|
||||
});
|
||||
|
||||
await test.step('关闭详情对话框', async () => {
|
||||
await exceptionLogPage.closeDetailDialog();
|
||||
});
|
||||
} else {
|
||||
console.log('当前没有异常日志记录,跳过详情查看测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,138 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { NotificationPage } from '../pages/NotificationPage';
|
||||
|
||||
test.describe('通知管理工作流', () => {
|
||||
let noticePage: NotificationPage;
|
||||
const timestamp = Date.now();
|
||||
const noticeTitle = `测试通知_${timestamp}`;
|
||||
const noticeContent = `这是测试通知内容_${timestamp}`;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
noticePage = new NotificationPage(page);
|
||||
});
|
||||
|
||||
test('查看通知列表', async ({ page }) => {
|
||||
await test.step('导航到通知管理页面', async () => {
|
||||
await noticePage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证表格显示', async () => {
|
||||
await expect(noticePage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证数据加载', async () => {
|
||||
const rowCount = await noticePage.getTableRowCount();
|
||||
console.log(`通知列表包含 ${rowCount} 条记录`);
|
||||
expect(rowCount).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
test('新增通知', async ({ page }) => {
|
||||
await test.step('导航到通知管理页面', async () => {
|
||||
await noticePage.goto();
|
||||
});
|
||||
|
||||
await test.step('点击新增通知按钮', async () => {
|
||||
await noticePage.addButton.click();
|
||||
await noticePage.dialog.waitFor({ state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写通知表单', async () => {
|
||||
await noticePage.titleInput.fill(noticeTitle);
|
||||
await noticePage.contentInput.fill(noticeContent);
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await noticePage.saveButton.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('验证创建成功', async () => {
|
||||
await expect(noticePage.dialog).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`通知 ${noticeTitle} 创建完成`);
|
||||
});
|
||||
});
|
||||
|
||||
test('编辑通知', async ({ page }) => {
|
||||
await test.step('导航到通知管理页面', async () => {
|
||||
await noticePage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(noticePage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击编辑按钮', async () => {
|
||||
const rows = await noticePage.getTableRowCount();
|
||||
if (rows > 0) {
|
||||
const firstRow = noticePage.table.locator('tr').first();
|
||||
const editBtn = firstRow.getByRole('button', { name: '编辑' });
|
||||
if (await editBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await editBtn.click();
|
||||
await noticePage.dialog.waitFor({ state: 'visible', timeout: 5000 });
|
||||
|
||||
await test.step('修改通知内容', async () => {
|
||||
const newContent = `更新通知内容_${timestamp}`;
|
||||
await noticePage.contentInput.clear();
|
||||
await noticePage.contentInput.fill(newContent);
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await noticePage.saveButton.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('验证更新成功', async () => {
|
||||
await expect(noticePage.dialog).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`通知已更新`);
|
||||
});
|
||||
} else {
|
||||
console.log('未找到编辑按钮,跳过编辑测试');
|
||||
}
|
||||
} else {
|
||||
console.log('当前没有通知记录,跳过编辑测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('删除通知', async ({ page }) => {
|
||||
await test.step('导航到通知管理页面', async () => {
|
||||
await noticePage.goto();
|
||||
});
|
||||
|
||||
await test.step('等待数据加载', async () => {
|
||||
await expect(noticePage.table).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('点击删除按钮', async () => {
|
||||
const rows = await noticePage.getTableRowCount();
|
||||
if (rows > 0) {
|
||||
const firstRow = noticePage.table.locator('tr').first();
|
||||
const deleteBtn = firstRow.getByRole('button', { name: '删除' });
|
||||
if (await deleteBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await deleteBtn.click();
|
||||
const confirmBtn = page.locator('.el-message-box');
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 3000 });
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
const confirmBtn = page.locator('.el-message-box').getByRole('button', { name: '确定' });
|
||||
if (await confirmBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const messageBox = page.locator('.el-message-box');
|
||||
await expect(messageBox).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`通知已删除`);
|
||||
});
|
||||
} else {
|
||||
console.log('未找到删除按钮,跳过删除测试');
|
||||
}
|
||||
} else {
|
||||
console.log('当前没有通知记录,跳过删除测试');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user