Files
blackcanyontickets/comprehensive-login-qa.cjs
dzinesco dbf4b11e81 fix: Implement comprehensive edit event button functionality and resolve authentication issues
Major fixes and improvements:
- Fixed edit event button functionality with proper event handlers and DOM ready state checking
- Added status column to tickets table via Supabase migration to resolve 500 API errors
- Updated stats API to correctly calculate revenue from decimal price values
- Resolved authentication redirect loops by fixing cookie configuration for Docker environment
- Fixed Permissions-Policy header syntax errors
- Added comprehensive debugging and error handling for event management
- Implemented modal-based event editing with form validation and API integration
- Enhanced event data loading with proper error handling and user feedback

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14 18:49:49 -06:00

327 lines
12 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);