08ea5fbe98
添加用户管理视图、API和状态管理文件
132 lines
3.7 KiB
TypeScript
132 lines
3.7 KiB
TypeScript
import { Page, expect } from '@playwright/test';
|
|
import { TestLogger } from '../core/test-logger.js';
|
|
|
|
/**
|
|
* 登录页面对象
|
|
* 封装登录页面的所有操作
|
|
*/
|
|
export class LoginPage {
|
|
private page: Page;
|
|
private testLogger: TestLogger;
|
|
private baseUrl: string;
|
|
|
|
// 选择器
|
|
private readonly usernameInput = 'input[placeholder="请输入用户名"]';
|
|
private readonly passwordInput = 'input[placeholder="请输入密码"]';
|
|
private readonly loginButton = 'button:has-text("登录")';
|
|
private readonly alertSelector = '[role="alert"]';
|
|
|
|
constructor(page: Page, testLogger: TestLogger, baseUrl: string = 'http://localhost:5174') {
|
|
this.page = page;
|
|
this.testLogger = testLogger;
|
|
this.baseUrl = baseUrl;
|
|
}
|
|
|
|
/**
|
|
* 导航到登录页面
|
|
*/
|
|
async navigate(): Promise<void> {
|
|
this.testLogger.info('🌐 导航到登录页面');
|
|
await this.page.goto(`${this.baseUrl}/login`);
|
|
await this.page.waitForLoadState('networkidle');
|
|
this.testLogger.success('登录页面已加载');
|
|
}
|
|
|
|
/**
|
|
* 填写用户名
|
|
*/
|
|
async fillUsername(username: string): Promise<void> {
|
|
this.testLogger.info(`📝 填写用户名: ${username}`);
|
|
await this.page.fill(this.usernameInput, username);
|
|
this.testLogger.success('用户名填写完成');
|
|
}
|
|
|
|
/**
|
|
* 填写密码
|
|
*/
|
|
async fillPassword(password: string): Promise<void> {
|
|
this.testLogger.info('📝 填写密码');
|
|
await this.page.fill(this.passwordInput, password);
|
|
this.testLogger.success('密码填写完成');
|
|
}
|
|
|
|
/**
|
|
* 点击登录按钮
|
|
*/
|
|
async clickLoginButton(): Promise<void> {
|
|
this.testLogger.info('🖱️ 点击登录按钮');
|
|
await this.page.click(this.loginButton);
|
|
this.testLogger.success('登录按钮已点击');
|
|
}
|
|
|
|
/**
|
|
* 执行完整登录流程
|
|
*/
|
|
async login(username: string, password: string): Promise<void> {
|
|
this.testLogger.startStep('用户登录流程');
|
|
|
|
await this.fillUsername(username);
|
|
await this.fillPassword(password);
|
|
await this.clickLoginButton();
|
|
|
|
this.testLogger.endStep('用户登录流程', 'passed');
|
|
}
|
|
|
|
/**
|
|
* 等待登录成功(跳转到仪表盘)
|
|
*/
|
|
async waitForLoginSuccess(timeout: number = 10000): Promise<void> {
|
|
this.testLogger.info('⏳ 等待登录成功');
|
|
await this.page.waitForURL('**/dashboard', { timeout });
|
|
this.testLogger.success('登录成功,已跳转到仪表盘');
|
|
}
|
|
|
|
/**
|
|
* 等待错误提示
|
|
*/
|
|
async waitForError(timeout: number = 5000): Promise<string> {
|
|
this.testLogger.info('⏳ 等待错误提示');
|
|
const alert = this.page.locator(this.alertSelector);
|
|
await alert.waitFor({ state: 'visible', timeout });
|
|
const errorText = await alert.textContent() || '';
|
|
this.testLogger.info(`错误提示: ${errorText}`);
|
|
return errorText;
|
|
}
|
|
|
|
/**
|
|
* 验证登录表单存在
|
|
*/
|
|
async verifyLoginFormExists(): Promise<boolean> {
|
|
const usernameExists = await this.page.locator(this.usernameInput).count() > 0;
|
|
const passwordExists = await this.page.locator(this.passwordInput).count() > 0;
|
|
const buttonExists = await this.page.locator(this.loginButton).count() > 0;
|
|
|
|
return usernameExists && passwordExists && buttonExists;
|
|
}
|
|
|
|
/**
|
|
* 验证当前在登录页面
|
|
*/
|
|
async verifyOnLoginPage(): Promise<boolean> {
|
|
const url = this.page.url();
|
|
return url.includes('/login');
|
|
}
|
|
|
|
/**
|
|
* 清除表单
|
|
*/
|
|
async clearForm(): Promise<void> {
|
|
this.testLogger.info('🧹 清除登录表单');
|
|
await this.page.fill(this.usernameInput, '');
|
|
await this.page.fill(this.passwordInput, '');
|
|
this.testLogger.success('表单已清除');
|
|
}
|
|
|
|
/**
|
|
* 获取页面标题
|
|
*/
|
|
async getPageTitle(): Promise<string> {
|
|
return await this.page.title();
|
|
}
|
|
}
|