const playwright = require('playwright'); (async () => { const browser = await playwright.chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); try { console.log('=== LOGOUT AND VALIDATION TEST ==='); // First login to test logout console.log('1. Logging in first...'); await page.goto('http://localhost:3000/login-new'); await page.fill('input[type="email"], input[name="email"]', 'tmartinez@gmail.com'); await page.fill('input[type="password"], input[name="password"]', 'Skittles@420'); await page.click('button[type="submit"], input[type="submit"]'); await page.waitForTimeout(3000); const dashboardUrl = page.url(); console.log(` Logged in, current URL: ${dashboardUrl}`); if (dashboardUrl.includes('/dashboard')) { console.log('2. Testing logout functionality...'); // Try to find user menu or dropdown that contains logout const userMenuButtons = [ 'button:has-text("Profile")', 'button:has-text("Account")', 'button:has-text("User")', '[data-testid="user-menu"]', '.user-menu', 'button[aria-haspopup="true"]', 'button[aria-expanded="false"]' ]; let userMenuFound = false; for (const selector of userMenuButtons) { const menuButton = page.locator(selector).first(); if (await menuButton.count() > 0) { console.log(` Found user menu: ${selector}`); await menuButton.click(); await page.waitForTimeout(1000); userMenuFound = true; break; } } if (!userMenuFound) { console.log(' No user menu found, looking for direct logout button...'); } // Now try to find logout button const logoutSelectors = [ 'button:has-text("Logout")', 'a:has-text("Logout")', 'button:has-text("Sign out")', 'a:has-text("Sign out")', 'button:has-text("Log out")', 'a:has-text("Log out")', '[data-testid="logout"]', '#logout-btn' ]; let logoutSuccess = false; for (const selector of logoutSelectors) { const logoutButton = page.locator(selector).first(); if (await logoutButton.count() > 0) { try { console.log(` Found logout button: ${selector}`); await logoutButton.click({ timeout: 5000 }); await page.waitForTimeout(2000); const afterLogoutUrl = page.url(); console.log(` URL after logout: ${afterLogoutUrl}`); if (afterLogoutUrl.includes('/login')) { console.log(' ✓ Logout successful - redirected to login'); logoutSuccess = true; } else { console.log(' ⚠ Logout may have failed - not redirected to login'); } break; } catch (error) { console.log(` Failed to click logout button: ${error.message}`); } } } if (!logoutSuccess) { console.log(' ⚠ Could not find or click logout button'); } } // Test form validation console.log('3. Testing form validation...'); await page.goto('http://localhost:3000/login-new'); await page.waitForTimeout(1000); // Test empty form submission console.log(' Testing empty form submission...'); await page.fill('input[type="email"], input[name="email"]', ''); await page.fill('input[type="password"], input[name="password"]', ''); await page.click('button[type="submit"], input[type="submit"]'); await page.waitForTimeout(1000); // Check for validation messages const validationElements = await page.locator('.error, [role="alert"], .alert-error, .text-red-500, .text-red-600, .border-red-500, :invalid').all(); console.log(` Validation elements found: ${validationElements.length}`); for (let i = 0; i < Math.min(validationElements.length, 3); i++) { const text = await validationElements[i].textContent(); if (text && text.trim()) { console.log(` - ${text.trim()}`); } } // Test invalid email format console.log(' Testing invalid email format...'); await page.fill('input[type="email"], input[name="email"]', 'invalid-email'); await page.fill('input[type="password"], input[name="password"]', 'password'); await page.click('button[type="submit"], input[type="submit"]'); await page.waitForTimeout(1000); const emailValidation = await page.locator('input[type="email"]:invalid').count(); console.log(` Email validation working: ${emailValidation > 0}`); // Test accessibility features console.log('4. Checking accessibility features...'); await page.goto('http://localhost:3000/login-new'); const accessibilityChecks = { formLabels: await page.locator('label').count(), ariaLabels: await page.locator('[aria-label]').count(), ariaDescribedBy: await page.locator('[aria-describedby]').count(), requiredFields: await page.locator('[required]').count(), autocompleteFields: await page.locator('[autocomplete]').count(), focusableElements: await page.locator('button, input, select, textarea, a[href]').count() }; console.log(' Accessibility features:'); Object.entries(accessibilityChecks).forEach(([key, value]) => { console.log(` ${key}: ${value}`); }); // Test keyboard navigation console.log('5. Testing keyboard navigation...'); await page.keyboard.press('Tab'); await page.waitForTimeout(500); const activeElement = await page.evaluate(() => document.activeElement.tagName); console.log(` First tab focuses: ${activeElement}`); // Test session persistence console.log('6. Testing session persistence...'); // Login again await page.fill('input[type="email"], input[name="email"]', 'tmartinez@gmail.com'); await page.fill('input[type="password"], input[name="password"]', 'Skittles@420'); await page.click('button[type="submit"], input[type="submit"]'); await page.waitForTimeout(3000); if (page.url().includes('/dashboard')) { console.log(' Logged in, testing page refresh...'); await page.reload(); await page.waitForTimeout(2000); const afterRefreshUrl = page.url(); console.log(` URL after refresh: ${afterRefreshUrl}`); if (afterRefreshUrl.includes('/dashboard')) { console.log(' ✓ Session persisted after page refresh'); } else { console.log(' ⚠ Session may not have persisted - redirected away'); } } } catch (error) { console.error('Test failed:', error.message); await page.screenshot({ path: 'logout-test-error.png', fullPage: true }); } finally { await browser.close(); console.log('\n=== LOGOUT AND VALIDATION TEST COMPLETE ==='); } })();