Files
everything-is-suitable/everything-is-suitable-test/e2e/tdd/auth-tdd.spec.ts
T
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

269 lines
8.4 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/login-page.js';
import { TestLogger } from '../core/test-logger.js';
/**
* TDD: 用户认证模块测试
*
* 测试策略:
* 1. 正常流程测试 - 验证正确的登录流程
* 2. 边界条件测试 - 验证空值、格式错误等边界情况
* 3. 错误处理测试 - 验证错误凭证、服务器错误等情况
*
* 目标覆盖率: 90%+
*/
test.describe('TDD: 用户认证 - 正常流程', () => {
let loginPage: LoginPage;
let testLogger: TestLogger;
test.beforeEach(async ({ page }) => {
testLogger = new TestLogger();
loginPage = new LoginPage(page, testLogger);
await loginPage.navigate();
});
test('应该成功登录并跳转到仪表盘 [正常流程]', async ({ page }) => {
// Given: 用户在登录页面
await expect(loginPage.verifyOnLoginPage()).resolves.toBe(true);
// When: 输入正确的用户名和密码
await loginPage.login('admin', 'admin123456');
// Then: 应该跳转到仪表盘
await loginPage.waitForLoginSuccess();
expect(page.url()).toContain('dashboard');
});
test('应该保持登录状态在页面刷新后 [正常流程]', async ({ page }) => {
// Given: 用户已登录
await loginPage.login('admin', 'admin123456');
await loginPage.waitForLoginSuccess();
// When: 刷新页面
await page.reload();
await page.waitForLoadState('networkidle');
// Then: 应该仍在仪表盘页面
expect(page.url()).toContain('dashboard');
});
});
test.describe('TDD: 用户认证 - 边界条件', () => {
let loginPage: LoginPage;
let testLogger: TestLogger;
test.beforeEach(async ({ page }) => {
testLogger = new TestLogger();
loginPage = new LoginPage(page, testLogger);
await loginPage.navigate();
});
test('应该拒绝空用户名 [边界条件]', async () => {
// Given: 用户名为空
await loginPage.fillPassword('admin123456');
// When: 点击登录
await loginPage.clickLoginButton();
// Then: 应该显示验证错误
const isOnLoginPage = await loginPage.verifyOnLoginPage();
expect(isOnLoginPage).toBe(true);
});
test('应该拒绝空密码 [边界条件]', async () => {
// Given: 密码为空
await loginPage.fillUsername('admin');
// When: 点击登录
await loginPage.clickLoginButton();
// Then: 应该显示验证错误
const isOnLoginPage = await loginPage.verifyOnLoginPage();
expect(isOnLoginPage).toBe(true);
});
test('应该拒绝超长用户名 [边界条件]', async () => {
// Given: 超长用户名(超过50个字符)
const longUsername = 'a'.repeat(51);
await loginPage.fillUsername(longUsername);
await loginPage.fillPassword('admin123456');
// When: 点击登录
await loginPage.clickLoginButton();
// Then: 应该显示错误
await expect(loginPage.waitForError()).resolves.toBeTruthy();
});
test('应该拒绝特殊字符用户名 [边界条件]', async () => {
// Given: 包含特殊字符的用户名
await loginPage.fillUsername('admin<script>alert(1)</script>');
await loginPage.fillPassword('admin123456');
// When: 点击登录
await loginPage.clickLoginButton();
// Then: 应该显示错误
await expect(loginPage.waitForError()).resolves.toBeTruthy();
});
});
test.describe('TDD: 用户认证 - 错误处理', () => {
let loginPage: LoginPage;
let testLogger: TestLogger;
test.beforeEach(async ({ page }) => {
testLogger = new TestLogger();
loginPage = new LoginPage(page, testLogger);
await loginPage.navigate();
});
test('应该拒绝错误的用户名 [错误处理]', async () => {
// Given: 错误的用户名
await loginPage.login('wronguser', 'admin123456');
// Then: 应该显示错误提示
const errorText = await loginPage.waitForError();
expect(errorText).toContain('用户名或密码错误');
// And: 仍在登录页面
expect(await loginPage.verifyOnLoginPage()).toBe(true);
});
test('应该拒绝错误的密码 [错误处理]', async () => {
// Given: 错误的密码
await loginPage.login('admin', 'wrongpassword');
// Then: 应该显示错误提示
const errorText = await loginPage.waitForError();
expect(errorText).toContain('用户名或密码错误');
// And: 仍在登录页面
expect(await loginPage.verifyOnLoginPage()).toBe(true);
});
test('应该拒绝错误的用户名和密码组合 [错误处理]', async () => {
// Given: 错误的用户名和密码
await loginPage.login('wronguser', 'wrongpassword');
// Then: 应该显示错误提示
const errorText = await loginPage.waitForError();
expect(errorText).toContain('用户名或密码错误');
});
test('应该处理多次登录失败 [错误处理]', async () => {
// Given: 连续3次登录失败
for (let i = 0; i < 3; i++) {
await loginPage.login('admin', 'wrongpassword');
await loginPage.waitForError();
await loginPage.clearForm();
}
// When: 第4次使用正确密码
await loginPage.login('admin', 'admin123456');
// Then: 应该成功登录
await loginPage.waitForLoginSuccess();
expect(loginPage.verifyOnLoginPage()).resolves.toBe(false);
});
});
test.describe('TDD: 用户认证 - 登出功能', () => {
let loginPage: LoginPage;
let testLogger: TestLogger;
test.beforeEach(async ({ page }) => {
testLogger = new TestLogger();
loginPage = new LoginPage(page, testLogger);
// 先登录
await loginPage.navigate();
await loginPage.login('admin', 'admin123456');
await loginPage.waitForLoginSuccess();
});
test('应该成功登出并返回登录页面 [正常流程]', async ({ page }) => {
// When: 点击用户菜单并选择退出
await page.click('.user-dropdown, .el-dropdown');
await page.waitForTimeout(500);
await page.click('text=退出登录');
// Then: 应该返回登录页面
await page.waitForURL('**/login', { timeout: 10000 });
expect(page.url()).toContain('login');
// And: 登录表单应该可见
expect(await loginPage.verifyLoginFormExists()).toBe(true);
});
test('应该清除登录状态在登出后 [正常流程]', async ({ page }) => {
// Given: 用户已登出
await page.click('.user-dropdown, .el-dropdown');
await page.waitForTimeout(500);
await page.click('text=退出登录');
await page.waitForURL('**/login', { timeout: 10000 });
// When: 直接访问仪表盘
await page.goto('http://localhost:5174/dashboard');
// Then: 应该被重定向到登录页面
await page.waitForTimeout(2000);
expect(page.url()).toContain('login');
});
});
test.describe('TDD: 用户认证 - 权限验证', () => {
let loginPage: LoginPage;
let testLogger: TestLogger;
test.beforeEach(async ({ page }) => {
testLogger = new TestLogger();
loginPage = new LoginPage(page, testLogger);
// 先登录
await loginPage.navigate();
await loginPage.login('admin', 'admin123456');
await loginPage.waitForLoginSuccess();
});
test('应该能够访问用户管理页面 [权限验证]', async ({ page }) => {
// When: 访问用户管理页面
await page.goto('http://localhost:5174/sys/user');
await page.waitForLoadState('networkidle');
// Then: 应该成功加载页面
expect(page.url()).toContain('/sys/user');
// And: 页面应该包含用户管理相关内容
const pageContent = await page.textContent('body');
expect(pageContent).toMatch(/用户|管理/);
});
test('应该能够访问角色管理页面 [权限验证]', async ({ page }) => {
// When: 访问角色管理页面
await page.goto('http://localhost:5174/sys/role');
await page.waitForLoadState('networkidle');
// Then: 应该成功加载页面
expect(page.url()).toContain('/sys/role');
// And: 页面应该包含角色管理相关内容
const pageContent = await page.textContent('body');
expect(pageContent).toMatch(/角色|管理/);
});
test('应该能够访问菜单管理页面 [权限验证]', async ({ page }) => {
// When: 访问菜单管理页面
await page.goto('http://localhost:5174/sys/menu');
await page.waitForLoadState('networkidle');
// Then: 应该成功加载页面
expect(page.url()).toContain('/sys/menu');
// And: 页面应该包含菜单管理相关内容
const pageContent = await page.textContent('body');
expect(pageContent).toMatch(/菜单|管理/);
});
});