Files
你的用户名 237c7802e5
Some checks failed
Deploy / deploy (push) Has been cancelled
Initial commit: Telegram Management System
Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 15:37:50 +08:00

593 lines
19 KiB
TypeScript

/**
* 权限控制功能端到端测试
* 测试权限管理、角色管理、权限验证等功能
*/
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 });
}