feat(admin): 添加用户管理相关文件

添加用户管理视图、API和状态管理文件
This commit is contained in:
张翔
2026-03-28 14:37:29 +08:00
commit 08ea5fbe98
1643 changed files with 255646 additions and 0 deletions
@@ -0,0 +1,131 @@
/**
* Dashboard页面E2E测试
*
* 测试仪表盘页面的所有功能和交互
*
* @tags @dashboard @e2e @view
*/
import { test, expect } from '@playwright/test';
import { TestLogger } from '../core/test-logger.js';
test.describe('E2E: Dashboard页面', () => {
let logger: TestLogger;
test.beforeEach(async ({ page }) => {
logger = new TestLogger();
// 先登录
await page.goto('http://localhost:5174/login');
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
await page.click('button:has-text("登录")');
await page.waitForURL('**/dashboard');
});
test('应该显示仪表盘内容 @smoke', async ({ page }) => {
// Then: 应该显示仪表盘元素
await expect(page.locator('.dashboard')).toBeVisible();
await expect(page.locator('.el-header')).toBeVisible();
await expect(page.locator('.el-aside')).toBeVisible();
});
test('应该显示侧边栏菜单 @smoke', async ({ page }) => {
// Then: 应该显示菜单项
await expect(page.locator('.el-menu')).toBeVisible();
// 验证主要菜单项存在
const menuItems = ['系统管理', '用户管理', '角色管理', '菜单管理'];
for (const item of menuItems) {
await expect(page.locator(`.el-menu-item:has-text("${item}")`)).toBeVisible();
}
});
test('应该能够导航到用户管理页面 @regression', async ({ page }) => {
// When: 点击用户管理菜单
await page.click('.el-menu-item:has-text("用户管理")');
// Then: 应该导航到用户管理页面
await page.waitForURL('**/user-management');
await expect(page).toHaveURL(/.*user-management/);
});
test('应该能够导航到角色管理页面 @regression', async ({ page }) => {
// When: 点击角色管理菜单
await page.click('.el-menu-item:has-text("角色管理")');
// Then: 应该导航到角色管理页面
await page.waitForURL('**/role-management');
await expect(page).toHaveURL(/.*role-management/);
});
test('应该能够导航到菜单管理页面 @regression', async ({ page }) => {
// When: 点击菜单管理菜单
await page.click('.el-menu-item:has-text("菜单管理")');
// Then: 应该导航到菜单管理页面
await page.waitForURL('**/menu-management');
await expect(page).toHaveURL(/.*menu-management/);
});
test('应该显示用户信息 @regression', async ({ page }) => {
// Then: 应该显示用户头像或用户名
const avatarVisible = await page.locator('.el-avatar').isVisible().catch(() => false);
const usernameVisible = await page.locator('.username').isVisible().catch(() => false);
const headerVisible = await page.locator('.el-header').isVisible().catch(() => false);
// 至少有一个元素可见
expect(avatarVisible || usernameVisible || headerVisible).toBe(true);
});
test('应该能够展开/收起侧边栏 @regression', async ({ page }) => {
// Given: 侧边栏是展开的
const aside = page.locator('.el-aside');
const initialWidth = await aside.boundingBox().then(box => box?.width || 200);
// When: 点击收起按钮(如果存在)
const collapseBtn = page.locator('.collapse-btn, .hamburger');
if (await collapseBtn.isVisible().catch(() => false)) {
await collapseBtn.click();
// Then: 侧边栏应该收起
const collapsedWidth = await aside.boundingBox().then(box => box?.width || 64);
expect(collapsedWidth).toBeLessThan(initialWidth);
}
});
test('应该能够退出登录 @critical', async ({ page }) => {
// When: 点击用户头像或退出按钮
const userMenu = page.locator('.el-avatar, .user-menu').first();
if (await userMenu.isVisible()) {
await userMenu.click();
// 点击退出登录
const logoutBtn = page.locator('.el-dropdown-menu__item:has-text("退出"), button:has-text("退出")');
if (await logoutBtn.isVisible().catch(() => false)) {
await logoutBtn.click();
// Then: 应该跳转到登录页面
await page.waitForURL('**/login');
await expect(page).toHaveURL(/.*login/);
}
}
});
test('应该在不同视口下正常显示 @responsive', async ({ page }) => {
// Given: 不同视口尺寸
const viewports = [
{ width: 1920, height: 1080, name: 'desktop' },
{ width: 1366, height: 768, name: 'laptop' },
{ width: 768, height: 1024, name: 'tablet' }
];
for (const viewport of viewports) {
await page.setViewportSize({ width: viewport.width, height: viewport.height });
await page.goto('http://localhost:5174/dashboard');
// Then: 仪表盘应该可见
await expect(page.locator('.dashboard')).toBeVisible();
await expect(page.locator('.el-header')).toBeVisible();
}
});
});
@@ -0,0 +1,100 @@
/**
* Login页面E2E测试
*
* 测试登录页面的所有功能和交互
*
* @tags @login @auth @e2e @view
*/
import { test, expect } from '@playwright/test';
import { TestLogger } from '../core/test-logger.js';
test.describe('E2E: Login页面', () => {
let logger: TestLogger;
test.beforeEach(async ({ page }) => {
logger = new TestLogger();
await page.goto('http://localhost:5174/login');
await page.waitForLoadState('networkidle');
});
test('应该显示登录表单 @smoke', async ({ page }) => {
// Then: 应该显示登录表单元素
await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible();
await expect(page.locator('input[placeholder="请输入密码"]')).toBeVisible();
await expect(page.locator('button:has-text("登录")')).toBeVisible();
});
test('应该能够成功登录 @critical', async ({ page }) => {
// Given: 输入有效的登录凭据
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
// When: 点击登录按钮
await page.click('button:has-text("登录")');
// Then: 应该跳转到仪表盘
await page.waitForURL('**/dashboard');
await expect(page).toHaveURL(/.*dashboard/);
});
test('应该显示错误消息当凭据无效 @regression', async ({ page }) => {
// Given: 输入无效的登录凭据
await page.fill('input[placeholder="请输入用户名"]', 'invalid');
await page.fill('input[placeholder="请输入密码"]', 'wrongpassword');
// When: 点击登录按钮
await page.click('button:has-text("登录")');
// Then: 应该显示错误消息
await expect(page.locator('.el-message--error')).toBeVisible();
});
test('应该验证必填字段 @regression', async ({ page }) => {
// When: 直接点击登录按钮(不输入任何内容)
await page.click('button:has-text("登录")');
// Then: 应该显示验证错误
await expect(page.locator('.el-form-item__error')).toBeVisible();
});
test('应该记住用户名当勾选记住我 @regression', async ({ page, context }) => {
// Given: 输入凭据并勾选记住我
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
// 勾选记住我(如果存在)
const rememberMe = page.locator('input[type="checkbox"]').first();
if (await rememberMe.isVisible().catch(() => false)) {
await rememberMe.check();
}
// When: 登录
await page.click('button:has-text("登录")');
await page.waitForURL('**/dashboard');
// Then: 重新打开登录页面应该记住用户名
await page.goto('http://localhost:5174/login');
const usernameInput = page.locator('input[placeholder="请输入用户名"]');
await expect(usernameInput).toHaveValue('admin');
});
test('应该在不同视口下正常显示 @responsive', async ({ page }) => {
// Given: 不同视口尺寸
const viewports = [
{ width: 1920, height: 1080, name: 'desktop' },
{ width: 1366, height: 768, name: 'laptop' },
{ width: 768, height: 1024, name: 'tablet' },
{ width: 375, height: 667, name: 'mobile' }
];
for (const viewport of viewports) {
await page.setViewportSize({ width: viewport.width, height: viewport.height });
await page.goto('http://localhost:5174/login');
// Then: 登录表单应该可见
await expect(page.locator('input[placeholder="请输入用户名"]')).toBeVisible();
await expect(page.locator('input[placeholder="请输入密码"]')).toBeVisible();
}
});
});
@@ -0,0 +1,99 @@
/**
* MenuManagement页面E2E测试
*
* 测试菜单管理页面的所有功能和交互
*
* @tags @menu-management @e2e @view
*/
import { test, expect } from '@playwright/test';
import { TestLogger } from '../core/test-logger.js';
test.describe('E2E: MenuManagement页面', () => {
let logger: TestLogger;
test.beforeEach(async ({ page }) => {
logger = new TestLogger();
// 先登录
await page.goto('http://localhost:5174/login');
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
await page.click('button:has-text("登录")');
await page.waitForURL('**/dashboard');
// 导航到菜单管理页面
await page.click('.el-menu-item:has-text("菜单管理")');
await page.waitForURL('**/menu-management');
});
test('应该显示菜单管理页面 @smoke', async ({ page }) => {
await expect(page.locator('.menu-management, .el-tree')).toBeVisible();
});
test('应该显示菜单树 @smoke', async ({ page }) => {
await expect(page.locator('.el-tree-node')).toHaveCount.greaterThan(0);
});
test('应该能够展开/收起菜单节点 @regression', async ({ page }) => {
const expandIcon = page.locator('.el-tree-node__expand-icon').first();
if (await expandIcon.isVisible()) {
await expandIcon.click();
await page.waitForTimeout(300);
// 验证子节点显示
await expect(page.locator('.el-tree-node__children')).toBeVisible();
}
});
test('应该能够打开新增菜单对话框 @critical', async ({ page }) => {
const addBtn = page.locator('button:has-text("新增"), .add-btn').first();
await addBtn.click();
await expect(page.locator('.el-dialog:has-text("新增菜单")')).toBeVisible();
});
test('应该能够创建新菜单 @critical', async ({ page }) => {
const addBtn = page.locator('button:has-text("新增"), .add-btn').first();
await addBtn.click();
await page.fill('.el-dialog input[placeholder*="菜单名称"]', '测试菜单');
await page.fill('.el-dialog input[placeholder*="路由路径"]', '/test');
const submitBtn = page.locator('.el-dialog button:has-text("确定")').first();
await submitBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
});
test('应该能够编辑菜单 @critical', async ({ page }) => {
const editBtn = page.locator('.el-tree-node .el-button:has-text("编辑"), .el-tree-node .edit-btn').first();
if (await editBtn.isVisible()) {
await editBtn.click();
await expect(page.locator('.el-dialog:has-text("编辑菜单")')).toBeVisible();
const nameInput = page.locator('.el-dialog input[placeholder*="菜单名称"]').first();
await nameInput.clear();
await nameInput.fill('更新菜单');
const submitBtn = page.locator('.el-dialog button:has-text("确定")').first();
await submitBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够删除菜单 @critical', async ({ page }) => {
const deleteBtn = page.locator('.el-tree-node .el-button:has-text("删除"), .el-tree-node .delete-btn').first();
if (await deleteBtn.isVisible()) {
await deleteBtn.click();
await expect(page.locator('.el-message-box:has-text("确认删除")')).toBeVisible();
const confirmBtn = page.locator('.el-message-box button:has-text("确定")').first();
await confirmBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够拖拽排序菜单 @regression', async ({ page }) => {
const dragNode = page.locator('.el-tree-node__content').first();
const targetNode = page.locator('.el-tree-node__content').nth(1);
if (await dragNode.isVisible() && await targetNode.isVisible()) {
await dragNode.dragTo(targetNode);
await page.waitForTimeout(500);
// 验证排序成功
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
});
@@ -0,0 +1,101 @@
/**
* OperationLogManagement页面E2E测试
*
* 测试操作日志管理页面的所有功能和交互
*
* @tags @operation-log @e2e @view
*/
import { test, expect } from '@playwright/test';
import { TestLogger } from '../core/test-logger.js';
test.describe('E2E: OperationLogManagement页面', () => {
let logger: TestLogger;
test.beforeEach(async ({ page }) => {
logger = new TestLogger();
// 先登录
await page.goto('http://localhost:5174/login');
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
await page.click('button:has-text("登录")');
await page.waitForURL('**/dashboard');
// 导航到操作日志页面
await page.click('.el-menu-item:has-text("操作日志")');
await page.waitForURL('**/operation-log');
});
test('应该显示操作日志页面 @smoke', async ({ page }) => {
await expect(page.locator('.operation-log, .el-table')).toBeVisible();
await expect(page.locator('.el-pagination')).toBeVisible();
});
test('应该显示日志列表 @smoke', async ({ page }) => {
await expect(page.locator('.el-table__row')).toHaveCount.greaterThan(0);
const headers = ['操作人', '操作类型', '操作内容', '操作时间', 'IP地址'];
for (const header of headers) {
await expect(page.locator(`.el-table__header:has-text("${header}")`)).toBeVisible();
}
});
test('应该能够搜索日志 @regression', async ({ page }) => {
const searchInput = page.locator('.search-input, input[placeholder*="搜索"]').first();
if (await searchInput.isVisible()) {
await searchInput.fill('admin');
await searchInput.press('Enter');
await page.waitForTimeout(500);
await expect(page.locator('.el-table__row')).toBeVisible();
}
});
test('应该能够按日期筛选 @regression', async ({ page }) => {
const datePicker = page.locator('.el-date-picker, .date-range-picker').first();
if (await datePicker.isVisible()) {
await datePicker.click();
// 选择日期范围
const startDate = page.locator('.el-picker-panel .available').first();
await startDate.click();
const endDate = page.locator('.el-picker-panel .available').nth(5);
await endDate.click();
await page.waitForTimeout(500);
await expect(page.locator('.el-table__row')).toBeVisible();
}
});
test('应该能够查看日志详情 @regression', async ({ page }) => {
const detailBtn = page.locator('.el-table__row .el-button:has-text("详情"), .el-table__row .detail-btn').first();
if (await detailBtn.isVisible()) {
await detailBtn.click();
await expect(page.locator('.el-dialog:has-text("日志详情")')).toBeVisible();
await expect(page.locator('.el-dialog .detail-content')).toBeVisible();
}
});
test('应该能够导出日志 @regression', async ({ page }) => {
const exportBtn = page.locator('button:has-text("导出"), .export-btn').first();
if (await exportBtn.isVisible()) {
await exportBtn.click();
// 验证导出成功提示
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够分页 @regression', async ({ page }) => {
const nextBtn = page.locator('.el-pagination .btn-next').first();
if (await nextBtn.isVisible() && await nextBtn.isEnabled()) {
await nextBtn.click();
await page.waitForTimeout(500);
await expect(page.locator('.el-table__row')).toBeVisible();
}
});
test('应该能够清空筛选条件 @regression', async ({ page }) => {
const resetBtn = page.locator('button:has-text("重置"), .reset-btn').first();
if (await resetBtn.isVisible()) {
await resetBtn.click();
await page.waitForTimeout(500);
await expect(page.locator('.el-table__row')).toBeVisible();
}
});
});
@@ -0,0 +1,94 @@
/**
* RoleManagement页面E2E测试
*
* 测试角色管理页面的所有功能和交互
*
* @tags @role-management @e2e @view
*/
import { test, expect } from '@playwright/test';
import { TestLogger } from '../core/test-logger.js';
test.describe('E2E: RoleManagement页面', () => {
let logger: TestLogger;
test.beforeEach(async ({ page }) => {
logger = new TestLogger();
// 先登录
await page.goto('http://localhost:5174/login');
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
await page.click('button:has-text("登录")');
await page.waitForURL('**/dashboard');
// 导航到角色管理页面
await page.click('.el-menu-item:has-text("角色管理")');
await page.waitForURL('**/role-management');
});
test('应该显示角色管理页面 @smoke', async ({ page }) => {
await expect(page.locator('.role-management, .el-table')).toBeVisible();
await expect(page.locator('.el-pagination')).toBeVisible();
});
test('应该显示角色列表 @smoke', async ({ page }) => {
await expect(page.locator('.el-table__row')).toHaveCount.greaterThan(0);
const headers = ['角色名称', '角色编码', '描述', '状态', '操作'];
for (const header of headers) {
await expect(page.locator(`.el-table__header:has-text("${header}")`)).toBeVisible();
}
});
test('应该能够打开新增角色对话框 @critical', async ({ page }) => {
const addBtn = page.locator('button:has-text("新增"), .add-btn').first();
await addBtn.click();
await expect(page.locator('.el-dialog:has-text("新增角色")')).toBeVisible();
});
test('应该能够创建新角色 @critical', async ({ page }) => {
const addBtn = page.locator('button:has-text("新增"), .add-btn').first();
await addBtn.click();
await page.fill('.el-dialog input[placeholder*="角色名称"]', '测试角色');
await page.fill('.el-dialog input[placeholder*="角色编码"]', 'test_role');
const submitBtn = page.locator('.el-dialog button:has-text("确定")').first();
await submitBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
});
test('应该能够编辑角色 @critical', async ({ page }) => {
const editBtn = page.locator('.el-table__row .el-button:has-text("编辑"), .el-table__row .edit-btn').first();
if (await editBtn.isVisible()) {
await editBtn.click();
await expect(page.locator('.el-dialog:has-text("编辑角色")')).toBeVisible();
const nameInput = page.locator('.el-dialog input[placeholder*="角色名称"]').first();
await nameInput.clear();
await nameInput.fill('更新角色');
const submitBtn = page.locator('.el-dialog button:has-text("确定")').first();
await submitBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够删除角色 @critical', async ({ page }) => {
const deleteBtn = page.locator('.el-table__row .el-button:has-text("删除"), .el-table__row .delete-btn').first();
if (await deleteBtn.isVisible()) {
await deleteBtn.click();
await expect(page.locator('.el-message-box:has-text("确认删除")')).toBeVisible();
const confirmBtn = page.locator('.el-message-box button:has-text("确定")').first();
await confirmBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够分配权限 @critical', async ({ page }) => {
const permissionBtn = page.locator('.el-table__row .el-button:has-text("权限"), .el-table__row .permission-btn').first();
if (await permissionBtn.isVisible()) {
await permissionBtn.click();
await expect(page.locator('.el-dialog:has-text("分配权限")')).toBeVisible();
await expect(page.locator('.el-tree')).toBeVisible();
const submitBtn = page.locator('.el-dialog button:has-text("确定")').first();
await submitBtn.click();
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
});
@@ -0,0 +1,193 @@
/**
* UserManagement页面E2E测试
*
* 测试用户管理页面的所有功能和交互
*
* @tags @user-management @e2e @view
*/
import { test, expect } from '@playwright/test';
import { TestLogger } from '../core/test-logger.js';
test.describe('E2E: UserManagement页面', () => {
let logger: TestLogger;
test.beforeEach(async ({ page }) => {
logger = new TestLogger();
// 先登录
await page.goto('http://localhost:5174/login');
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="请输入密码"]', 'admin123');
await page.click('button:has-text("登录")');
await page.waitForURL('**/dashboard');
// 导航到用户管理页面
await page.click('.el-menu-item:has-text("用户管理")');
await page.waitForURL('**/user-management');
});
test('应该显示用户管理页面 @smoke', async ({ page }) => {
// Then: 应该显示页面元素
await expect(page.locator('.user-management, .el-table')).toBeVisible();
await expect(page.locator('.el-pagination')).toBeVisible();
});
test('应该显示用户列表 @smoke', async ({ page }) => {
// Then: 应该显示用户数据表格
await expect(page.locator('.el-table__row')).toHaveCount.greaterThan(0);
// 验证表头
const headers = ['用户名', '邮箱', '手机号', '状态', '操作'];
for (const header of headers) {
await expect(page.locator(`.el-table__header:has-text("${header}")`)).toBeVisible();
}
});
test('应该能够搜索用户 @regression', async ({ page }) => {
// Given: 搜索关键词
const searchInput = page.locator('.search-input, input[placeholder*="搜索"]').first();
if (await searchInput.isVisible()) {
// When: 输入搜索关键词
await searchInput.fill('admin');
await searchInput.press('Enter');
// Then: 应该显示搜索结果
await page.waitForTimeout(500);
await expect(page.locator('.el-table__row')).toBeVisible();
}
});
test('应该能够打开新增用户对话框 @critical', async ({ page }) => {
// When: 点击新增按钮
const addBtn = page.locator('button:has-text("新增"), .add-btn').first();
await addBtn.click();
// Then: 应该显示新增对话框
await expect(page.locator('.el-dialog:has-text("新增用户")')).toBeVisible();
await expect(page.locator('.el-dialog input[placeholder*="用户名"]').first()).toBeVisible();
});
test('应该能够创建新用户 @critical', async ({ page }) => {
// When: 打开新增对话框
const addBtn = page.locator('button:has-text("新增"), .add-btn').first();
await addBtn.click();
// 填写表单
await page.fill('.el-dialog input[placeholder*="用户名"]', 'testuser');
await page.fill('.el-dialog input[placeholder*="邮箱"]', 'test@example.com');
await page.fill('.el-dialog input[placeholder*="手机号"]', '13800138000');
// 提交表单
const submitBtn = page.locator('.el-dialog button:has-text("确定"), .el-dialog .el-button--primary').first();
await submitBtn.click();
// Then: 应该显示成功消息
await expect(page.locator('.el-message--success')).toBeVisible();
});
test('应该能够编辑用户 @critical', async ({ page }) => {
// When: 点击编辑按钮
const editBtn = page.locator('.el-table__row .el-button:has-text("编辑"), .el-table__row .edit-btn').first();
if (await editBtn.isVisible()) {
await editBtn.click();
// Then: 应该显示编辑对话框
await expect(page.locator('.el-dialog:has-text("编辑用户")')).toBeVisible();
// 修改数据
const usernameInput = page.locator('.el-dialog input[placeholder*="用户名"]').first();
await usernameInput.clear();
await usernameInput.fill('updateduser');
// 提交
const submitBtn = page.locator('.el-dialog button:has-text("确定")').first();
await submitBtn.click();
// Then: 应该显示成功消息
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够删除用户 @critical', async ({ page }) => {
// When: 点击删除按钮
const deleteBtn = page.locator('.el-table__row .el-button:has-text("删除"), .el-table__row .delete-btn').first();
if (await deleteBtn.isVisible()) {
await deleteBtn.click();
// Then: 应该显示确认对话框
await expect(page.locator('.el-message-box:has-text("确认删除")')).toBeVisible();
// 确认删除
const confirmBtn = page.locator('.el-message-box button:has-text("确定")').first();
await confirmBtn.click();
// Then: 应该显示成功消息
await expect(page.locator('.el-message--success')).toBeVisible();
}
});
test('应该能够分页 @regression', async ({ page }) => {
// When: 点击下一页
const nextBtn = page.locator('.el-pagination .btn-next, .el-pagination button:has-text("下一页")').first();
if (await nextBtn.isVisible() && await nextBtn.isEnabled()) {
await nextBtn.click();
await page.waitForTimeout(500);
// Then: 应该显示不同数据
await expect(page.locator('.el-table__row')).toBeVisible();
}
});
test('应该能够重置搜索条件 @regression', async ({ page }) => {
// Given: 输入搜索条件
const searchInput = page.locator('.search-input, input[placeholder*="搜索"]').first();
if (await searchInput.isVisible()) {
await searchInput.fill('test');
// When: 点击重置按钮
const resetBtn = page.locator('button:has-text("重置"), .reset-btn').first();
if (await resetBtn.isVisible()) {
await resetBtn.click();
// Then: 搜索条件应该被清空
await expect(searchInput).toHaveValue('');
}
}
});
test('应该能够批量删除 @regression', async ({ page }) => {
// When: 选择多个用户
const checkboxes = page.locator('.el-table__row .el-checkbox__input').slice(0, 2);
for (const checkbox of await checkboxes.all()) {
await checkbox.click();
}
// 点击批量删除
const batchDeleteBtn = page.locator('button:has-text("批量删除")').first();
if (await batchDeleteBtn.isVisible()) {
await batchDeleteBtn.click();
// Then: 应该显示确认对话框
await expect(page.locator('.el-message-box:has-text("确认")')).toBeVisible();
}
});
test('应该在不同视口下正常显示 @responsive', async ({ page }) => {
// Given: 不同视口尺寸
const viewports = [
{ width: 1920, height: 1080, name: 'desktop' },
{ width: 1366, height: 768, name: 'laptop' },
{ width: 1024, height: 768, name: 'tablet' }
];
for (const viewport of viewports) {
await page.setViewportSize({ width: viewport.width, height: viewport.height });
await page.goto('http://localhost:5174/user-management');
await page.waitForTimeout(1000);
// Then: 用户列表应该可见
await expect(page.locator('.el-table')).toBeVisible();
}
});
});