feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
import { Page, expect } from '@playwright/test';
|
||||
import { BasePage } from './base-page';
|
||||
import { testLogger } from '../core/test-logger';
|
||||
|
||||
export class LoginPage extends BasePage {
|
||||
private readonly selectors = {
|
||||
usernameInput: '[data-testid="username-input"]',
|
||||
passwordInput: '[data-testid="password-input"]',
|
||||
loginButton: '[data-testid="login-button"]',
|
||||
errorMessage: '.ant-message-error',
|
||||
successMessage: '.ant-message-success',
|
||||
loginForm: '[data-testid="login-form"]',
|
||||
rememberMeCheckbox: '[data-testid="remember-checkbox"]',
|
||||
forgotPasswordLink: 'text=忘记密码',
|
||||
registerLink: 'text=注册账号'
|
||||
};
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
async navigate(): Promise<void> {
|
||||
testLogger.info('导航到登录页面');
|
||||
await super.navigate('/login');
|
||||
}
|
||||
|
||||
async waitForLoad(): Promise<void> {
|
||||
testLogger.debug('等待登录页面加载完成');
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
this.waitForElement(this.selectors.usernameInput),
|
||||
this.waitForElement(this.selectors.passwordInput),
|
||||
this.waitForElement(this.selectors.loginButton)
|
||||
]);
|
||||
|
||||
testLogger.info('登录页面加载完成');
|
||||
} catch (error) {
|
||||
testLogger.error('登录页面加载失败', error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getUsernameInput() {
|
||||
return this.page.locator(this.selectors.usernameInput);
|
||||
}
|
||||
|
||||
async getPasswordInput() {
|
||||
return this.page.locator(this.selectors.passwordInput);
|
||||
}
|
||||
|
||||
async getLoginButton() {
|
||||
return this.page.locator(this.selectors.loginButton);
|
||||
}
|
||||
|
||||
async getErrorMessage() {
|
||||
return this.page.locator(this.selectors.errorMessage);
|
||||
}
|
||||
|
||||
async getSuccessMessage() {
|
||||
return this.page.locator(this.selectors.successMessage);
|
||||
}
|
||||
|
||||
async fillUsername(username: string): Promise<void> {
|
||||
testLogger.info(`填写用户名: ${username}`);
|
||||
await this.fill(this.selectors.usernameInput, username);
|
||||
}
|
||||
|
||||
async fillPassword(password: string): Promise<void> {
|
||||
testLogger.info('填写密码');
|
||||
await this.fill(this.selectors.passwordInput, password);
|
||||
}
|
||||
|
||||
async clickLoginButton(): Promise<void> {
|
||||
testLogger.info('点击登录按钮');
|
||||
await this.click(this.selectors.loginButton);
|
||||
}
|
||||
|
||||
async toggleRememberMe(remember: boolean): Promise<void> {
|
||||
testLogger.info(`设置记住密码: ${remember}`);
|
||||
|
||||
if (remember) {
|
||||
await this.check(this.selectors.rememberMeCheckbox);
|
||||
} else {
|
||||
await this.uncheck(this.selectors.rememberMeCheckbox);
|
||||
}
|
||||
}
|
||||
|
||||
async login(username: string, password: string, rememberMe: boolean = false): Promise<void> {
|
||||
testLogger.startStep('用户登录');
|
||||
|
||||
try {
|
||||
await this.waitForLoad();
|
||||
await this.fillUsername(username);
|
||||
await this.fillPassword(password);
|
||||
|
||||
if (rememberMe) {
|
||||
await this.toggleRememberMe(true);
|
||||
}
|
||||
|
||||
await this.clickLoginButton();
|
||||
|
||||
testLogger.endStep('用户登录', 'passed');
|
||||
} catch (error) {
|
||||
testLogger.endStep('用户登录', 'failed', error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async loginAndWaitForDashboard(username: string, password: string, rememberMe: boolean = false): Promise<void> {
|
||||
testLogger.startStep('登录并等待跳转到仪表盘');
|
||||
|
||||
try {
|
||||
await this.login(username, password, rememberMe);
|
||||
|
||||
await this.waitForURL(/.*dashboard/, this.timeout.navigation);
|
||||
|
||||
testLogger.endStep('登录并等待跳转到仪表盘', 'passed');
|
||||
} catch (error) {
|
||||
testLogger.endStep('登录并等待跳转到仪表盘', 'failed', error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async expectErrorMessage(message: string): Promise<void> {
|
||||
testLogger.debug(`期望错误消息: ${message}`);
|
||||
|
||||
const errorLocator = this.getErrorMessage();
|
||||
await expect(errorLocator).toBeVisible({ timeout: 5000 });
|
||||
await expect(errorLocator).toContainText(message);
|
||||
}
|
||||
|
||||
async expectSuccessMessage(message: string): Promise<void> {
|
||||
testLogger.debug(`期望成功消息: ${message}`);
|
||||
|
||||
const successLocator = this.getSuccessMessage();
|
||||
await expect(successLocator).toBeVisible({ timeout: 5000 });
|
||||
await expect(successLocator).toContainText(message);
|
||||
}
|
||||
|
||||
async hasErrorMessage(): Promise<boolean> {
|
||||
const errorLocator = this.getErrorMessage();
|
||||
const count = await errorLocator.count();
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
async hasSuccessMessage(): Promise<boolean> {
|
||||
const successLocator = this.getSuccessMessage();
|
||||
const count = await successLocator.count();
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
async getErrorMessageText(): Promise<string> {
|
||||
const errorLocator = this.getErrorMessage();
|
||||
const text = await errorLocator.textContent();
|
||||
return text || '';
|
||||
}
|
||||
|
||||
async getSuccessMessageText(): Promise<string> {
|
||||
const successLocator = this.getSuccessMessage();
|
||||
const text = await successLocator.textContent();
|
||||
return text || '';
|
||||
}
|
||||
|
||||
async isLoginButtonEnabled(): Promise<boolean> {
|
||||
const loginButton = this.getLoginButton();
|
||||
return await loginButton.isEnabled();
|
||||
}
|
||||
|
||||
async isUsernameInputVisible(): Promise<boolean> {
|
||||
return await this.isVisible(this.selectors.usernameInput);
|
||||
}
|
||||
|
||||
async isPasswordInputVisible(): Promise<boolean> {
|
||||
return await this.isVisible(this.selectors.passwordInput);
|
||||
}
|
||||
|
||||
async isLoginFormVisible(): Promise<boolean> {
|
||||
return await this.isVisible(this.selectors.loginForm);
|
||||
}
|
||||
|
||||
async clearUsername(): Promise<void> {
|
||||
testLogger.info('清空用户名输入框');
|
||||
const usernameInput = this.getUsernameInput();
|
||||
await usernameInput.fill('');
|
||||
}
|
||||
|
||||
async clearPassword(): Promise<void> {
|
||||
testLogger.info('清空密码输入框');
|
||||
const passwordInput = this.getPasswordInput();
|
||||
await passwordInput.fill('');
|
||||
}
|
||||
|
||||
async clearAllFields(): Promise<void> {
|
||||
await this.clearUsername();
|
||||
await this.clearPassword();
|
||||
}
|
||||
|
||||
async clickForgotPassword(): Promise<void> {
|
||||
testLogger.info('点击忘记密码链接');
|
||||
await this.click(this.selectors.forgotPasswordLink);
|
||||
}
|
||||
|
||||
async clickRegister(): Promise<void> {
|
||||
testLogger.info('点击注册账号链接');
|
||||
await this.click(this.selectors.registerLink);
|
||||
}
|
||||
|
||||
async pressEnter(): Promise<void> {
|
||||
testLogger.info('按Enter键提交登录');
|
||||
await this.page.keyboard.press('Enter');
|
||||
}
|
||||
|
||||
async loginWithEnter(username: string, password: string): Promise<void> {
|
||||
testLogger.startStep('使用Enter键登录');
|
||||
|
||||
try {
|
||||
await this.waitForLoad();
|
||||
await this.fillUsername(username);
|
||||
await this.fillPassword(password);
|
||||
await this.pressEnter();
|
||||
|
||||
testLogger.endStep('使用Enter键登录', 'passed');
|
||||
} catch (error) {
|
||||
testLogger.endStep('使用Enter键登录', 'failed', error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async takeScreenshotOnLogin(name: string = 'login-page'): Promise<string> {
|
||||
return await this.takeScreenshot(name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user