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('数据已被其他用户修改'); }); });