import { Page, expect } from '@playwright/test';
/**
* LoginPage - Page Object Model for OrangeHRM login page
* Encapsulates all interactions with the login page
*/
export class LoginPage {
readonly page: Page;
readonly loginUrl = 'https://opensource-demo.orangehrmlive.com/web/index.php/auth/login';
// Selectors
readonly usernameInput = 'input[name="username"]';
readonly passwordInput = 'input[name="password"]';
readonly loginButton = 'button[type="submit"]';
readonly dashboardHeader = '.oxd-topbar'; // Element that appears after successful login
constructor(page: Page) {
this.page = page;
}
/**
* Navigate to the OrangeHRM login page
*/
async navigateToLogin(): Promise<void> {
console.log(`Navigating to ${this.loginUrl}`);
await this.page.goto(this.loginUrl, { waitUntil: 'networkidle' });
}
/**
* Enter username in the username field
* @param username - The username to enter (e.g., "Admin")
*/
async enterUsername(username: string): Promise<void> {
console.log(`Entering username: ${username}`);
await this.page.fill(this.usernameInput, username);
}
/**
* Enter password in the password field
* @param password - The password to enter (e.g., "admin123")
*/
async enterPassword(password: string): Promise<void> {
console.log(`Entering password`);
await this.page.fill(this.passwordInput, password);
}
/**
* Click the login button
* Note: Does NOT wait for successful navigation (dashboard may not appear with invalid credentials)
*/
async clickLogin(): Promise<void> {
console.log('Clicking login button');
await this.page.click(this.loginButton, { timeout: 5000 });
// Don't wait for dashboard here - let the caller decide
// This allows tests to handle both successful logins and failed attempts
}
/**
* Click login button and wait for successful navigation (dashboard appears)
* Use this when you expect login to succeed
*/
async clickLoginAndWait(): Promise<void> {
await this.clickLogin();
// Wait for navigation to complete (wait for dashboard header to appear)
await this.page.waitForSelector(this.dashboardHeader, { timeout: 10000 });
}
/**
* Take a screenshot of the current page
* @param fileName - The filename for the screenshot (without path; saved to test-results folder)
*/
async takeScreenshot(fileName: string): Promise<void> {
const filePath = `test-results/${fileName}`;
console.log(`Taking screenshot: ${filePath}`);
await this.page.screenshot({ path: filePath, fullPage: true });
}
/**
* Verify that login was successful by checking for dashboard header
*/
async verifyLoginSuccess(): Promise<void> {
console.log('Verifying login was successful');
await expect(this.page.locator(this.dashboardHeader)).toBeVisible({ timeout: 10000 });
}
/**
* Get the current page title
*/
async getPageTitle(): Promise<string> {
return await this.page.title();
}
}