08ea5fbe98
添加用户管理视图、API和状态管理文件
307 lines
11 KiB
TypeScript
307 lines
11 KiB
TypeScript
import { test, expect } from './test-fixtures.js';
|
|
|
|
/**
|
|
* 用户认证模块完整测试套件
|
|
* 采用TDD方法:Red -> Green -> Refactor
|
|
* 测试覆盖:登录、登出、Token刷新、权限验证
|
|
*/
|
|
|
|
test.describe('用户认证 - 登录功能', () => {
|
|
test.beforeEach(async ({ pageObjects, testLogger }) => {
|
|
testLogger.info('开始登录功能测试套件');
|
|
await pageObjects.loginPage.navigate();
|
|
});
|
|
|
|
test.afterEach(async ({ testLogger, helpers }) => {
|
|
testLogger.info('登录功能测试用例完成');
|
|
await helpers.screenshot.takeScreenshot('after-auth-test');
|
|
});
|
|
|
|
test('应该成功登录并跳转到仪表盘', async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.startTest('成功登录');
|
|
|
|
try {
|
|
await pageObjects.loginPage.login(testData.admin.username, testData.admin.password);
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
|
|
const pageTitle = await pageObjects.dashboardPage.getPageTitle();
|
|
expect(pageTitle).toContain('仪表盘');
|
|
|
|
testLogger.endTest('成功登录', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('成功登录', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该显示登录页面所有元素', async ({ pageObjects, testLogger }) => {
|
|
testLogger.startTest('登录页面元素验证');
|
|
|
|
try {
|
|
const isUsernameVisible = await pageObjects.loginPage.isUsernameInputVisible();
|
|
const isPasswordVisible = await pageObjects.loginPage.isPasswordInputVisible();
|
|
const isLoginFormVisible = await pageObjects.loginPage.isLoginFormVisible();
|
|
|
|
expect(isUsernameVisible).toBe(true);
|
|
expect(isPasswordVisible).toBe(true);
|
|
expect(isLoginFormVisible).toBe(true);
|
|
|
|
testLogger.endTest('登录页面元素验证', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('登录页面元素验证', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该验证用户名不能为空', async ({ pageObjects, testLogger }) => {
|
|
testLogger.startTest('用户名空值验证');
|
|
|
|
try {
|
|
await pageObjects.loginPage.clickLoginButton();
|
|
|
|
const hasError = await pageObjects.loginPage.hasErrorMessage();
|
|
expect(hasError).toBe(true);
|
|
|
|
testLogger.endTest('用户名空值验证', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('用户名空值验证', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该验证密码不能为空', async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.startTest('密码空值验证');
|
|
|
|
try {
|
|
await pageObjects.loginPage.fillUsername(testData.admin.username);
|
|
await pageObjects.loginPage.clickLoginButton();
|
|
|
|
const hasError = await pageObjects.loginPage.hasErrorMessage();
|
|
expect(hasError).toBe(true);
|
|
|
|
testLogger.endTest('密码空值验证', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('密码空值验证', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该拒绝错误的用户名', async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.startTest('错误用户名验证');
|
|
|
|
try {
|
|
await pageObjects.loginPage.login('wronguser', testData.admin.password);
|
|
|
|
const hasError = await pageObjects.loginPage.hasErrorMessage();
|
|
expect(hasError).toBe(true);
|
|
|
|
testLogger.endTest('错误用户名验证', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('错误用户名验证', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该拒绝错误的密码', async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.startTest('错误密码验证');
|
|
|
|
try {
|
|
await pageObjects.loginPage.login(testData.admin.username, 'wrongpassword');
|
|
|
|
const hasError = await pageObjects.loginPage.hasErrorMessage();
|
|
expect(hasError).toBe(true);
|
|
|
|
testLogger.endTest('错误密码验证', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('错误密码验证', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该支持使用Enter键登录', async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.startTest('Enter键登录');
|
|
|
|
try {
|
|
await pageObjects.loginPage.loginWithEnter(testData.admin.username, testData.admin.password);
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
|
|
const isDashboardVisible = await pageObjects.dashboardPage.isDashboardVisible();
|
|
expect(isDashboardVisible).toBe(true);
|
|
|
|
testLogger.endTest('Enter键登录', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('Enter键登录', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('用户认证 - 登出功能', () => {
|
|
test.beforeEach(async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.info('开始登出功能测试套件');
|
|
await pageObjects.loginPage.navigate();
|
|
await pageObjects.loginPage.login(testData.admin.username, testData.admin.password);
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
});
|
|
|
|
test('应该成功登出并返回登录页面', async ({ page, pageObjects, testLogger }) => {
|
|
testLogger.startTest('成功登出');
|
|
|
|
try {
|
|
// 点击用户下拉菜单
|
|
const dropdownTrigger = page.locator('.ant-dropdown-link');
|
|
await dropdownTrigger.click();
|
|
|
|
await page.waitForTimeout(500);
|
|
|
|
// 点击退出按钮
|
|
const logoutMenuItem = page.locator('.ant-dropdown-menu-item').filter({ hasText: /退出/i });
|
|
await logoutMenuItem.click();
|
|
|
|
// 等待跳转到登录页面
|
|
await page.waitForURL(/.*login/, { timeout: 10000 });
|
|
|
|
const isLoginFormVisible = await pageObjects.loginPage.isLoginFormVisible();
|
|
expect(isLoginFormVisible).toBe(true);
|
|
|
|
testLogger.endTest('成功登出', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('成功登出', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('用户认证 - Token管理', () => {
|
|
test.beforeEach(async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.info('开始Token管理测试套件');
|
|
await pageObjects.loginPage.navigate();
|
|
await pageObjects.loginPage.login(testData.admin.username, testData.admin.password);
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
});
|
|
|
|
test('应该保持登录状态在页面刷新后', async ({ page, pageObjects, testLogger }) => {
|
|
testLogger.startTest('刷新后保持登录');
|
|
|
|
try {
|
|
// 刷新页面
|
|
await page.reload();
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
|
|
const isDashboardVisible = await pageObjects.dashboardPage.isDashboardVisible();
|
|
expect(isDashboardVisible).toBe(true);
|
|
|
|
testLogger.endTest('刷新后保持登录', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('刷新后保持登录', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('用户认证 - 权限验证', () => {
|
|
test.beforeEach(async ({ pageObjects, testData, testLogger }) => {
|
|
testLogger.info('开始权限验证测试套件');
|
|
await pageObjects.loginPage.navigate();
|
|
await pageObjects.loginPage.login(testData.admin.username, testData.admin.password);
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
});
|
|
|
|
test('应该能够访问用户管理页面', async ({ pageObjects, testLogger }) => {
|
|
testLogger.startTest('访问用户管理');
|
|
|
|
try {
|
|
await pageObjects.userManagementPage.navigate();
|
|
await pageObjects.userManagementPage.waitForLoad();
|
|
|
|
const pageTitle = await pageObjects.userManagementPage.getPageTitle();
|
|
expect(pageTitle).toContain('用户');
|
|
|
|
testLogger.endTest('访问用户管理', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('访问用户管理', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该能够访问角色管理页面', async ({ pageObjects, testLogger }) => {
|
|
testLogger.startTest('访问角色管理');
|
|
|
|
try {
|
|
await pageObjects.roleManagementPage.navigate();
|
|
await pageObjects.roleManagementPage.waitForLoad();
|
|
|
|
const pageTitle = await pageObjects.roleManagementPage.getPageTitle();
|
|
expect(pageTitle).toContain('角色');
|
|
|
|
testLogger.endTest('访问角色管理', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('访问角色管理', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
test('应该能够访问菜单管理页面', async ({ pageObjects, testLogger }) => {
|
|
testLogger.startTest('访问菜单管理');
|
|
|
|
try {
|
|
await pageObjects.menuManagementPage.navigate();
|
|
await pageObjects.menuManagementPage.waitForLoad();
|
|
|
|
const pageTitle = await pageObjects.menuManagementPage.getPageTitle();
|
|
expect(pageTitle).toContain('菜单');
|
|
|
|
testLogger.endTest('访问菜单管理', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('访问菜单管理', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('用户认证 - 端到端流程', () => {
|
|
test('应该完成完整的登录-操作-登出流程', async ({ page, pageObjects, testData, testLogger, helpers }) => {
|
|
testLogger.startTest('完整认证流程');
|
|
|
|
try {
|
|
// 步骤1: 登录
|
|
testLogger.startStep('用户登录');
|
|
await pageObjects.loginPage.navigate();
|
|
await pageObjects.loginPage.login(testData.admin.username, testData.admin.password);
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
testLogger.endStep('用户登录', 'passed');
|
|
|
|
// 步骤2: 访问用户管理
|
|
testLogger.startStep('访问用户管理');
|
|
await pageObjects.userManagementPage.navigate();
|
|
await pageObjects.userManagementPage.waitForLoad();
|
|
testLogger.endStep('访问用户管理', 'passed');
|
|
|
|
// 步骤3: 返回仪表盘
|
|
testLogger.startStep('返回仪表盘');
|
|
await pageObjects.dashboardPage.navigate();
|
|
await pageObjects.dashboardPage.waitForLoad();
|
|
testLogger.endStep('返回仪表盘', 'passed');
|
|
|
|
// 步骤4: 登出
|
|
testLogger.startStep('用户登出');
|
|
const dropdownTrigger = page.locator('.ant-dropdown-link');
|
|
await dropdownTrigger.click();
|
|
await page.waitForTimeout(500);
|
|
const logoutMenuItem = page.locator('.ant-dropdown-menu-item').filter({ hasText: /退出/i });
|
|
await logoutMenuItem.click();
|
|
await page.waitForURL(/.*login/, { timeout: 10000 });
|
|
testLogger.endStep('用户登出', 'passed');
|
|
|
|
// 验证返回登录页面
|
|
const isLoginFormVisible = await pageObjects.loginPage.isLoginFormVisible();
|
|
expect(isLoginFormVisible).toBe(true);
|
|
|
|
testLogger.endTest('完整认证流程', 'passed');
|
|
} catch (error) {
|
|
testLogger.endTest('完整认证流程', 'failed', error as Error);
|
|
throw error;
|
|
}
|
|
});
|
|
});
|