upskill-event-manager/wordpress-dev/tests/e2e/pages/LoginPage.ts
bengizmo d1f1005a5a fix: Update login form selectors to match actual page structure
- Updated LoginPage selectors to use more robust input[name] selectors instead of id-based
- Added better error handling and message detection
- Enhanced form waiting for better reliability
- Created debug test scripts to verify selector functionality
- Fixed isLoginFormVisible reference in trainer journey test

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-21 20:21:16 -03:00

142 lines
No EOL
4.5 KiB
TypeScript

import { Page, expect } from '@playwright/test';
import { BasePage } from './BasePage';
import { PATHS } from '../config/staging-config';
/**
* Page object representing the login page
*/
export class LoginPage extends BasePage {
// Login form elements based on debug analysis
private readonly usernameInput = 'input[name="log"]';
private readonly passwordInput = 'input[name="pwd"]';
private readonly loginButton = 'input[type="submit"]';
private readonly rememberMeCheckbox = 'input[name="rememberme"]';
private readonly loginError = '.login-error, .login_error, #login_error, .notice-error, .woocommerce-error, .wp-die-message';
private readonly forgotPasswordLink = 'a:text("Lost your password?")';
private readonly loginForm = 'form#hvac_community_loginform';
constructor(page: Page) {
super(page);
}
/**
* Navigate to the login page
*/
async navigate(): Promise<void> {
this.log('Navigating to login page');
await this.page.goto(PATHS.login);
await this.page.waitForLoadState('networkidle');
// Make sure the form is visible before proceeding
await this.page.waitForSelector(this.loginForm, { timeout: 10000 });
}
/**
* Alternative name for navigate for backward compatibility
*/
async navigateToLogin(): Promise<void> {
await this.navigate();
}
/**
* Login with provided credentials
* @param username Username or email
* @param password Password
*/
async login(username: string, password: string): Promise<void> {
this.log(`Logging in as ${username}`);
// Wait for form elements to be ready
await this.page.waitForSelector(this.usernameInput, { state: 'visible', timeout: 10000 });
await this.page.waitForSelector(this.passwordInput, { state: 'visible', timeout: 5000 });
await this.page.waitForSelector(this.loginButton, { state: 'visible', timeout: 5000 });
// Fill in the credentials
await this.page.fill(this.usernameInput, username);
await this.page.fill(this.passwordInput, password);
// Click login and wait for navigation
await this.page.click(this.loginButton);
await this.page.waitForLoadState('networkidle');
this.log('Login form submitted');
}
/**
* Check if we're logged in
*/
async isLoggedIn(): Promise<boolean> {
await this.page.waitForLoadState('networkidle');
const url = await this.getUrl();
return url.includes('hvac-dashboard');
}
/**
* Check if username field is visible
*/
async isUsernameFieldVisible(): Promise<boolean> {
try {
await this.page.waitForSelector(this.usernameInput, { state: 'visible', timeout: 5000 });
return true;
} catch (error) {
return false;
}
}
/**
* Get error message if login failed
*/
async getErrorMessage(): Promise<string | null> {
// Check all possible error selectors
const errorSelectors = this.loginError.split(', ');
for (const selector of errorSelectors) {
if (await this.page.isVisible(selector)) {
return await this.page.textContent(selector);
}
}
// Check for any text containing common error messages
const pageContent = await this.page.content();
if (pageContent.includes('Invalid username') ||
pageContent.includes('incorrect password') ||
pageContent.includes('Unknown username') ||
pageContent.includes('Error:')) {
// Try to find error message in the page content
const errorText = await this.page.evaluate(() => {
const errorElements = Array.from(document.querySelectorAll('p, div, span'))
.filter(el => el.textContent &&
(el.textContent.includes('Invalid') ||
el.textContent.includes('Error') ||
el.textContent.includes('incorrect') ||
el.textContent.includes('Unknown')));
return errorElements.length > 0 ? errorElements[0].textContent : null;
});
return errorText;
}
return null;
}
/**
* Click on "forgot password" link
*/
async clickForgotPassword(): Promise<void> {
await this.page.click(this.forgotPasswordLink);
await this.page.waitForLoadState('networkidle');
}
/**
* Toggle "remember me" checkbox
* @param check If true, check the box; if false, uncheck it
*/
async setRememberMe(check: boolean): Promise<void> {
const isChecked = await this.page.isChecked(this.rememberMeCheckbox);
if (check !== isChecked) {
await this.page.click(this.rememberMeCheckbox);
}
}
}