feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,538 @@
|
||||
/**
|
||||
* 角色管理工作流实现
|
||||
* 实现角色管理相关的端到端业务流程
|
||||
*/
|
||||
|
||||
import { Page } from '@playwright/test';
|
||||
import { BusinessWorkflow } from '../core/business-workflows.js';
|
||||
import { TestLogger } from '../core/test-logger.js';
|
||||
import { TestDataManager, TestRole } from '../core/test-data-manager.js';
|
||||
import { LoginPage } from '../pages/login-page.js';
|
||||
import { RoleManagementPage } from '../pages/role-management-page.js';
|
||||
|
||||
export interface RoleWorkflowContext {
|
||||
page: Page;
|
||||
testLogger: TestLogger;
|
||||
testDataManager: TestDataManager;
|
||||
loginPage: LoginPage;
|
||||
roleManagementPage: RoleManagementPage;
|
||||
createdRole?: TestRole;
|
||||
createdRoleId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建角色工作流
|
||||
*/
|
||||
export function createRoleWorkflow(context: RoleWorkflowContext): BusinessWorkflow {
|
||||
const { page, testLogger, testDataManager, loginPage, roleManagementPage } = context;
|
||||
|
||||
return {
|
||||
name: 'createRole',
|
||||
description: '创建新角色的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件: 用户已登录');
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/roles')) {
|
||||
testLogger.info('用户未登录,执行登录');
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToRoleManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到角色管理页面');
|
||||
await roleManagementPage.navigate();
|
||||
await roleManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickAddRoleButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击新增角色按钮');
|
||||
await roleManagementPage.clickAddRole();
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'fillRoleForm',
|
||||
action: async () => {
|
||||
testLogger.info('📝 填写角色表单');
|
||||
context.createdRole = testDataManager.createTestRole();
|
||||
|
||||
await page.fill('input[name="name"]', context.createdRole.name);
|
||||
await page.fill('input[name="roleKey"]', context.createdRole.code);
|
||||
|
||||
if (context.createdRole.description) {
|
||||
await page.fill('textarea[name="description"]', context.createdRole.description);
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'submitRoleForm',
|
||||
action: async () => {
|
||||
testLogger.info('📤 提交角色表单');
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
await page.waitForSelector('.el-message--success', {
|
||||
state: 'visible',
|
||||
timeout: 10000
|
||||
});
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyRoleCreated',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证角色创建成功');
|
||||
|
||||
if (context.createdRole) {
|
||||
await roleManagementPage.searchRole(context.createdRole.name);
|
||||
const roleCount = await roleManagementPage.getRoleCount();
|
||||
if (roleCount === 0) {
|
||||
throw new Error('角色创建后未在列表中找到');
|
||||
}
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
}
|
||||
],
|
||||
|
||||
postconditions: async () => {
|
||||
testLogger.info('🔍 检查后置条件: 角色创建成功');
|
||||
return !!context.createdRole;
|
||||
},
|
||||
|
||||
cleanup: async () => {
|
||||
testLogger.info('🧹 执行清理操作');
|
||||
if (context.createdRole) {
|
||||
try {
|
||||
await roleManagementPage.searchRole(context.createdRole.name);
|
||||
const roleCount = await roleManagementPage.getRoleCount();
|
||||
if (roleCount > 0) {
|
||||
await roleManagementPage.clickDeleteRole(0);
|
||||
await roleManagementPage.confirmDelete();
|
||||
}
|
||||
} catch (error) {
|
||||
testLogger.warn('清理角色失败,可能角色不存在');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑角色工作流
|
||||
*/
|
||||
export function editRoleWorkflow(context: RoleWorkflowContext, targetRoleName?: string): BusinessWorkflow {
|
||||
const { page, testLogger, testDataManager, loginPage, roleManagementPage } = context;
|
||||
|
||||
return {
|
||||
name: 'editRole',
|
||||
description: '编辑角色的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件');
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/roles')) {
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToRoleManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到角色管理页面');
|
||||
await roleManagementPage.navigate();
|
||||
await roleManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'searchRole',
|
||||
action: async () => {
|
||||
testLogger.info('🔍 搜索目标角色');
|
||||
const searchRoleName = targetRoleName || context.createdRole?.name || 'admin';
|
||||
await roleManagementPage.searchRole(searchRoleName);
|
||||
|
||||
const roleCount = await roleManagementPage.getRoleCount();
|
||||
if (roleCount === 0) {
|
||||
throw new Error(`未找到角色: ${searchRoleName}`);
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickEditButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击编辑按钮');
|
||||
await roleManagementPage.clickEditRole(0);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'updateRoleForm',
|
||||
action: async () => {
|
||||
testLogger.info('📝 更新角色表单');
|
||||
|
||||
const newDescription = `Updated description ${Date.now()}`;
|
||||
await page.fill('textarea[name="description"]', newDescription);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'submitRoleForm',
|
||||
action: async () => {
|
||||
testLogger.info('📤 提交角色表单');
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
await page.waitForSelector('.el-message--success', {
|
||||
state: 'visible',
|
||||
timeout: 10000
|
||||
});
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyRoleUpdated',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证角色更新成功');
|
||||
|
||||
const successMessage = await roleManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('角色更新未显示成功消息');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色工作流
|
||||
*/
|
||||
export function deleteRoleWorkflow(context: RoleWorkflowContext, targetRoleName?: string): BusinessWorkflow {
|
||||
const { page, testLogger, roleManagementPage, loginPage } = context;
|
||||
|
||||
return {
|
||||
name: 'deleteRole',
|
||||
description: '删除角色的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件');
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/roles')) {
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToRoleManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到角色管理页面');
|
||||
await roleManagementPage.navigate();
|
||||
await roleManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'searchRole',
|
||||
action: async () => {
|
||||
testLogger.info('🔍 搜索目标角色');
|
||||
const searchRoleName = targetRoleName || context.createdRole?.name;
|
||||
if (!searchRoleName) {
|
||||
throw new Error('未指定要删除的角色');
|
||||
}
|
||||
await roleManagementPage.searchRole(searchRoleName);
|
||||
|
||||
const roleCount = await roleManagementPage.getRoleCount();
|
||||
if (roleCount === 0) {
|
||||
throw new Error(`未找到角色: ${searchRoleName}`);
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickDeleteButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击删除按钮');
|
||||
await roleManagementPage.clickDeleteRole(0);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'confirmDelete',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 确认删除');
|
||||
await roleManagementPage.confirmDelete();
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyRoleDeleted',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证角色删除成功');
|
||||
|
||||
const successMessage = await roleManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('角色删除未显示成功消息');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配权限工作流
|
||||
*/
|
||||
export function assignPermissionsWorkflow(context: RoleWorkflowContext, targetRoleName?: string): BusinessWorkflow {
|
||||
const { page, testLogger, roleManagementPage, loginPage } = context;
|
||||
|
||||
return {
|
||||
name: 'assignPermissions',
|
||||
description: '为角色分配权限的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件');
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/roles')) {
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToRoleManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到角色管理页面');
|
||||
await roleManagementPage.navigate();
|
||||
await roleManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'searchRole',
|
||||
action: async () => {
|
||||
testLogger.info('🔍 搜索目标角色');
|
||||
const searchRoleName = targetRoleName || context.createdRole?.name || 'admin';
|
||||
await roleManagementPage.searchRole(searchRoleName);
|
||||
|
||||
const roleCount = await roleManagementPage.getRoleCount();
|
||||
if (roleCount === 0) {
|
||||
throw new Error(`未找到角色: ${searchRoleName}`);
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickAssignPermissionsButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击分配权限按钮');
|
||||
await roleManagementPage.clickAssignPermissions(0);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'selectPermissions',
|
||||
action: async () => {
|
||||
testLogger.info('📝 选择权限');
|
||||
|
||||
// 等待权限树加载
|
||||
await page.waitForSelector('.el-tree', { timeout: 10000 });
|
||||
|
||||
// 选择一些权限节点(示例:选择第一个和第二个)
|
||||
const checkboxes = await page.locator('.el-tree-node__content .el-checkbox').all();
|
||||
if (checkboxes.length > 0) {
|
||||
await checkboxes[0].click();
|
||||
}
|
||||
if (checkboxes.length > 1) {
|
||||
await checkboxes[1].click();
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'savePermissions',
|
||||
action: async () => {
|
||||
testLogger.info('💾 保存权限设置');
|
||||
await page.click('button:has-text("确定")');
|
||||
|
||||
await page.waitForSelector('.el-message--success', {
|
||||
state: 'visible',
|
||||
timeout: 10000
|
||||
});
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyPermissionsAssigned',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证权限分配成功');
|
||||
|
||||
const successMessage = await roleManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('权限分配未显示成功消息');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色生命周期工作流
|
||||
*/
|
||||
export function roleLifecycleWorkflow(context: RoleWorkflowContext): BusinessWorkflow {
|
||||
const { testLogger, testDataManager } = context;
|
||||
let createdRoleName: string | undefined;
|
||||
|
||||
return {
|
||||
name: 'roleLifecycle',
|
||||
description: '角色从创建到删除的完整生命周期',
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'login',
|
||||
action: async () => {
|
||||
const loginWorkflow = createRoleWorkflow(context);
|
||||
if (loginWorkflow.preconditions) {
|
||||
await loginWorkflow.preconditions();
|
||||
}
|
||||
},
|
||||
timeout: 20000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'createRole',
|
||||
action: async () => {
|
||||
const createWorkflow = createRoleWorkflow(context);
|
||||
for (const step of createWorkflow.steps) {
|
||||
await step.action();
|
||||
}
|
||||
createdRoleName = context.createdRole?.name;
|
||||
},
|
||||
timeout: 60000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyRoleInList',
|
||||
action: async () => {
|
||||
if (!createdRoleName) {
|
||||
throw new Error('角色创建失败');
|
||||
}
|
||||
await context.roleManagementPage.searchRole(createdRoleName);
|
||||
const count = await context.roleManagementPage.getRoleCount();
|
||||
if (count === 0) {
|
||||
throw new Error('新创建的角色未在列表中');
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'assignPermissions',
|
||||
action: async () => {
|
||||
const permissionsWorkflow = assignPermissionsWorkflow(context, createdRoleName);
|
||||
for (const step of permissionsWorkflow.steps.slice(2)) {
|
||||
await step.action();
|
||||
}
|
||||
},
|
||||
timeout: 45000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'editRole',
|
||||
action: async () => {
|
||||
const editWorkflow = editRoleWorkflow(context, createdRoleName);
|
||||
for (const step of editWorkflow.steps.slice(2)) {
|
||||
await step.action();
|
||||
}
|
||||
},
|
||||
timeout: 45000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyRoleUpdated',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证角色更新成功');
|
||||
const successMessage = await context.roleManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('角色更新验证失败');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'deleteRole',
|
||||
action: async () => {
|
||||
const deleteWorkflow = deleteRoleWorkflow(context, createdRoleName);
|
||||
for (const step of deleteWorkflow.steps.slice(2)) {
|
||||
await step.action();
|
||||
}
|
||||
},
|
||||
timeout: 30000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyRoleDeleted',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证角色删除成功');
|
||||
if (!createdRoleName) return;
|
||||
|
||||
await context.roleManagementPage.searchRole(createdRoleName);
|
||||
const count = await context.roleManagementPage.getRoleCount();
|
||||
if (count > 0) {
|
||||
throw new Error('角色删除后仍存在于列表中');
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
/**
|
||||
* 用户管理工作流实现
|
||||
* 实现用户管理相关的端到端业务流程
|
||||
*/
|
||||
|
||||
import { Page } from '@playwright/test';
|
||||
import { BusinessWorkflow, WorkflowStep } from '../core/business-workflows.js';
|
||||
import { TestLogger } from '../core/test-logger.js';
|
||||
import { TestDataManager, TestUser } from '../core/test-data-manager.js';
|
||||
import { LoginPage } from '../pages/login-page.js';
|
||||
import { UserManagementPage } from '../pages/user-management-page.js';
|
||||
|
||||
export interface UserWorkflowContext {
|
||||
page: Page;
|
||||
testLogger: TestLogger;
|
||||
testDataManager: TestDataManager;
|
||||
loginPage: LoginPage;
|
||||
userManagementPage: UserManagementPage;
|
||||
createdUser?: TestUser;
|
||||
createdUserId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户工作流
|
||||
*/
|
||||
export function createUserWorkflow(context: UserWorkflowContext): BusinessWorkflow {
|
||||
const { page, testLogger, testDataManager, loginPage, userManagementPage } = context;
|
||||
|
||||
return {
|
||||
name: 'createUser',
|
||||
description: '创建新用户的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件: 用户已登录');
|
||||
// 检查是否已登录
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/users')) {
|
||||
testLogger.info('用户未登录,执行登录');
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToUserManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到用户管理页面');
|
||||
await userManagementPage.navigate();
|
||||
await userManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickAddUserButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击新增用户按钮');
|
||||
await userManagementPage.clickAddUser();
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'fillUserForm',
|
||||
action: async () => {
|
||||
testLogger.info('📝 填写用户表单');
|
||||
context.createdUser = testDataManager.createTestUser();
|
||||
|
||||
// 填写表单字段
|
||||
await page.fill('input[name="username"]', context.createdUser.username);
|
||||
await page.fill('input[name="password"]', context.createdUser.password);
|
||||
await page.fill('input[name="email"]', context.createdUser.email);
|
||||
|
||||
if (context.createdUser.phone) {
|
||||
await page.fill('input[name="phone"]', context.createdUser.phone);
|
||||
}
|
||||
if (context.createdUser.realName) {
|
||||
await page.fill('input[name="realName"]', context.createdUser.realName);
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'submitUserForm',
|
||||
action: async () => {
|
||||
testLogger.info('📤 提交用户表单');
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// 等待提交完成
|
||||
await page.waitForSelector('.ant-message-success', {
|
||||
state: 'visible',
|
||||
timeout: 10000
|
||||
});
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyUserCreated',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证用户创建成功');
|
||||
|
||||
// 搜索新创建的用户
|
||||
if (context.createdUser) {
|
||||
await userManagementPage.searchUser(context.createdUser.username);
|
||||
|
||||
// 验证用户出现在列表中
|
||||
const userCount = await userManagementPage.getUserCount();
|
||||
if (userCount === 0) {
|
||||
throw new Error('用户创建后未在列表中找到');
|
||||
}
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
}
|
||||
],
|
||||
|
||||
postconditions: async () => {
|
||||
testLogger.info('🔍 检查后置条件: 用户创建成功');
|
||||
return !!context.createdUser;
|
||||
},
|
||||
|
||||
cleanup: async () => {
|
||||
testLogger.info('🧹 执行清理操作');
|
||||
// 清理创建的用户
|
||||
if (context.createdUser) {
|
||||
try {
|
||||
await userManagementPage.searchUser(context.createdUser.username);
|
||||
// 如果找到用户,执行删除
|
||||
const userCount = await userManagementPage.getUserCount();
|
||||
if (userCount > 0) {
|
||||
await userManagementPage.clickDeleteUser(0);
|
||||
await userManagementPage.confirmDelete();
|
||||
}
|
||||
} catch (error) {
|
||||
testLogger.warn('清理用户失败,可能用户不存在');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户工作流
|
||||
*/
|
||||
export function editUserWorkflow(context: UserWorkflowContext, targetUsername?: string): BusinessWorkflow {
|
||||
const { page, testLogger, testDataManager, loginPage, userManagementPage } = context;
|
||||
|
||||
return {
|
||||
name: 'editUser',
|
||||
description: '编辑用户的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件');
|
||||
// 确保已登录
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/users')) {
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToUserManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到用户管理页面');
|
||||
await userManagementPage.navigate();
|
||||
await userManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'searchUser',
|
||||
action: async () => {
|
||||
testLogger.info('🔍 搜索目标用户');
|
||||
const searchUsername = targetUsername || context.createdUser?.username || 'admin';
|
||||
await userManagementPage.searchUser(searchUsername);
|
||||
|
||||
// 验证找到用户
|
||||
const userCount = await userManagementPage.getUserCount();
|
||||
if (userCount === 0) {
|
||||
throw new Error(`未找到用户: ${searchUsername}`);
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickEditButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击编辑按钮');
|
||||
await userManagementPage.clickEditUser(0);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'updateUserForm',
|
||||
action: async () => {
|
||||
testLogger.info('📝 更新用户表单');
|
||||
|
||||
// 更新邮箱
|
||||
const newEmail = testDataManager.generateEmail('updated');
|
||||
await page.fill('input[name="email"]', newEmail);
|
||||
|
||||
// 更新手机号
|
||||
const newPhone = testDataManager.generatePhone();
|
||||
await page.fill('input[name="phone"]', newPhone);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'submitUserForm',
|
||||
action: async () => {
|
||||
testLogger.info('📤 提交用户表单');
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// 等待提交完成
|
||||
await page.waitForSelector('.ant-message-success', {
|
||||
state: 'visible',
|
||||
timeout: 10000
|
||||
});
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyUserUpdated',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证用户更新成功');
|
||||
|
||||
// 验证成功消息
|
||||
const successMessage = await userManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('用户更新未显示成功消息');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户工作流
|
||||
*/
|
||||
export function deleteUserWorkflow(context: UserWorkflowContext, targetUsername?: string): BusinessWorkflow {
|
||||
const { page, testLogger, userManagementPage, loginPage } = context;
|
||||
|
||||
return {
|
||||
name: 'deleteUser',
|
||||
description: '删除用户的完整流程',
|
||||
|
||||
preconditions: async () => {
|
||||
testLogger.info('🔍 检查前置条件');
|
||||
const currentUrl = page.url();
|
||||
if (!currentUrl.includes('/dashboard') && !currentUrl.includes('/users')) {
|
||||
await loginPage.navigate();
|
||||
await loginPage.login('admin', 'admin123');
|
||||
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'navigateToUserManagement',
|
||||
action: async () => {
|
||||
testLogger.info('🌐 导航到用户管理页面');
|
||||
await userManagementPage.navigate();
|
||||
await userManagementPage.waitForLoad();
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'searchUser',
|
||||
action: async () => {
|
||||
testLogger.info('🔍 搜索目标用户');
|
||||
const searchUsername = targetUsername || context.createdUser?.username;
|
||||
if (!searchUsername) {
|
||||
throw new Error('未指定要删除的用户');
|
||||
}
|
||||
await userManagementPage.searchUser(searchUsername);
|
||||
|
||||
const userCount = await userManagementPage.getUserCount();
|
||||
if (userCount === 0) {
|
||||
throw new Error(`未找到用户: ${searchUsername}`);
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'clickDeleteButton',
|
||||
action: async () => {
|
||||
testLogger.info('🖱️ 点击删除按钮');
|
||||
await userManagementPage.clickDeleteUser(0);
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'confirmDelete',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 确认删除');
|
||||
await userManagementPage.confirmDelete();
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyUserDeleted',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证用户删除成功');
|
||||
|
||||
// 验证成功消息
|
||||
const successMessage = await userManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('用户删除未显示成功消息');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户生命周期工作流
|
||||
*/
|
||||
export function userLifecycleWorkflow(context: UserWorkflowContext): BusinessWorkflow {
|
||||
const { testLogger, testDataManager } = context;
|
||||
let createdUsername: string | undefined;
|
||||
|
||||
return {
|
||||
name: 'userLifecycle',
|
||||
description: '用户从创建到删除的完整生命周期',
|
||||
|
||||
steps: [
|
||||
{
|
||||
name: 'login',
|
||||
action: async () => {
|
||||
const loginWorkflow = createUserWorkflow(context);
|
||||
if (loginWorkflow.preconditions) {
|
||||
await loginWorkflow.preconditions();
|
||||
}
|
||||
},
|
||||
timeout: 20000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'createUser',
|
||||
action: async () => {
|
||||
const createWorkflow = createUserWorkflow(context);
|
||||
for (const step of createWorkflow.steps) {
|
||||
await step.action();
|
||||
}
|
||||
createdUsername = context.createdUser?.username;
|
||||
},
|
||||
timeout: 60000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyUserInList',
|
||||
action: async () => {
|
||||
if (!createdUsername) {
|
||||
throw new Error('用户创建失败');
|
||||
}
|
||||
await context.userManagementPage.searchUser(createdUsername);
|
||||
const count = await context.userManagementPage.getUserCount();
|
||||
if (count === 0) {
|
||||
throw new Error('新创建的用户未在列表中');
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'editUser',
|
||||
action: async () => {
|
||||
const editWorkflow = editUserWorkflow(context, createdUsername);
|
||||
for (const step of editWorkflow.steps.slice(2)) { // 跳过导航和搜索
|
||||
await step.action();
|
||||
}
|
||||
},
|
||||
timeout: 45000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyUserUpdated',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证用户更新成功');
|
||||
const successMessage = await context.userManagementPage.getSuccessMessage();
|
||||
if (!successMessage.includes('成功')) {
|
||||
throw new Error('用户更新验证失败');
|
||||
}
|
||||
},
|
||||
timeout: 10000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'deleteUser',
|
||||
action: async () => {
|
||||
const deleteWorkflow = deleteUserWorkflow(context, createdUsername);
|
||||
for (const step of deleteWorkflow.steps.slice(2)) { // 跳过导航和搜索
|
||||
await step.action();
|
||||
}
|
||||
},
|
||||
timeout: 30000,
|
||||
retryCount: 3
|
||||
},
|
||||
{
|
||||
name: 'verifyUserDeleted',
|
||||
action: async () => {
|
||||
testLogger.info('✅ 验证用户删除成功');
|
||||
if (!createdUsername) return;
|
||||
|
||||
await context.userManagementPage.searchUser(createdUsername);
|
||||
const count = await context.userManagementPage.getUserCount();
|
||||
if (count > 0) {
|
||||
throw new Error('用户删除后仍存在于列表中');
|
||||
}
|
||||
},
|
||||
timeout: 15000,
|
||||
retryCount: 3
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user