Files
novalon-manage-system/novalon-manage-web/e2e/role-management-exceptions.spec.ts
T
张翔 e2ad1331cc feat: 添加测试框架和覆盖率报告功能
feat(测试): 新增Playwright和Vitest测试配置
feat(测试): 添加测试覆盖率报告生成功能
feat(测试): 实现前后端测试脚本集成

fix(测试): 修复测试密码不匹配问题
fix(测试): 修正URL等待策略
fix(测试): 调整错误消息选择器

refactor(测试): 重构测试目录结构
refactor(测试): 优化测试用例组织方式

docs: 更新测试报告文档
docs: 添加测试覆盖率报告模板

ci: 添加Docker测试环境配置
ci: 实现测试自动化脚本

chore: 更新依赖版本
chore: 添加测试相关配置文件
2026-03-25 09:03:37 +08:00

387 lines
14 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { DashboardPage } from './pages/DashboardPage';
import { RoleManagementPage } from './pages/RoleManagementPage';
import { TestDataManager } from './utils/testDataManager';
import { TestHelper } from './utils/testHelper';
test.describe('角色管理异常场景测试', () => {
let loginPage: LoginPage;
let dashboardPage: DashboardPage;
let roleManagementPage: RoleManagementPage;
let testRole: any;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
dashboardPage = new DashboardPage(page);
roleManagementPage = new RoleManagementPage(page);
await loginPage.goto();
await loginPage.login('admin', 'admin123');
});
test.afterEach(async ({ page, request }) => {
await TestHelper.clearAllStorage(page);
if (testRole) {
await TestDataManager.deleteTestRole(request, testRole.roleKey);
testRole = null;
}
});
test('创建角色 - 重复角色键', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('尝试创建重复角色键的角色', async () => {
await roleManagementPage.clickCreateRole();
await TestHelper.waitForElementVisible(page, '.el-dialog');
const roleData = {
roleName: '管理员',
roleKey: 'admin',
roleSort: '1',
status: '1',
remark: '重复角色键',
};
await roleManagementPage.fillRoleForm(roleData);
await roleManagementPage.submitForm();
});
await test.step('验证错误消息', async () => {
await TestHelper.waitForErrorMessage(page);
const errorMessage = await TestHelper.getElementText(page, '.el-message__content');
expect(errorMessage).toContain('角色键已存在');
});
});
test('创建角色 - 缺少必填字段', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('尝试创建缺少必填字段的角色', async () => {
await roleManagementPage.clickCreateRole();
await TestHelper.waitForElementVisible(page, '.el-dialog');
const roleData = {
roleName: '',
roleKey: '',
roleSort: '',
status: '',
remark: '',
};
await roleManagementPage.fillRoleForm(roleData);
await roleManagementPage.submitForm();
});
await test.step('验证表单验证', async () => {
const submitButton = page.locator('.el-dialog__footer button[type="submit"]');
const isDisabled = await submitButton.evaluate(el => (el as HTMLButtonElement).disabled);
expect(isDisabled).toBeTruthy();
});
});
test('创建角色 - 无效角色键格式', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('尝试创建无效角色键格式的角色', async () => {
await roleManagementPage.clickCreateRole();
await TestHelper.waitForElementVisible(page, '.el-dialog');
const roleData = {
roleName: `测试角色_${Date.now()}`,
roleKey: '无效角色键!@#',
roleSort: '1',
status: '1',
remark: '无效角色键格式',
};
await roleManagementPage.fillRoleForm(roleData);
await roleManagementPage.submitForm();
});
await test.step('验证角色键格式错误', async () => {
const roleKeyInput = page.locator('input[name="roleKey"]');
const hasError = await roleKeyInput.evaluate(el => el.classList.contains('is-error'));
expect(hasError).toBeTruthy();
});
});
test('编辑角色 - 不存在的角色ID', async ({ page }) => {
await test.step('尝试编辑不存在的角色', async () => {
await page.goto('/roles/999999/edit');
await TestHelper.waitForPageLoad(page);
});
await test.step('验证404错误或重定向', async () => {
const currentUrl = page.url();
expect(currentUrl).toMatch(/(404|roles)/);
});
});
test('删除角色 - 不存在的角色ID', async ({ page, request }) => {
await test.step('尝试删除不存在的角色', async () => {
const response = await request.delete('http://localhost:8084/api/roles/999999');
expect(response.status()).toBe(404);
});
});
test('删除角色 - 系统内置角色', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('尝试删除系统内置角色', async () => {
const adminRoleRow = page.locator('table tbody tr').filter({ hasText: 'admin' }).first();
const deleteButton = adminRoleRow.locator('.delete-button');
if (await deleteButton.count() > 0) {
await deleteButton.click();
await TestHelper.waitForElementVisible(page, '.el-message-box');
await page.click('.el-message-box__btns .el-button--primary');
await TestHelper.waitForPageLoad(page);
}
});
await test.step('验证系统内置角色不能删除', async () => {
const adminRoleRow = page.locator('table tbody tr').filter({ hasText: 'admin' }).first();
await expect(adminRoleRow).toBeVisible();
});
});
test('搜索角色 - 空搜索条件', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('执行空搜索', async () => {
const searchInput = page.locator('input[placeholder*="搜索"]').or(page.locator('.search-input'));
if (await searchInput.count() > 0) {
await searchInput.fill('');
await TestHelper.waitForPageLoad(page);
}
});
await test.step('验证显示所有角色', async () => {
const roleCount = await page.locator('.el-table__body tr').count();
expect(roleCount).toBeGreaterThan(0);
});
});
test('搜索角色 - 不存在的角色名', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('搜索不存在的角色', async () => {
const searchInput = page.locator('input[placeholder*="搜索"]').or(page.locator('.search-input'));
if (await searchInput.count() > 0) {
await searchInput.fill('nonexistentrole123456');
await TestHelper.waitForPageLoad(page);
}
});
await test.step('验证无结果', async () => {
const roleCount = await page.locator('.el-table__body tr').count();
expect(roleCount).toBe(0);
});
});
test('分配权限 - 角色不存在', async ({ page, request }) => {
await test.step('尝试为不存在的角色分配权限', async () => {
const response = await request.post('http://localhost:8084/api/roles/999999/permissions', {
data: { permissions: ['user:view'] }
});
expect(response.status()).toBe(404);
});
});
test('分配权限 - 无效权限标识', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('尝试分配无效权限', async () => {
const firstRow = page.locator('.el-table__body tr').first();
await firstRow.click();
await TestHelper.waitForElementVisible(page, '.permission-dialog');
const invalidPermission = page.locator('.permission-item').filter({ hasText: 'invalid:permission' });
if (await invalidPermission.count() > 0) {
await invalidPermission.click();
await page.click('.permission-dialog .save-button');
await TestHelper.waitForPageLoad(page);
}
});
await test.step('验证权限分配失败', async () => {
await TestHelper.waitForErrorMessage(page);
});
});
test('角色状态切换 - 禁用后用户无法登录', async ({ page, request }) => {
testRole = TestDataManager.generateTestRole();
await TestDataManager.createTestRole(request, testRole);
const testUser = TestDataManager.generateTestUser({ roleIds: [testRole.id] });
await TestDataManager.createTestUser(request, testUser);
await test.step('禁用角色', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
const roleRow = page.locator('table tbody tr').filter({ hasText: testRole.roleName }).first();
await roleRow.locator('.status-toggle').click();
await TestHelper.waitForSuccessMessage(page);
});
await test.step('验证用户无法登录', async () => {
await loginPage.logout();
await loginPage.goto();
const testUser = TestDataManager.generateTestUser();
await loginPage.login(testUser.username, testUser.password);
await TestHelper.waitForErrorMessage(page);
const currentUrl = page.url();
expect(currentUrl).toContain('/login');
});
});
test('批量删除角色 - 未选择角色', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('尝试批量删除未选择的角色', async () => {
const batchDeleteButton = page.locator('button:has-text("批量删除")');
if (await batchDeleteButton.count() > 0) {
await batchDeleteButton.click();
}
});
await test.step('验证提示消息', async () => {
await TestHelper.waitForErrorMessage(page);
});
});
test('批量删除角色 - 包含系统内置角色', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('选择包含系统内置角色的多个角色', async () => {
const adminRoleRow = page.locator('table tbody tr').filter({ hasText: 'admin' }).first();
await adminRoleRow.locator('input[type="checkbox"]').check();
const otherRoleRow = page.locator('table tbody tr').nth(1);
if (await otherRoleRow.count() > 0) {
await otherRoleRow.locator('input[type="checkbox"]').check();
}
});
await test.step('尝试批量删除', async () => {
const batchDeleteButton = page.locator('button:has-text("批量删除")');
if (await batchDeleteButton.count() > 0) {
await batchDeleteButton.click();
await TestHelper.waitForElementVisible(page, '.el-message-box');
await page.click('.el-message-box__btns .el-button--primary');
await TestHelper.waitForPageLoad(page);
}
});
await test.step('验证系统内置角色未被删除', async () => {
const adminRoleRow = page.locator('table tbody tr').filter({ hasText: 'admin' }).first();
await expect(adminRoleRow).toBeVisible();
});
});
test('网络错误 - 创建角色时断网', async ({ page }) => {
await test.step('导航到角色管理页面', async () => {
await dashboardPage.navigateToRoleManagement();
await TestHelper.waitForPageLoad(page);
});
await test.step('模拟网络错误', async () => {
await page.route('**/api/roles', route => route.abort('failed'));
});
await test.step('尝试创建角色', async () => {
await roleManagementPage.clickCreateRole();
await TestHelper.waitForElementVisible(page, '.el-dialog');
const roleData = {
roleName: `测试角色_${Date.now()}`,
roleKey: `test_role_${Date.now()}`,
roleSort: '1',
status: '1',
remark: '测试角色',
};
await roleManagementPage.fillRoleForm(roleData);
await roleManagementPage.submitForm();
});
await test.step('验证网络错误提示', async () => {
await TestHelper.waitForErrorMessage(page);
});
});
test('并发操作 - 同时编辑同一角色', async ({ page, context }) => {
const page1 = page;
const page2 = await context.newPage();
await page1.goto('/roles');
await page2.goto('/roles');
await TestHelper.waitForPageLoad(page1);
await TestHelper.waitForPageLoad(page2);
const firstRow1 = page1.locator('.el-table__body tr').first();
const firstRow2 = page2.locator('.el-table__body tr').first();
await firstRow1.click();
await firstRow2.click();
await TestHelper.waitForElementVisible(page1, '.el-dialog');
await TestHelper.waitForElementVisible(page2, '.el-dialog');
await page1.fill('input[name="roleName"]', '并发编辑1');
await page2.fill('input[name="roleName"]', '并发编辑2');
await page1.click('.el-dialog__footer button[type="submit"]');
await TestHelper.waitForPageLoad(page1);
await page2.click('.el-dialog__footer button[type="submit"]');
await TestHelper.waitForPageLoad(page2);
await page1.goto('/roles');
await page2.goto('/roles');
await TestHelper.waitForPageLoad(page1);
await TestHelper.waitForPageLoad(page2);
const errorMessage1 = await TestHelper.getElementText(page1, '.el-message__content');
const errorMessage2 = await TestHelper.getElementText(page2, '.el-message__content');
expect(errorMessage1 || errorMessage2).toContain('数据已被其他用户修改');
});
});