diff --git a/wordpress-dev/tests/e2e/debug-login-page.spec.ts b/wordpress-dev/tests/e2e/debug-login-page.spec.ts new file mode 100644 index 00000000..514c36a9 --- /dev/null +++ b/wordpress-dev/tests/e2e/debug-login-page.spec.ts @@ -0,0 +1,113 @@ +import { test, expect } from '@playwright/test'; +import { STAGING_URL } from './config/staging-config'; + +test('Debug login page', async ({ page }) => { + console.log('Starting login page debug'); + + // Navigate to the login page + console.log('Navigating to login page...'); + await page.goto(`${STAGING_URL}/community-login/`, { waitUntil: 'networkidle' }); + console.log(`Current URL: ${page.url()}`); + + // Take screenshot of the page + await page.screenshot({ path: 'screenshots/login-page.png' }); + console.log('Screenshot saved to screenshots/login-page.png'); + + // Get page title + const title = await page.title(); + console.log(`Page title: ${title}`); + + // Check for redirects + if (!page.url().includes('community-login')) { + console.log(`⚠️ Page was redirected to: ${page.url()}`); + } + + // Check for iframes + const iframes = await page.$$('iframe'); + console.log(`Number of iframes: ${iframes.length}`); + + // Dump HTML content + const html = await page.content(); + console.log('First 500 chars of HTML:'); + console.log(html.substring(0, 500)); + + // Look for common login form elements with various selectors + const selectors = [ + '#user_login', + '#username', + 'input[name="log"]', + 'input[name="username"]', + '#user_pass', + '#password', + 'input[name="pwd"]', + 'input[name="password"]', + '#wp-submit', + 'input[type="submit"]', + 'button[type="submit"]' + ]; + + console.log('\nChecking for form elements:'); + for (const selector of selectors) { + const count = await page.$$eval(selector, (elements) => elements.length).catch(() => 0); + if (count > 0) { + console.log(`✅ Found ${count} elements matching selector: ${selector}`); + const element = await page.$(selector); + if (element) { + const tagName = await element.evaluate(el => el.tagName).catch(() => 'Unknown'); + const type = await element.evaluate(el => el.getAttribute('type')).catch(() => 'Unknown'); + const name = await element.evaluate(el => el.getAttribute('name')).catch(() => 'Unknown'); + const id = await element.evaluate(el => el.getAttribute('id')).catch(() => 'Unknown'); + console.log(` Tag: ${tagName}, Type: ${type}, Name: ${name}, ID: ${id}`); + } + } else { + console.log(`❌ No elements found for selector: ${selector}`); + } + } + + // Check for error containers + const errorSelectors = [ + '.login-error', + '#login_error', + '.login_error', + '.notice-error', + '.woocommerce-error', + '.wp-die-message' + ]; + + console.log('\nChecking for error containers:'); + for (const selector of errorSelectors) { + const count = await page.$$eval(selector, (elements) => elements.length).catch(() => 0); + console.log(`${selector}: ${count > 0 ? '✅ Found' : '❌ Not found'}`); + } + + // Output all forms on the page + const forms = await page.$$('form'); + console.log(`\nNumber of forms: ${forms.length}`); + + for (let i = 0; i < forms.length; i++) { + const form = forms[i]; + const action = await form.evaluate(f => f.getAttribute('action') || 'No action').catch(() => 'Unknown'); + const method = await form.evaluate(f => f.getAttribute('method') || 'No method').catch(() => 'Unknown'); + const id = await form.evaluate(f => f.getAttribute('id') || 'No id').catch(() => 'Unknown'); + const className = await form.evaluate(f => f.getAttribute('class') || 'No class').catch(() => 'Unknown'); + + console.log(`\nForm #${i+1}:`); + console.log(` ID: ${id}`); + console.log(` Class: ${className}`); + console.log(` Action: ${action}`); + console.log(` Method: ${method}`); + + // Get inputs in the form + const inputs = await form.$$('input'); + console.log(` Inputs: ${inputs.length}`); + + for (const input of inputs) { + const type = await input.evaluate(i => i.getAttribute('type') || 'No type').catch(() => 'Unknown'); + const name = await input.evaluate(i => i.getAttribute('name') || 'No name').catch(() => 'Unknown'); + const id = await input.evaluate(i => i.getAttribute('id') || 'No id').catch(() => 'Unknown'); + console.log(` Input: Type=${type}, Name=${name}, ID=${id}`); + } + } + + console.log('\nLogin page debug complete'); +}); \ No newline at end of file diff --git a/wordpress-dev/tests/e2e/login-test.spec.ts b/wordpress-dev/tests/e2e/login-test.spec.ts index d864f581..89d50acd 100644 --- a/wordpress-dev/tests/e2e/login-test.spec.ts +++ b/wordpress-dev/tests/e2e/login-test.spec.ts @@ -1,48 +1,63 @@ import { test, expect } from '@playwright/test'; import { LoginPage } from './pages/LoginPage'; -import { DashboardPage } from './pages/DashboardPage'; test.describe('Login Flow', () => { - test('should show error on login page', async ({ page }) => { + test('should login with valid credentials', async ({ page }) => { // Constants const testTrainerUsername = 'test_trainer'; const testTrainerPassword = 'Test123!'; + // Create a login page instance + const loginPage = new LoginPage(page); + // Navigate to login page - await page.goto('/community-login/'); - await page.waitForLoadState('networkidle'); + await loginPage.navigate(); // Save a screenshot before login - await page.screenshot({ path: 'login-page-before.png' }); + await page.screenshot({ path: 'screenshots/login-page-before.png' }); - // Dump the HTML content of the login form - const loginFormHTML = await page.locator('#loginform').innerHTML(); - console.log('Login form HTML:', loginFormHTML); + // Verify login form is visible + expect(await loginPage.isUsernameFieldVisible()).toBeTruthy(); - // Fill login form - await page.fill('#user_login', testTrainerUsername); - await page.fill('#user_pass', testTrainerPassword); - await page.click('#wp-submit'); + // Login with valid credentials + await loginPage.login(testTrainerUsername, testTrainerPassword); // Wait for navigation - await page.waitForTimeout(2000); await page.waitForLoadState('networkidle'); - // Check if we're logged in by looking for dashboard elements - await page.screenshot({ path: 'login-result.png' }); + // Check if logged in + const isLoggedIn = await loginPage.isLoggedIn(); + console.log(`Is logged in: ${isLoggedIn}`); - // Print current URL and page title for debugging - console.log('Current URL after login:', page.url()); + // Take a screenshot of the result + await page.screenshot({ path: 'screenshots/login-success.png' }); - // Dump any error messages - const errorHTML = await page.locator('.login-error, .message, #login_error').innerHTML().catch(() => 'No error element found'); - console.log('Login error message:', errorHTML); + // Print current URL for debugging + const currentUrl = await page.url(); + console.log('Current URL after login:', currentUrl); - // Instead of checking login success, check if an error is displayed - const hasError = await page.locator('.login-error, .message, #login_error').isVisible(); - console.log('Has error displayed:', hasError); + // Verify login was successful + expect(isLoggedIn).toBeTruthy(); + }); + + test('should show error with invalid credentials', async ({ page }) => { + // Create a login page instance + const loginPage = new LoginPage(page); - // Accept any result - we're just debugging - expect(true).toBeTruthy(); + // Navigate to login page + await loginPage.navigate(); + + // Login with invalid credentials + await loginPage.login('invalid_user', 'wrong_password'); + + // Check for error message + const errorMessage = await loginPage.getErrorMessage(); + console.log(`Error message: ${errorMessage}`); + + // Take a screenshot of the error + await page.screenshot({ path: 'screenshots/login-error.png' }); + + // Expect an error message + expect(errorMessage).not.toBeNull(); }); }); \ No newline at end of file diff --git a/wordpress-dev/tests/e2e/pages/LoginPage.ts b/wordpress-dev/tests/e2e/pages/LoginPage.ts index f05e467a..b39f0dad 100644 --- a/wordpress-dev/tests/e2e/pages/LoginPage.ts +++ b/wordpress-dev/tests/e2e/pages/LoginPage.ts @@ -6,13 +6,14 @@ import { PATHS } from '../config/staging-config'; * Page object representing the login page */ export class LoginPage extends BasePage { - // Login form elements - private readonly usernameInput = '#user_login'; - private readonly passwordInput = '#user_pass'; - private readonly loginButton = '#wp-submit'; - private readonly rememberMeCheckbox = '#rememberme'; - private readonly loginError = '.login-error, .login_error'; - private readonly forgotPasswordLink = 'a.forgot-password, a:text("Lost your password?")'; + // 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); @@ -22,8 +23,12 @@ export class LoginPage extends BasePage { * Navigate to the login page */ async navigate(): Promise { + this.log('Navigating to login page'); await this.page.goto(PATHS.login); - await this.page.waitForSelector(this.usernameInput); + await this.page.waitForLoadState('networkidle'); + + // Make sure the form is visible before proceeding + await this.page.waitForSelector(this.loginForm, { timeout: 10000 }); } /** @@ -40,16 +45,28 @@ export class LoginPage extends BasePage { */ async login(username: string, password: string): Promise { 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 { + await this.page.waitForLoadState('networkidle'); const url = await this.getUrl(); return url.includes('hvac-dashboard'); } @@ -58,16 +75,49 @@ export class LoginPage extends BasePage { * Check if username field is visible */ async isUsernameFieldVisible(): Promise { - return await this.page.isVisible(this.usernameInput); + 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 { - if (await this.page.isVisible(this.loginError)) { - return await this.page.textContent(this.loginError); + // 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; } diff --git a/wordpress-dev/tests/e2e/trainer-journey.test.ts b/wordpress-dev/tests/e2e/trainer-journey.test.ts index 04eccc0f..944d5373 100644 --- a/wordpress-dev/tests/e2e/trainer-journey.test.ts +++ b/wordpress-dev/tests/e2e/trainer-journey.test.ts @@ -35,7 +35,7 @@ test.describe('Trainer User Journey', () => { await expect(page).toHaveURL(/.*community-login/); // Verify login form is visible - expect(await loginPage.isLoginFormVisible()).toBe(true); + expect(await loginPage.isUsernameFieldVisible()).toBe(true); // Login with test trainer credentials await loginPage.login(trainer.username, trainer.password);