/** * 权限控制功能端到端测试 * 测试权限管理、角色管理、权限验证等功能 */ import { test, expect, Page } from '@playwright/test'; const TEST_CONFIG = { baseURL: 'http://localhost:5173', timeout: 30000, superAdmin: { username: 'super_admin', password: 'super123456', }, testUser: { username: 'test_user', password: 'test123456', }, }; // 测试权限数据 const TEST_PERMISSION = { name: '测试权限_' + Date.now(), code: 'test:permission:' + Date.now(), type: 'button', parentId: null, description: '这是一个测试权限', resource: '/test/resource', actions: ['view', 'create'], }; // 测试角色数据 const TEST_ROLE = { name: '测试角色_' + Date.now(), code: 'test_role_' + Date.now(), description: '这是一个测试角色', status: 'active', level: 2, }; test.describe('权限管理功能测试', () => { test.beforeEach(async ({ page }) => { test.setTimeout(TEST_CONFIG.timeout); await page.goto(TEST_CONFIG.baseURL); await loginAsSuperAdmin(page); // 导航到权限管理页面 await page.click('[data-testid="menu-system"]'); await page.click('[data-testid="menu-permission-management"]'); await page.waitForURL(/\/system\/permission/); }); test('应该正确显示权限管理页面', async ({ page }) => { // 检查页面标题 await expect(page.locator('.page-title')).toContainText( /权限管理|Permission Management/, ); // 检查权限树结构 await expect(page.locator('.permission-tree')).toBeVisible(); await expect(page.locator('.ant-tree')).toBeVisible(); // 检查操作按钮 await expect( page.locator('[data-testid="add-permission-button"]'), ).toBeVisible(); await expect( page.locator('[data-testid="expand-all-button"]'), ).toBeVisible(); await expect( page.locator('[data-testid="collapse-all-button"]'), ).toBeVisible(); // 检查权限详情面板 await expect(page.locator('.permission-details')).toBeVisible(); }); test('应该能创建新权限', async ({ page }) => { // 点击添加权限按钮 await page.click('[data-testid="add-permission-button"]'); // 等待创建弹窗出现 await expect(page.locator('.ant-modal')).toBeVisible(); await expect(page.locator('.ant-modal-title')).toContainText( /添加权限|新增权限/, ); // 填写权限信息 await page.fill('[data-testid="form-name"]', TEST_PERMISSION.name); await page.fill('[data-testid="form-code"]', TEST_PERMISSION.code); await page.selectOption('[data-testid="form-type"]', TEST_PERMISSION.type); await page.fill( '[data-testid="form-description"]', TEST_PERMISSION.description, ); await page.fill('[data-testid="form-resource"]', TEST_PERMISSION.resource); // 选择操作权限 for (const action of TEST_PERMISSION.actions) { await page.check(`[data-testid="action-${action}"]`); } // 提交表单 await page.click('[data-testid="form-submit"]'); // 等待成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); await expect(page.locator('.ant-message-success')).toContainText( /创建成功|添加成功/, ); // 弹窗应该关闭 await expect(page.locator('.ant-modal')).not.toBeVisible(); // 在权限树中应该能找到新创建的权限 await expect( page .locator('.ant-tree-node-content-wrapper') .filter({ hasText: TEST_PERMISSION.name }), ).toBeVisible(); }); test('权限树展开折叠功能应该正常工作', async ({ page }) => { // 点击展开所有 await page.click('[data-testid="expand-all-button"]'); // 等待展开完成 await page.waitForTimeout(1000); // 检查是否有展开的节点 const expandedNodes = page.locator('.ant-tree-switcher-open'); expect(await expandedNodes.count()).toBeGreaterThan(0); // 点击折叠所有 await page.click('[data-testid="collapse-all-button"]'); // 等待折叠完成 await page.waitForTimeout(1000); // 检查是否所有节点都被折叠 const collapsedNodes = page.locator('.ant-tree-switcher-close'); expect(await collapsedNodes.count()).toBeGreaterThan(0); }); test('权限详情查看应该正常工作', async ({ page }) => { // 点击权限树中的一个节点 const firstPermissionNode = page .locator('.ant-tree-node-content-wrapper') .first(); await firstPermissionNode.click(); // 检查权限详情面板是否更新 await expect(page.locator('.permission-details')).toBeVisible(); await expect(page.locator('[data-testid="detail-name"]')).toBeVisible(); await expect(page.locator('[data-testid="detail-code"]')).toBeVisible(); await expect(page.locator('[data-testid="detail-type"]')).toBeVisible(); // 检查操作按钮 await expect(page.locator('[data-testid="edit-permission"]')).toBeVisible(); await expect( page.locator('[data-testid="delete-permission"]'), ).toBeVisible(); }); test('应该能编辑权限信息', async ({ page }) => { // 点击刚创建的权限节点 const testPermissionNode = page .locator('.ant-tree-node-content-wrapper') .filter({ hasText: TEST_PERMISSION.name }); await testPermissionNode.click(); // 点击编辑按钮 await page.click('[data-testid="edit-permission"]'); // 等待编辑弹窗出现 await expect(page.locator('.ant-modal')).toBeVisible(); await expect(page.locator('.ant-modal-title')).toContainText( /编辑权限|修改权限/, ); // 修改描述 const newDescription = '已修改的测试权限描述'; await page.fill('[data-testid="form-description"]', newDescription); // 提交修改 await page.click('[data-testid="form-submit"]'); // 等待成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); // 验证修改是否生效 await testPermissionNode.click(); await expect( page.locator('[data-testid="detail-description"]'), ).toContainText(newDescription); }); test('权限搜索功能应该正常工作', async ({ page }) => { // 输入搜索关键词 await page.fill('[data-testid="permission-search"]', TEST_PERMISSION.name); // 等待搜索结果 await page.waitForTimeout(1000); // 检查搜索结果 const visibleNodes = page.locator('.ant-tree-node-content-wrapper:visible'); const searchResults = visibleNodes.filter({ hasText: TEST_PERMISSION.name, }); await expect(searchResults).toHaveCount({ min: 1 }); // 清空搜索 await page.fill('[data-testid="permission-search"]', ''); await page.waitForTimeout(1000); // 检查是否显示所有权限 expect(await visibleNodes.count()).toBeGreaterThan(1); }); test('应该能删除权限', async ({ page }) => { // 点击要删除的权限节点 const testPermissionNode = page .locator('.ant-tree-node-content-wrapper') .filter({ hasText: TEST_PERMISSION.name }); await testPermissionNode.click(); // 点击删除按钮 await page.click('[data-testid="delete-permission"]'); // 确认删除 await expect(page.locator('.ant-modal-confirm')).toBeVisible(); await page.click('.ant-btn-primary'); // 等待删除成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); // 验证权限已被删除 await expect(testPermissionNode).not.toBeVisible(); }); }); test.describe('角色管理功能测试', () => { test.beforeEach(async ({ page }) => { await page.goto(TEST_CONFIG.baseURL); await loginAsSuperAdmin(page); // 导航到角色管理页面 await page.click('[data-testid="menu-system"]'); await page.click('[data-testid="menu-role-management"]'); await page.waitForURL(/\/system\/role/); }); test('应该正确显示角色管理页面', async ({ page }) => { // 检查页面标题 await expect(page.locator('.page-title')).toContainText( /角色管理|Role Management/, ); // 检查搜索表单 await expect(page.locator('[data-testid="search-name"]')).toBeVisible(); await expect(page.locator('[data-testid="search-status"]')).toBeVisible(); await expect(page.locator('[data-testid="search-button"]')).toBeVisible(); // 检查操作按钮 await expect(page.locator('[data-testid="add-role-button"]')).toBeVisible(); await expect( page.locator('[data-testid="batch-delete-button"]'), ).toBeVisible(); // 检查角色列表表格 await expect(page.locator('.ant-table')).toBeVisible(); }); test('应该能创建新角色', async ({ page }) => { // 点击添加角色按钮 await page.click('[data-testid="add-role-button"]'); // 等待创建弹窗出现 await expect(page.locator('.ant-modal')).toBeVisible(); await expect(page.locator('.ant-modal-title')).toContainText( /添加角色|新增角色/, ); // 填写角色信息 await page.fill('[data-testid="form-name"]', TEST_ROLE.name); await page.fill('[data-testid="form-code"]', TEST_ROLE.code); await page.fill('[data-testid="form-description"]', TEST_ROLE.description); await page.selectOption('[data-testid="form-status"]', TEST_ROLE.status); await page.fill('[data-testid="form-level"]', TEST_ROLE.level.toString()); // 提交表单 await page.click('[data-testid="form-submit"]'); // 等待成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); // 在列表中搜索新创建的角色 await page.fill('[data-testid="search-name"]', TEST_ROLE.name); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); const roleRow = page .locator('.ant-table-tbody tr') .filter({ hasText: TEST_ROLE.name }); await expect(roleRow).toBeVisible(); }); test('角色权限分配应该正常工作', async ({ page }) => { // 搜索刚创建的角色 await page.fill('[data-testid="search-name"]', TEST_ROLE.name); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); // 点击权限分配按钮 const assignButton = page .locator('.ant-table-tbody tr') .filter({ hasText: TEST_ROLE.name }) .locator('[data-testid="assign-permissions"]'); await assignButton.click(); // 等待权限分配弹窗出现 await expect(page.locator('.ant-modal')).toBeVisible(); await expect(page.locator('.ant-modal-title')).toContainText( /权限分配|分配权限/, ); // 检查权限树 await expect(page.locator('.permission-tree')).toBeVisible(); // 选择一些权限 const permissionCheckboxes = page.locator('.ant-tree-checkbox'); await permissionCheckboxes.nth(0).click(); await permissionCheckboxes.nth(1).click(); // 保存权限分配 await page.click('[data-testid="save-permissions"]'); // 等待成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); }); test('角色状态切换应该正常工作', async ({ page }) => { // 搜索角色 await page.fill('[data-testid="search-name"]', TEST_ROLE.name); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); const roleRow = page .locator('.ant-table-tbody tr') .filter({ hasText: TEST_ROLE.name }); // 点击状态切换开关 const statusSwitch = roleRow.locator('[data-testid="status-switch"]'); await statusSwitch.click(); // 确认状态变更 await page.click('[data-testid="confirm-status-change"]'); // 等待成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); }); test('角色复制功能应该正常工作', async ({ page }) => { // 搜索角色 await page.fill('[data-testid="search-name"]', TEST_ROLE.name); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); // 点击复制按钮 const copyButton = page .locator('.ant-table-tbody tr') .filter({ hasText: TEST_ROLE.name }) .locator('[data-testid="copy-role"]'); await copyButton.click(); // 等待复制弹窗 await expect(page.locator('.ant-modal')).toBeVisible(); await expect(page.locator('.ant-modal-title')).toContainText( /复制角色|克隆角色/, ); // 修改角色名称和编码 const newName = '复制的测试角色_' + Date.now(); const newCode = 'copied_role_' + Date.now(); await page.fill('[data-testid="form-name"]', newName); await page.fill('[data-testid="form-code"]', newCode); // 确认复制 await page.click('[data-testid="form-submit"]'); // 等待成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); // 验证复制的角色出现在列表中 await page.fill('[data-testid="search-name"]', newName); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); await expect( page.locator('.ant-table-tbody tr').filter({ hasText: newName }), ).toBeVisible(); }); test('应该能删除角色', async ({ page }) => { // 搜索要删除的角色 await page.fill('[data-testid="search-name"]', TEST_ROLE.name); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); // 点击删除按钮 const deleteButton = page .locator('.ant-table-tbody tr') .filter({ hasText: TEST_ROLE.name }) .locator('[data-testid="delete-button"]'); await deleteButton.click(); // 确认删除 await expect(page.locator('.ant-modal-confirm')).toBeVisible(); await page.click('.ant-btn-primary'); // 等待删除成功消息 await expect(page.locator('.ant-message-success')).toBeVisible(); // 验证角色已被删除 await page.reload(); await page.fill('[data-testid="search-name"]', TEST_ROLE.name); await page.click('[data-testid="search-button"]'); await page.waitForTimeout(1000); await expect(page.locator('.ant-empty')).toBeVisible(); }); }); test.describe('权限验证功能测试', () => { test('路由权限验证应该正常工作', async ({ page }) => { // 使用普通用户登录 await page.goto(TEST_CONFIG.baseURL); await loginAsTestUser(page); // 尝试访问系统管理页面(假设普通用户没有权限) await page.goto(`${TEST_CONFIG.baseURL}/system/permission`); // 应该显示403错误页面或被重定向 await expect(page.locator('.ant-result-403, .error-403')).toBeVisible(); // 或者检查是否被重定向到无权限页面 await expect(page.url()).toMatch(/\/403|\/unauthorized/); }); test('菜单权限过滤应该正常工作', async ({ page }) => { await page.goto(TEST_CONFIG.baseURL); await loginAsTestUser(page); // 检查系统管理菜单是否被隐藏 await expect(page.locator('[data-testid="menu-system"]')).not.toBeVisible(); // 检查用户有权限的菜单是否显示 await expect(page.locator('[data-testid="menu-dashboard"]')).toBeVisible(); await expect(page.locator('[data-testid="menu-account"]')).toBeVisible(); }); test('按钮权限控制应该正常工作', async ({ page }) => { await page.goto(TEST_CONFIG.baseURL); await loginAsTestUser(page); // 访问账号列表页面 await page.goto(`${TEST_CONFIG.baseURL}/account/list`); // 检查删除按钮是否被隐藏(假设普通用户没有删除权限) await expect( page.locator('[data-testid="delete-button"]'), ).not.toBeVisible(); // 但查看按钮应该可见 await expect(page.locator('[data-testid="view-button"]')).toBeVisible(); }); test('API权限验证应该正常工作', async ({ page }) => { await page.goto(TEST_CONFIG.baseURL); await loginAsTestUser(page); // 监听网络请求 page.on('response', async (response) => { if ( response.url().includes('/api/system/permission') && response.request().method() === 'POST' ) { // 检查是否返回403权限不足错误 expect(response.status()).toBe(403); } }); // 尝试通过开发者工具发送受限API请求 await page.evaluate(() => { fetch('/api/system/permission', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${localStorage.getItem('access_token')}`, }, body: JSON.stringify({ name: 'test', code: 'test' }), }); }); // 等待请求完成 await page.waitForTimeout(2000); }); test('权限缓存和实时更新应该正常工作', async ({ page }) => { // 使用超级管理员登录 await page.goto(TEST_CONFIG.baseURL); await loginAsSuperAdmin(page); // 创建一个测试用户并分配有限权限 await page.click('[data-testid="menu-system"]'); await page.click('[data-testid="menu-user-management"]'); // 找到测试用户并修改其权限 const testUserRow = page .locator('.ant-table-tbody tr') .filter({ hasText: TEST_CONFIG.testUser.username }); if ((await testUserRow.count()) > 0) { await testUserRow.locator('[data-testid="assign-role"]').click(); // 分配新的角色权限 await page.check('[data-testid="role-admin"]'); await page.click('[data-testid="save-user-roles"]'); await expect(page.locator('.ant-message-success')).toBeVisible(); } // 切换到测试用户账号(模拟用户刷新或重新登录) await page.click('[data-testid="user-dropdown"]'); await page.click('[data-testid="logout-button"]'); await loginAsTestUser(page); // 检查权限是否已更新 await expect(page.locator('[data-testid="menu-system"]')).toBeVisible(); }); test('权限指令v-permission应该正常工作', async ({ page }) => { await page.goto(TEST_CONFIG.baseURL); await loginAsTestUser(page); // 访问有使用v-permission指令的页面 await page.goto(`${TEST_CONFIG.baseURL}/account/list`); // 检查使用v-permission指令的元素是否按权限显示/隐藏 const createButton = page.locator('[v-permission="account:create"]'); const viewButton = page.locator('[v-permission="account:view"]'); if ((await createButton.count()) > 0) { // 如果用户没有创建权限,按钮应该被隐藏 await expect(createButton).not.toBeVisible(); } if ((await viewButton.count()) > 0) { // 如果用户有查看权限,按钮应该可见 await expect(viewButton).toBeVisible(); } }); }); // 辅助函数:超级管理员登录 async function loginAsSuperAdmin(page: Page) { await page.fill( '[data-testid="username-input"]', TEST_CONFIG.superAdmin.username, ); await page.fill( '[data-testid="password-input"]', TEST_CONFIG.superAdmin.password, ); await page.click('[data-testid="login-button"]'); await page.waitForURL(/\/dashboard/, { timeout: 10000 }); } // 辅助函数:测试用户登录 async function loginAsTestUser(page: Page) { await page.fill( '[data-testid="username-input"]', TEST_CONFIG.testUser.username, ); await page.fill( '[data-testid="password-input"]', TEST_CONFIG.testUser.password, ); await page.click('[data-testid="login-button"]'); await page.waitForURL(/\/dashboard/, { timeout: 10000 }); }