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>
This commit is contained in:
327
comprehensive-login-qa.cjs
Normal file
327
comprehensive-login-qa.cjs
Normal file
@@ -0,0 +1,327 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user