test: E2E 测试用例更新与新增
- 更新 Page Object 模型适配新字段名 - 新增 UAT 测试套件与 journey 测试用例 - 优化测试辅助工具与数据工厂 - 更新 playwright 认证状态
This commit is contained in:
@@ -21,20 +21,20 @@ test.describe('管理员完整工作流', () => {
|
||||
|
||||
await test.step('点击创建角色按钮', async () => {
|
||||
await page.locator('button:has-text("新增角色")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写角色信息', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await dialog.locator('input').first().fill(roleName);
|
||||
await dialog.locator('input').nth(1).fill(roleKey);
|
||||
await dialog.locator('.el-input-number .el-input__inner').fill('99');
|
||||
await dialog.locator('.ant-input-number .ant-input__inner').fill('99');
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await page.locator('.el-dialog button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,11 +51,11 @@ test.describe('管理员完整工作流', () => {
|
||||
|
||||
await test.step('点击创建用户按钮', async () => {
|
||||
await page.locator('button:has-text("新增用户")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写用户信息', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await dialog.locator('input').first().fill(username);
|
||||
await dialog.locator('input[type="password"]').fill('Test@123');
|
||||
await dialog.locator('input').nth(2).fill(`测试用户${timestamp}`);
|
||||
@@ -64,9 +64,9 @@ test.describe('管理员完整工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await page.locator('.el-dialog button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('搜索新创建的用户', async () => {
|
||||
@@ -85,13 +85,13 @@ test.describe('管理员完整工作流', () => {
|
||||
await expect(userRow).toBeVisible({ timeout: 10000 });
|
||||
|
||||
await userRow.locator('button:has-text("分配角色")').click();
|
||||
await page.waitForSelector('.el-dialog:has-text("分配角色")', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal:has-text("分配角色")', { state: 'visible', timeout: 5000 });
|
||||
|
||||
const transfer = page.locator('.el-transfer');
|
||||
const leftPanel = transfer.locator('.el-transfer-panel').first();
|
||||
const rightPanel = transfer.locator('.el-transfer-panel').last();
|
||||
const transfer = page.locator('.ant-transfer');
|
||||
const leftPanel = transfer.locator('.ant-transfer-list').first();
|
||||
const rightPanel = transfer.locator('.ant-transfer-list').last();
|
||||
|
||||
const rightPanelItems = await rightPanel.locator('.el-checkbox').all();
|
||||
const rightPanelItems = await rightPanel.locator('.ant-checkbox').all();
|
||||
let hasSuperAdminRole = false;
|
||||
|
||||
for (const item of rightPanelItems) {
|
||||
@@ -103,7 +103,7 @@ test.describe('管理员完整工作流', () => {
|
||||
}
|
||||
|
||||
if (!hasSuperAdminRole) {
|
||||
const leftPanelItems = await leftPanel.locator('.el-checkbox').all();
|
||||
const leftPanelItems = await leftPanel.locator('.ant-checkbox').all();
|
||||
let superAdminCheckbox = null;
|
||||
|
||||
for (const item of leftPanelItems) {
|
||||
@@ -121,7 +121,7 @@ test.describe('管理员完整工作流', () => {
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
const moveToRightButton = transfer.locator('.el-transfer__buttons button').nth(1);
|
||||
const moveToRightButton = transfer.locator('.ant-transfer-operation button').nth(1);
|
||||
if (await moveToRightButton.isEnabled()) {
|
||||
await moveToRightButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
@@ -129,9 +129,9 @@ test.describe('管理员完整工作流', () => {
|
||||
}
|
||||
}
|
||||
|
||||
await page.locator('.el-dialog:has-text("分配角色") button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog:has-text("分配角色")', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success').last()).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal:has-text("分配角色") button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal:has-text("分配角色")', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success').last()).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -140,7 +140,7 @@ test.describe('管理员完整工作流', () => {
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const avatarButton = page.locator('.el-avatar').first();
|
||||
const avatarButton = page.locator('.ant-avatar').first();
|
||||
await avatarButton.click({ timeout: 10000 });
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
@@ -166,7 +166,7 @@ test.describe('管理员完整工作流', () => {
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const avatarButton = page.locator('.el-avatar').first();
|
||||
const avatarButton = page.locator('.ant-avatar').first();
|
||||
if (await avatarButton.isVisible()) {
|
||||
await avatarButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
@@ -187,7 +187,7 @@ test.describe('管理员完整工作流', () => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('button:has-text("删除")').first().click();
|
||||
await page.locator('button:has-text("确定")').click();
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('删除测试角色', async () => {
|
||||
@@ -197,7 +197,7 @@ test.describe('管理员完整工作流', () => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('button:has-text("删除")').first().click();
|
||||
await page.locator('button:has-text("确定")').click();
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { OperationLogPage } from '../pages/OperationLogPage';
|
||||
import { LoginLogPage } from '../pages/LoginLogPage';
|
||||
import { ExceptionLogPage } from '../pages/ExceptionLogPage';
|
||||
|
||||
test.describe('User Journey: 审计日志查看', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test('UJ-08: 操作日志查看与搜索', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const opLogPage = new OperationLogPage(page);
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到操作日志', async () => {
|
||||
await opLogPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证日志表格加载', async () => {
|
||||
await expect(opLogPage.table).toBeVisible({ timeout: 15000 });
|
||||
});
|
||||
|
||||
await test.step('搜索日志', async () => {
|
||||
await opLogPage.searchByKeyword('admin');
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await test.step('刷新日志', async () => {
|
||||
await opLogPage.reload();
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-09: 登录日志查看', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const loginLogPage = new LoginLogPage(page);
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到登录日志', async () => {
|
||||
await loginLogPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证日志表格加载', async () => {
|
||||
await expect(loginLogPage.table).toBeVisible({ timeout: 15000 });
|
||||
});
|
||||
|
||||
await test.step('搜索日志', async () => {
|
||||
await loginLogPage.searchByKeyword('admin');
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-10: 异常日志查看', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const exLogPage = new ExceptionLogPage(page);
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到异常日志', async () => {
|
||||
await exLogPage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证日志表格加载', async () => {
|
||||
await expect(exLogPage.table).toBeVisible({ timeout: 15000 });
|
||||
});
|
||||
|
||||
await test.step('搜索日志', async () => {
|
||||
await exLogPage.search('error');
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -24,17 +24,17 @@ test.describe('审计工作流', () => {
|
||||
await page.locator('text=审计日志').click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.locator('.el-menu-item:has-text("操作日志")').click();
|
||||
await page.locator('.ant-menu-item:has-text("操作日志")').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page).toHaveURL(/.*oplog/, { timeout: 10000 });
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证操作日志记录', async () => {
|
||||
await page.waitForTimeout(2000);
|
||||
const logContent = await page.locator('.el-table').textContent();
|
||||
const logContent = await page.locator('.ant-table').textContent();
|
||||
expect(logContent).toMatch(/用户管理|角色管理|菜单管理/);
|
||||
});
|
||||
});
|
||||
@@ -47,7 +47,7 @@ test.describe('审计工作流', () => {
|
||||
await page.locator('text=审计日志').click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.locator('.el-menu-item:has-text("登录日志")').click();
|
||||
await page.locator('.ant-menu-item:has-text("登录日志")').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
@@ -55,8 +55,8 @@ test.describe('审计工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('验证登录日志显示', async () => {
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
const logContent = await page.locator('.el-table').textContent();
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
const logContent = await page.locator('.ant-table').textContent();
|
||||
expect(logContent).toBeTruthy();
|
||||
expect(logContent.length).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -70,24 +70,24 @@ test.describe('审计工作流', () => {
|
||||
await page.locator('text=审计日志').click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.locator('.el-menu-item:has-text("操作日志")').click();
|
||||
await page.locator('.ant-menu-item:has-text("操作日志")').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('按模块筛选', async () => {
|
||||
const moduleSelect = page.locator('.el-select:has-text("模块")');
|
||||
const moduleSelect = page.locator('.ant-select:has-text("模块")');
|
||||
if (await moduleSelect.isVisible()) {
|
||||
await moduleSelect.click();
|
||||
await page.locator('.el-select-dropdown__item:has-text("用户管理")').click();
|
||||
await page.locator('.ant-select-item:has-text("用户管理")').click();
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('按时间范围筛选', async () => {
|
||||
const dateRangePicker = page.locator('.el-date-editor');
|
||||
const dateRangePicker = page.locator('.ant-picker');
|
||||
if (await dateRangePicker.isVisible()) {
|
||||
await dateRangePicker.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { SystemConfigPage } from '../pages/SystemConfigPage';
|
||||
import { DictionaryManagementPage } from '../pages/DictionaryManagementPage';
|
||||
|
||||
test.describe('User Journey: 系统配置与字典管理', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
const timestamp = Date.now();
|
||||
|
||||
test('UJ-04: 系统配置 CRUD', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const configPage = new SystemConfigPage(page);
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到系统配置', async () => {
|
||||
await configPage.goto();
|
||||
});
|
||||
|
||||
await test.step('创建配置', async () => {
|
||||
await configPage.addConfig(
|
||||
`E2E配置_${timestamp}`,
|
||||
`e2e.config.key_${timestamp}`,
|
||||
'e2e_test_value',
|
||||
'test',
|
||||
'E2E测试配置'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('验证配置已创建', async () => {
|
||||
const exists = await configPage.containsText(`e2e.config.key_${timestamp}`);
|
||||
expect(exists).toBe(true);
|
||||
});
|
||||
|
||||
await test.step('编辑配置值', async () => {
|
||||
await configPage.editConfig(`e2e.config.key_${timestamp}`, 'updated_value');
|
||||
});
|
||||
|
||||
await test.step('删除配置', async () => {
|
||||
await configPage.deleteConfig(`e2e.config.key_${timestamp}`);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-05: 字典类型与数据 CRUD', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const dictPage = new DictionaryManagementPage(page);
|
||||
const dictName = `E2E字典_${timestamp}`;
|
||||
const dictType = `e2e_dict_${timestamp}`;
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到字典管理', async () => {
|
||||
await dictPage.goto();
|
||||
});
|
||||
|
||||
await test.step('创建字典类型', async () => {
|
||||
await dictPage.createDictType(dictName, dictType, 1, 'E2E测试字典');
|
||||
});
|
||||
|
||||
await test.step('选择字典类型', async () => {
|
||||
await dictPage.selectDictType(dictType);
|
||||
});
|
||||
|
||||
await test.step('创建字典数据', async () => {
|
||||
await dictPage.createDictData('E2E选项A', 'option_a', 1, 1);
|
||||
});
|
||||
|
||||
await test.step('验证字典数据已创建', async () => {
|
||||
const exists = await dictPage.dataContainsText('E2E选项A');
|
||||
expect(exists).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -113,11 +113,11 @@ test.describe('系统配置工作流', () => {
|
||||
const deleteBtn = firstRow.getByRole('button', { name: '删除' });
|
||||
if (await deleteBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await deleteBtn.click();
|
||||
const confirmBtn = page.locator('.el-message-box');
|
||||
const confirmBtn = page.locator('.ant-message-box');
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 3000 });
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
const confirmBtn = page.locator('.el-message-box').getByRole('button', { name: '确定' });
|
||||
const confirmBtn = page.locator('.ant-message-box').getByRole('button', { name: '确定' });
|
||||
if (await confirmBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
@@ -125,7 +125,7 @@ test.describe('系统配置工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const messageBox = page.locator('.el-message-box');
|
||||
const messageBox = page.locator('.ant-message-box');
|
||||
await expect(messageBox).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`配置已删除`);
|
||||
});
|
||||
|
||||
@@ -111,11 +111,11 @@ test.describe('字典管理工作流', () => {
|
||||
const deleteBtn = firstRow.getByRole('button', { name: '删除' });
|
||||
if (await deleteBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await deleteBtn.click();
|
||||
const confirmBtn = page.locator('.el-message-box');
|
||||
const confirmBtn = page.locator('.ant-message-box');
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 3000 });
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
const confirmBtn = page.locator('.el-message-box').getByRole('button', { name: '确定' });
|
||||
const confirmBtn = page.locator('.ant-message-box').getByRole('button', { name: '确定' });
|
||||
if (await confirmBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
@@ -123,7 +123,7 @@ test.describe('字典管理工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const messageBox = page.locator('.el-message-box');
|
||||
const messageBox = page.locator('.ant-message-box');
|
||||
await expect(messageBox).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`字典已删除`);
|
||||
});
|
||||
|
||||
@@ -20,19 +20,19 @@ test.describe('数据字典管理完整工作流', () => {
|
||||
|
||||
await test.step('点击新增字典按钮', async () => {
|
||||
await page.locator('button:has-text("新增字典")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写字典信息', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await dialog.locator('input').first().fill(dictName);
|
||||
await dialog.locator('input').nth(1).fill(dictType);
|
||||
});
|
||||
|
||||
await test.step('提交字典表单', async () => {
|
||||
await page.locator('.el-dialog button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('验证字典已创建', async () => {
|
||||
@@ -57,18 +57,18 @@ test.describe('数据字典管理完整工作流', () => {
|
||||
await test.step('编辑字典', async () => {
|
||||
const dictRow = page.locator(`tr:has-text("${dictName}")`);
|
||||
await dictRow.locator('button:has-text("编辑")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('修改字典信息', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await dialog.locator('input').first().fill(updatedName);
|
||||
});
|
||||
|
||||
await test.step('提交更新', async () => {
|
||||
await page.locator('.el-dialog button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('验证字典已更新', async () => {
|
||||
@@ -91,13 +91,13 @@ test.describe('数据字典管理完整工作流', () => {
|
||||
await test.step('删除字典', async () => {
|
||||
const dictRow = page.locator(`tr:has-text("更新字典_${timestamp}")`);
|
||||
await dictRow.locator('button:has-text("删除")').click();
|
||||
await page.waitForSelector('.el-message-box', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-message-box', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
await page.locator('.el-message-box button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-message-box', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-message-box button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-message-box', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ test.describe('异常日志工作流', () => {
|
||||
await detailButton.click();
|
||||
|
||||
await test.step('验证详情对话框显示', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await expect(dialog).toBeVisible({ timeout: 5000 });
|
||||
console.log('异常日志详情对话框已打开');
|
||||
});
|
||||
|
||||
@@ -9,11 +9,11 @@ test.describe('文件管理工作流', () => {
|
||||
await page.locator('text=系统管理').click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.locator('.el-menu-item:has-text("文件管理")').click();
|
||||
await page.locator('.ant-menu-item:has-text("文件管理")').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('上传文件', async () => {
|
||||
@@ -30,7 +30,7 @@ test.describe('文件管理工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('验证文件上传成功', async () => {
|
||||
const successMessage = page.locator('.el-message--success');
|
||||
const successMessage = page.locator('.ant-message-success');
|
||||
if (await successMessage.isVisible()) {
|
||||
expect(await successMessage.textContent()).toContain('成功');
|
||||
}
|
||||
@@ -54,10 +54,10 @@ test.describe('文件管理工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('按类型筛选', async () => {
|
||||
const typeFilter = page.locator('.el-select:has-text("类型")');
|
||||
const typeFilter = page.locator('.ant-select:has-text("类型")');
|
||||
if (await typeFilter.isVisible()) {
|
||||
await typeFilter.click();
|
||||
await page.locator('.el-select-dropdown__item').first().click();
|
||||
await page.locator('.ant-select-item').first().click();
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
});
|
||||
@@ -71,7 +71,7 @@ test.describe('文件管理工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('选择文件', async () => {
|
||||
const fileCheckbox = page.locator('.el-checkbox').first();
|
||||
const fileCheckbox = page.locator('.ant-checkbox').first();
|
||||
if (await fileCheckbox.isVisible()) {
|
||||
await fileCheckbox.click();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { DashboardPage } from '../pages/DashboardPage';
|
||||
|
||||
test.describe('User Journey: 登录 → 仪表盘 → 登出', () => {
|
||||
test('UJ-01: 管理员完整登录登出流程', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const dashboardPage = new DashboardPage(page);
|
||||
|
||||
await test.step('访问登录页面', async () => {
|
||||
await loginPage.goto();
|
||||
await expect(page).toHaveURL(/.*login/);
|
||||
await expect(loginPage.usernameInput).toBeVisible();
|
||||
await expect(loginPage.passwordInput).toBeVisible();
|
||||
await expect(loginPage.loginButton).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('输入凭据并登录', async () => {
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('验证登录成功跳转到仪表盘', async () => {
|
||||
await expect(page).toHaveURL(/.*dashboard/);
|
||||
});
|
||||
|
||||
await test.step('验证仪表盘内容加载', async () => {
|
||||
await expect(page.locator('.ant-statistic').first()).toBeVisible({ timeout: 15000 });
|
||||
});
|
||||
|
||||
await test.step('验证侧边菜单可见', async () => {
|
||||
await expect(page.locator('.ant-menu')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('点击头像下拉菜单', async () => {
|
||||
await page.locator('.ant-avatar').first().click();
|
||||
await page.waitForTimeout(500);
|
||||
await expect(page.locator('.ant-dropdown-menu-item:has-text("退出登录")')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('点击退出登录', async () => {
|
||||
await page.locator('.ant-dropdown-menu-item:has-text("退出登录")').click();
|
||||
await page.waitForURL(/.*login/, { timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证已跳转到登录页面', async () => {
|
||||
await expect(page).toHaveURL(/.*login/);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-01b: 登录失败场景', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
|
||||
await test.step('访问登录页面', async () => {
|
||||
await loginPage.goto();
|
||||
});
|
||||
|
||||
await test.step('输入错误密码', async () => {
|
||||
await loginPage.loginAndExpectError('admin', 'wrongpassword');
|
||||
});
|
||||
|
||||
await test.step('验证错误消息显示', async () => {
|
||||
const errorMsg = await loginPage.getErrorMessage();
|
||||
expect(errorMsg).not.toBeNull();
|
||||
});
|
||||
|
||||
await test.step('验证仍在登录页面', async () => {
|
||||
await expect(page).toHaveURL(/.*login/);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-01c: 未登录访问受保护页面重定向到登录', async ({ page }) => {
|
||||
await test.step('直接访问仪表盘', async () => {
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForTimeout(2000);
|
||||
});
|
||||
|
||||
await test.step('验证被重定向到登录页面', async () => {
|
||||
await expect(page).toHaveURL(/.*login/, { timeout: 10000 });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { DashboardPage } from '../pages/DashboardPage';
|
||||
import { MenuManagementPage } from '../pages/MenuManagementPage';
|
||||
|
||||
test.describe('User Journey: 菜单管理全链路', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
const timestamp = Date.now();
|
||||
const menuName = `E2E菜单_${timestamp}`;
|
||||
|
||||
test('UJ-03: 菜单创建→编辑→删除', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const menuPage = new MenuManagementPage(page);
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到菜单管理', async () => {
|
||||
await menuPage.goto();
|
||||
});
|
||||
|
||||
await test.step('创建新菜单', async () => {
|
||||
await menuPage.clickCreateMenu();
|
||||
await menuPage.fillMenuForm({
|
||||
name: menuName,
|
||||
type: 'menu',
|
||||
path: `/e2e-test-${timestamp}`,
|
||||
icon: 'file',
|
||||
component: `e2e/Test_${timestamp}`,
|
||||
permission: `e2e:test_${timestamp}`,
|
||||
sort: 99,
|
||||
status: 'ACTIVE',
|
||||
visible: true,
|
||||
});
|
||||
await menuPage.submitForm();
|
||||
const success = await menuPage.containsText(menuName);
|
||||
expect(success).toBe(true);
|
||||
});
|
||||
|
||||
await test.step('编辑菜单', async () => {
|
||||
await menuPage.editMenu(menuName);
|
||||
const modal = page.locator('.ant-modal').filter({ hasText: /编辑菜单/ });
|
||||
const nameInput = modal.locator('.ant-form-item').filter({ hasText: '菜单名称' }).locator('input');
|
||||
await nameInput.clear();
|
||||
await nameInput.fill(`${menuName}_已编辑`);
|
||||
await menuPage.submitForm();
|
||||
});
|
||||
|
||||
await test.step('删除菜单', async () => {
|
||||
await menuPage.goto();
|
||||
await menuPage.deleteMenu(`${menuName}_已编辑`);
|
||||
await menuPage.confirmDelete();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -111,11 +111,11 @@ test.describe('通知管理工作流', () => {
|
||||
const deleteBtn = firstRow.getByRole('button', { name: '删除' });
|
||||
if (await deleteBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await deleteBtn.click();
|
||||
const confirmBtn = page.locator('.el-message-box');
|
||||
const confirmBtn = page.locator('.ant-message-box');
|
||||
await confirmBtn.waitFor({ state: 'visible', timeout: 3000 });
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
const confirmBtn = page.locator('.el-message-box').getByRole('button', { name: '确定' });
|
||||
const confirmBtn = page.locator('.ant-message-box').getByRole('button', { name: '确定' });
|
||||
if (await confirmBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
@@ -123,7 +123,7 @@ test.describe('通知管理工作流', () => {
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const messageBox = page.locator('.el-message-box');
|
||||
const messageBox = page.locator('.ant-message-box');
|
||||
await expect(messageBox).not.toBeVisible({ timeout: 5000 });
|
||||
console.log(`通知已删除`);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { NotificationPage } from '../pages/NotificationPage';
|
||||
import { FileManagementPage } from '../pages/FileManagementPage';
|
||||
|
||||
test.describe('User Journey: 通知与文件管理', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
const timestamp = Date.now();
|
||||
|
||||
test('UJ-06: 通知管理 CRUD', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const notifyPage = new NotificationPage(page);
|
||||
const title = `E2E通知_${timestamp}`;
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到通知管理', async () => {
|
||||
await notifyPage.goto();
|
||||
});
|
||||
|
||||
await test.step('创建通知', async () => {
|
||||
await notifyPage.addNotification(title, 'E2E测试通知内容', '通知');
|
||||
});
|
||||
|
||||
await test.step('验证通知已创建', async () => {
|
||||
const exists = await notifyPage.containsText(title);
|
||||
expect(exists).toBe(true);
|
||||
});
|
||||
|
||||
await test.step('编辑通知', async () => {
|
||||
await notifyPage.editNotification(title, '更新后的通知内容');
|
||||
});
|
||||
|
||||
await test.step('删除通知', async () => {
|
||||
await notifyPage.deleteNotification(title);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-07: 文件上传与管理', async ({ page }) => {
|
||||
const loginPage = new LoginPage(page);
|
||||
const filePage = new FileManagementPage(page);
|
||||
|
||||
await test.step('登录', async () => {
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
});
|
||||
|
||||
await test.step('导航到文件管理', async () => {
|
||||
await filePage.goto();
|
||||
});
|
||||
|
||||
await test.step('验证文件管理页面加载', async () => {
|
||||
await expect(filePage.uploadButton).toBeVisible({ timeout: 10000 });
|
||||
await expect(filePage.refreshButton).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('刷新文件列表', async () => {
|
||||
await filePage.reload();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -21,20 +21,20 @@ test.describe('系统配置管理完整工作流', () => {
|
||||
|
||||
await test.step('点击新增配置按钮', async () => {
|
||||
await page.locator('button:has-text("新增配置")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('填写配置信息', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await dialog.locator('input').first().fill(configName);
|
||||
await dialog.locator('input').nth(1).fill(configKey);
|
||||
await dialog.locator('input').nth(2).fill(configValue);
|
||||
});
|
||||
|
||||
await test.step('提交配置表单', async () => {
|
||||
await page.locator('.el-dialog button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('验证配置已创建', async () => {
|
||||
@@ -59,18 +59,18 @@ test.describe('系统配置管理完整工作流', () => {
|
||||
await test.step('编辑配置', async () => {
|
||||
const configRow = page.locator(`tr:has-text("${configName}")`);
|
||||
await configRow.locator('button:has-text("编辑")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-modal', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('修改配置值', async () => {
|
||||
const dialog = page.locator('.el-dialog');
|
||||
const dialog = page.locator('.ant-modal');
|
||||
await dialog.locator('input').nth(2).fill(updatedValue);
|
||||
});
|
||||
|
||||
await test.step('提交更新', async () => {
|
||||
await page.locator('.el-dialog button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-dialog', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-modal button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-modal', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('验证配置已更新', async () => {
|
||||
@@ -93,13 +93,13 @@ test.describe('系统配置管理完整工作流', () => {
|
||||
await test.step('删除配置', async () => {
|
||||
const configRow = page.locator(`tr:has-text("${configName}")`);
|
||||
await configRow.locator('button:has-text("删除")').click();
|
||||
await page.waitForSelector('.el-message-box', { state: 'visible', timeout: 5000 });
|
||||
await page.waitForSelector('.ant-message-box', { state: 'visible', timeout: 5000 });
|
||||
});
|
||||
|
||||
await test.step('确认删除', async () => {
|
||||
await page.locator('.el-message-box button:has-text("确定")').click();
|
||||
await page.waitForSelector('.el-message-box', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 });
|
||||
await page.locator('.ant-message-box button:has-text("确定")').click();
|
||||
await page.waitForSelector('.ant-message-box', { state: 'hidden', timeout: 10000 });
|
||||
await expect(page.locator('.ant-message-success')).toBeVisible({ timeout: 5000 });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -6,21 +6,21 @@ test.describe('用户权限边界验证', () => {
|
||||
await page.goto('/users');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*users/);
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证可以访问角色管理', async () => {
|
||||
await page.goto('/roles');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*roles/);
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('验证可以访问菜单管理', async () => {
|
||||
await page.goto('/menus');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await expect(page).toHaveURL(/.*menus/);
|
||||
await expect(page.locator('.el-table')).toBeVisible({ timeout: 10000 });
|
||||
await expect(page.locator('.ant-table')).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ test.describe('用户权限边界验证', () => {
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const avatarButton = page.locator('.el-avatar').first();
|
||||
const avatarButton = page.locator('.ant-avatar').first();
|
||||
await avatarButton.click({ timeout: 10000 });
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
@@ -68,9 +68,9 @@ test.describe('用户权限边界验证', () => {
|
||||
if (await createButton.isVisible()) {
|
||||
await createButton.click();
|
||||
await page.waitForTimeout(2000);
|
||||
const errorMessage = page.locator('.el-message--error');
|
||||
const errorMessage = page.locator('.ant-message-error');
|
||||
const hasError = await errorMessage.isVisible().catch(() => false);
|
||||
expect(hasError || await page.locator('.el-dialog').isVisible()).toBeTruthy();
|
||||
expect(hasError || await page.locator('.ant-modal').isVisible()).toBeTruthy();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -80,7 +80,7 @@ test.describe('用户权限边界验证', () => {
|
||||
await page.goto('/dashboard');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
const avatarButton = page.locator('.el-avatar').first();
|
||||
const avatarButton = page.locator('.ant-avatar').first();
|
||||
await avatarButton.click({ timeout: 10000 });
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { LoginPage } from '../pages/LoginPage';
|
||||
import { DashboardPage } from '../pages/DashboardPage';
|
||||
import { UserManagementPage } from '../pages/UserManagementPage';
|
||||
import { RoleManagementPage } from '../pages/RoleManagementPage';
|
||||
|
||||
test.describe('User Journey: 用户与角色管理全链路', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
let loginPage: LoginPage;
|
||||
let dashboardPage: DashboardPage;
|
||||
let userPage: UserManagementPage;
|
||||
let rolePage: RoleManagementPage;
|
||||
|
||||
const timestamp = Date.now();
|
||||
const roleName = `E2E角色_${timestamp}`;
|
||||
const roleKey = `e2e_role_${timestamp}`;
|
||||
const username = `e2e_user_${timestamp}`;
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
loginPage = new LoginPage(page);
|
||||
await loginPage.goto();
|
||||
await loginPage.login('admin', 'Test@123');
|
||||
dashboardPage = new DashboardPage(page);
|
||||
userPage = new UserManagementPage(page);
|
||||
rolePage = new RoleManagementPage(page);
|
||||
});
|
||||
|
||||
test('UJ-02a: 创建角色', async () => {
|
||||
await test.step('导航到角色管理', async () => {
|
||||
await rolePage.goto();
|
||||
});
|
||||
|
||||
await test.step('点击新增角色', async () => {
|
||||
await rolePage.clickCreateRole();
|
||||
});
|
||||
|
||||
await test.step('填写角色表单', async () => {
|
||||
await rolePage.fillRoleForm({
|
||||
roleName,
|
||||
roleKey,
|
||||
roleSort: 99,
|
||||
status: 'ACTIVE',
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await rolePage.submitForm();
|
||||
});
|
||||
|
||||
await test.step('验证创建成功', async () => {
|
||||
const success = await rolePage.waitForSuccessMessage();
|
||||
expect(success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-02b: 创建用户并分配角色', async () => {
|
||||
await test.step('导航到用户管理', async () => {
|
||||
await userPage.goto();
|
||||
});
|
||||
|
||||
await test.step('点击新增用户', async () => {
|
||||
await userPage.clickCreateUser();
|
||||
});
|
||||
|
||||
await test.step('填写用户表单', async () => {
|
||||
await userPage.fillUserForm({
|
||||
username,
|
||||
password: 'Test@123456',
|
||||
nickname: `E2E测试用户_${timestamp}`,
|
||||
email: `e2e_${timestamp}@test.com`,
|
||||
phone: '13800138000',
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('提交表单', async () => {
|
||||
await userPage.submitForm();
|
||||
});
|
||||
|
||||
await test.step('验证创建成功', async () => {
|
||||
const success = await userPage.waitForSuccessMessage();
|
||||
expect(success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-02c: 编辑用户', async () => {
|
||||
await test.step('导航到用户管理', async () => {
|
||||
await userPage.goto();
|
||||
await userPage.waitForTableReady();
|
||||
});
|
||||
|
||||
await test.step('编辑第一个用户', async () => {
|
||||
await userPage.editUser(1);
|
||||
});
|
||||
|
||||
await test.step('修改昵称', async () => {
|
||||
const modal = userPage.page.locator('.ant-modal').filter({ hasText: /编辑用户/ });
|
||||
const nicknameInput = modal.locator('.ant-form-item').filter({ hasText: '昵称' }).locator('input');
|
||||
await nicknameInput.clear();
|
||||
await nicknameInput.fill(`修改昵称_${timestamp}`);
|
||||
});
|
||||
|
||||
await test.step('提交修改', async () => {
|
||||
await userPage.submitForm();
|
||||
});
|
||||
|
||||
await test.step('验证修改成功', async () => {
|
||||
const success = await userPage.waitForSuccessMessage();
|
||||
expect(success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
test('UJ-02d: 删除用户', async () => {
|
||||
await test.step('导航到用户管理', async () => {
|
||||
await userPage.goto();
|
||||
await userPage.waitForTableReady();
|
||||
});
|
||||
|
||||
await test.step('删除最后一个用户', async () => {
|
||||
const count = await userPage.getUserCount();
|
||||
if (count > 0) {
|
||||
await userPage.deleteUser(count);
|
||||
await userPage.confirmDelete();
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('验证删除成功', async () => {
|
||||
const success = await userPage.waitForSuccessMessage();
|
||||
expect(success).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user