trip-planner/tests/support/pages/LoginPage.js

140 lines
4.1 KiB
JavaScript
Raw Normal View History

2025-09-27 00:23:19 +02:00
const BasePage = require('./BasePage');
class LoginPage extends BasePage {
constructor(driver) {
super(driver);
// Selectors based on the LoginForm component
this.selectors = {
form: '.login-form',
heading: '.login-form h2',
emailInput: '#email',
passwordInput: '#password',
submitButton: 'button[type="submit"]',
errorMessage: '.error-message',
generalError: '.alert-error',
fieldError: '.error-message'
};
}
async navigateToLogin() {
await this.navigateTo('/');
// Click the Login tab if not already active
const loginButton = await this.driver.findElement({ css: '.auth-toggle button:first-child' });
await loginButton.click();
await this.waitForLoginForm();
}
async waitForLoginForm() {
await this.utils.waitForElementVisible(this.selectors.form);
}
async isLoginFormDisplayed() {
return await this.isElementVisible(this.selectors.form);
}
async getLoginHeading() {
return await this.getElementText(this.selectors.heading);
}
async enterEmail(email) {
await this.typeIntoElement(this.selectors.emailInput, email);
}
async enterPassword(password) {
await this.typeIntoElement(this.selectors.passwordInput, password);
}
async clickSubmit() {
await this.clickElement(this.selectors.submitButton);
}
async getSubmitButtonText() {
return await this.getElementText(this.selectors.submitButton);
}
async isSubmitButtonDisabled() {
const button = await this.utils.waitForElement(this.selectors.submitButton);
return await button.getAttribute('disabled') !== null;
}
async login(email, password) {
await this.enterEmail(email);
await this.enterPassword(password);
await this.clickSubmit();
}
async getGeneralErrorMessage() {
try {
return await this.getElementText(this.selectors.generalError);
} catch (error) {
return null;
}
}
async getEmailErrorMessage() {
try {
const emailField = await this.utils.waitForElement(this.selectors.emailInput);
const parent = await emailField.findElement({ xpath: '..' });
const errorElement = await parent.findElement({ css: this.selectors.fieldError });
return await errorElement.getText();
} catch (error) {
return null;
}
}
async getPasswordErrorMessage() {
try {
const passwordField = await this.utils.waitForElement(this.selectors.passwordInput);
const parent = await passwordField.findElement({ xpath: '..' });
const errorElement = await parent.findElement({ css: this.selectors.fieldError });
return await errorElement.getText();
} catch (error) {
return null;
}
}
async hasEmailFieldError() {
const emailField = await this.utils.waitForElement(this.selectors.emailInput);
const className = await emailField.getAttribute('class');
return className.includes('error');
}
async hasPasswordFieldError() {
const passwordField = await this.utils.waitForElement(this.selectors.passwordInput);
const className = await passwordField.getAttribute('class');
return className.includes('error');
}
async waitForSuccessfulLogin() {
// Wait for dashboard to appear (auth guard passes)
await this.driver.wait(
async () => {
try {
const dashboard = await this.driver.findElement({ css: '.dashboard' });
return await dashboard.isDisplayed();
} catch (error) {
return false;
}
},
10000,
'Login did not show dashboard within expected time'
);
}
async waitForLoginError() {
// Wait for either general error or field errors to appear
await this.driver.wait(
async () => {
const hasGeneralError = await this.isElementVisible(this.selectors.generalError);
const hasEmailError = await this.hasEmailFieldError();
const hasPasswordError = await this.hasPasswordFieldError();
return hasGeneralError || hasEmailError || hasPasswordError;
},
10000,
'No error message appeared within expected time'
);
}
}
module.exports = LoginPage;