const { chromium } = require('playwright'); const fs = require('fs'); async function comprehensiveLoginQA() { const browser = await chromium.launch({ headless: false, slowMo: 500 }); const context = await browser.newContext({ viewport: { width: 1200, height: 800 } }); const page = await context.newPage(); // Track issues found const issues = []; const consoleMessages = []; const networkErrors = []; // Listen for console and network issues page.on('console', msg => { const message = `${msg.type()}: ${msg.text()}`; consoleMessages.push(message); if (msg.type() === 'error') { console.log(`āŒ Console Error: ${msg.text()}`); } }); page.on('requestfailed', request => { const error = `Failed: ${request.url()} - ${request.failure().errorText}`; networkErrors.push(error); console.log(`āŒ Network Error: ${error}`); }); try { console.log('šŸ” COMPREHENSIVE LOGIN PAGE QA AUDIT'); console.log('=====================================\n'); // Test 1: Page Loading console.log('1ļøāƒ£ Testing Page Load...'); await page.goto('http://localhost:3000/login-new', { waitUntil: 'networkidle' }); console.log('āœ… Page loaded successfully'); await page.screenshot({ path: 'login-page.png', fullPage: true }); console.log('šŸ“ø Screenshot saved: login-page.png\n'); // Test 2: Form Elements Presence console.log('2ļøāƒ£ Testing Form Elements...'); const emailField = page.locator('#email'); const passwordField = page.locator('#password'); const submitButton = page.locator('#login-btn'); const errorMessage = page.locator('#error-message'); const emailExists = await emailField.count() > 0; const passwordExists = await passwordField.count() > 0; const submitExists = await submitButton.count() > 0; const errorExists = await errorMessage.count() > 0; console.log(`āœ… Email field: ${emailExists ? 'Present' : 'āŒ MISSING'}`); console.log(`āœ… Password field: ${passwordExists ? 'Present' : 'āŒ MISSING'}`); console.log(`āœ… Submit button: ${submitExists ? 'Present' : 'āŒ MISSING'}`); console.log(`āœ… Error container: ${errorExists ? 'Present' : 'āŒ MISSING'}`); if (!emailExists || !passwordExists || !submitExists) { issues.push('Critical form elements missing'); } // Test 3: Form Attributes console.log('\n3ļøāƒ£ Testing Form Attributes...'); if (emailExists) { const emailType = await emailField.getAttribute('type'); const emailRequired = await emailField.getAttribute('required'); const emailName = await emailField.getAttribute('name'); const emailPlaceholder = await emailField.getAttribute('placeholder'); console.log(`āœ… Email type: ${emailType}`); console.log(`āœ… Email required: ${emailRequired !== null ? 'Yes' : 'No'}`); console.log(`āœ… Email name: ${emailName}`); console.log(`āœ… Email placeholder: ${emailPlaceholder}`); if (emailType !== 'email') issues.push('Email field should have type="email"'); if (!emailRequired) issues.push('Email field should be required'); } if (passwordExists) { const passwordType = await passwordField.getAttribute('type'); const passwordRequired = await passwordField.getAttribute('required'); const passwordName = await passwordField.getAttribute('name'); console.log(`āœ… Password type: ${passwordType}`); console.log(`āœ… Password required: ${passwordRequired !== null ? 'Yes' : 'No'}`); console.log(`āœ… Password name: ${passwordName}`); if (passwordType !== 'password') issues.push('Password field should have type="password"'); if (!passwordRequired) issues.push('Password field should be required'); } // Test 4: Accessibility console.log('\n4ļøāƒ£ Testing Accessibility...'); // Check labels const emailLabel = await page.locator('label[for="email"]').textContent(); const passwordLabel = await page.locator('label[for="password"]').textContent(); console.log(`āœ… Email label: "${emailLabel}"`); console.log(`āœ… Password label: "${passwordLabel}"`); if (!emailLabel) issues.push('Email field missing proper label'); if (!passwordLabel) issues.push('Password field missing proper label'); // Test tab navigation await page.keyboard.press('Tab'); await page.waitForTimeout(300); let focusedElement = await page.evaluate(() => document.activeElement.id); console.log(`āœ… First tab focus: ${focusedElement}`); await page.keyboard.press('Tab'); await page.waitForTimeout(300); focusedElement = await page.evaluate(() => document.activeElement.id); console.log(`āœ… Second tab focus: ${focusedElement}`); await page.keyboard.press('Tab'); await page.waitForTimeout(300); focusedElement = await page.evaluate(() => document.activeElement.id); console.log(`āœ… Third tab focus: ${focusedElement}`); // Test 5: Form Validation console.log('\n5ļøāƒ£ Testing Form Validation...'); // Test empty form submission await submitButton.click(); await page.waitForTimeout(1000); // Check HTML5 validation const emailValidity = await emailField.evaluate(el => el.validity.valid); const passwordValidity = await passwordField.evaluate(el => el.validity.valid); console.log(`āœ… Email field validity (empty): ${emailValidity ? 'āŒ Should be invalid' : 'Valid'}`); console.log(`āœ… Password field validity (empty): ${passwordValidity ? 'āŒ Should be invalid' : 'Valid'}`); await page.screenshot({ path: 'login-validation.png', fullPage: true }); console.log('šŸ“ø Validation screenshot saved: login-validation.png'); // Test invalid email format await emailField.fill('invalid-email'); await passwordField.fill('somepassword'); await submitButton.click(); await page.waitForTimeout(1000); const emailValidityInvalid = await emailField.evaluate(el => el.validity.valid); console.log(`āœ… Email validity (invalid format): ${emailValidityInvalid ? 'āŒ Should be invalid' : 'Valid'}`); // Test 6: Form Functionality console.log('\n6ļøāƒ£ Testing Form Functionality...'); // Clear and fill with valid test data await emailField.fill('test@example.com'); await passwordField.fill('testpassword123'); await page.screenshot({ path: 'login-form-filled.png', fullPage: true }); console.log('šŸ“ø Filled form screenshot saved: login-form-filled.png'); // Monitor for loading state const initialButtonText = await submitButton.textContent(); console.log(`āœ… Initial button text: "${initialButtonText}"`); // Submit the form and check loading state await submitButton.click(); await page.waitForTimeout(500); // Wait for loading state const loadingButtonText = await submitButton.textContent(); const buttonDisabled = await submitButton.isDisabled(); console.log(`āœ… Loading button text: "${loadingButtonText}"`); console.log(`āœ… Button disabled during loading: ${buttonDisabled}`); // Wait for response await page.waitForTimeout(3000); // Check for error message or redirect const errorVisible = await errorMessage.isVisible(); const currentURL = page.url(); console.log(`āœ… Error message visible: ${errorVisible}`); console.log(`āœ… Current URL: ${currentURL}`); if (errorVisible) { const errorText = await errorMessage.textContent(); console.log(`šŸ“ Error message: "${errorText}"`); } await page.screenshot({ path: 'login-after-attempt.png', fullPage: true }); console.log('šŸ“ø Post-submission screenshot saved: login-after-attempt.png'); // Test 7: UI/UX Quality console.log('\n7ļøāƒ£ Testing UI/UX Quality...'); // Check focus states await emailField.focus(); await page.waitForTimeout(300); await page.screenshot({ path: 'login-email-focus.png', fullPage: true }); await passwordField.focus(); await page.waitForTimeout(300); await page.screenshot({ path: 'login-password-focus.png', fullPage: true }); // Check hover states await submitButton.hover(); await page.waitForTimeout(300); await page.screenshot({ path: 'login-button-hover.png', fullPage: true }); console.log('šŸ“ø Focus and hover state screenshots saved'); // Test 8: Mobile Responsiveness console.log('\n8ļøāƒ£ Testing Mobile Responsiveness...'); await page.setViewportSize({ width: 375, height: 667 }); // iPhone SE await page.waitForTimeout(500); await page.screenshot({ path: 'login-mobile.png', fullPage: true }); console.log('šŸ“ø Mobile screenshot saved: login-mobile.png'); // Test mobile form usability const mobileFormWidth = await page.locator('form').boundingBox(); console.log(`āœ… Mobile form width: ${mobileFormWidth.width}px`); // Reset to desktop await page.setViewportSize({ width: 1200, height: 800 }); // Test 9: Check other auth pages console.log('\n9ļøāƒ£ Testing Other Auth Pages...'); const authPages = [ { path: '/login', name: 'Original Login' }, { path: '/dashboard', name: 'Dashboard' }, { path: '/auth-status', name: 'Auth Status' } ]; for (const authPage of authPages) { try { console.log(`Testing ${authPage.name} (${authPage.path})...`); const response = await page.goto(`http://localhost:3000${authPage.path}`, { waitUntil: 'networkidle', timeout: 10000 }); const status = response.status(); const title = await page.title(); console.log(` āœ… Status: ${status}, Title: "${title}"`); const filename = `auth-page${authPage.path.replace('/', '-')}.png`; await page.screenshot({ path: filename, fullPage: true }); console.log(` šŸ“ø Screenshot: ${filename}`); } catch (error) { console.log(` āŒ ${authPage.name}: ${error.message}`); issues.push(`${authPage.name} page error: ${error.message}`); } } } catch (error) { console.error('āŒ Test failed:', error); issues.push(`Test execution error: ${error.message}`); await page.screenshot({ path: 'test-error.png', fullPage: true }); } finally { await context.close(); await browser.close(); } // Generate comprehensive report console.log('\nšŸ“‹ QA AUDIT SUMMARY'); console.log('==================='); console.log(`āœ… Issues found: ${issues.length}`); console.log(`šŸ“ Console messages: ${consoleMessages.length}`); console.log(`🚨 Network errors: ${networkErrors.length}`); if (issues.length > 0) { console.log('\n🚨 ISSUES FOUND:'); issues.forEach((issue, index) => { console.log(`${index + 1}. ${issue}`); }); } if (consoleMessages.length > 0) { console.log('\nšŸ“ CONSOLE MESSAGES:'); consoleMessages.forEach((msg, index) => { console.log(`${index + 1}. ${msg}`); }); } if (networkErrors.length > 0) { console.log('\n🚨 NETWORK ERRORS:'); networkErrors.forEach((error, index) => { console.log(`${index + 1}. ${error}`); }); } // Save detailed report const report = { timestamp: new Date().toISOString(), testResults: { totalIssues: issues.length, consoleMessages: consoleMessages.length, networkErrors: networkErrors.length, issues, consoleMessages, networkErrors }, testDetails: { url: 'http://localhost:3000/login-new', browser: 'Chromium', viewport: '1200x800', mobileTest: '375x667' } }; fs.writeFileSync('login-qa-comprehensive-report.json', JSON.stringify(report, null, 2)); console.log('\nšŸ’¾ Detailed report saved: login-qa-comprehensive-report.json'); console.log('\nšŸŽ‰ QA Audit Complete!'); return report; } comprehensiveLoginQA().catch(console.error);