Files
blackcanyontickets/qa-audit-comprehensive.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

302 lines
13 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');
const path = require('path');
async function runComprehensiveQAAudit() {
console.log('🔍 Starting Comprehensive QA Audit...');
const browser = await chromium.launch({
headless: false,
slowMo: 1000 // Slow down for visibility
});
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
});
const page = await context.newPage();
// Track console errors
const consoleErrors = [];
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push(`${new Date().toISOString()}: ${msg.text()}`);
}
});
// Track network failures
const networkErrors = [];
page.on('response', response => {
if (response.status() >= 400) {
networkErrors.push(`${response.status()}: ${response.url()}`);
}
});
try {
// Step 1: Login
console.log('📝 Step 1: Logging in...');
await page.goto('http://localhost:3001/login');
await page.waitForSelector('input[type="email"]', { timeout: 10000 });
await page.fill('input[type="email"]', 'tmartinez@gmail.com');
await page.fill('input[type="password"]', 'Skittles@420');
// Take login form screenshot
await page.screenshot({ path: 'login-form-qa.png', fullPage: true });
console.log('📸 Screenshot: login-form-qa.png');
await page.click('button[type="submit"]');
await page.waitForNavigation({ timeout: 15000 });
console.log(`✅ Login successful - Current URL: ${page.url()}`);
// Step 2: Test Dashboard
console.log('\n📊 Step 2: Testing Dashboard...');
await page.goto('http://localhost:3001/dashboard');
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000); // Let content load
await page.screenshot({ path: 'dashboard-qa.png', fullPage: true });
console.log('📸 Screenshot: dashboard-qa.png');
// Test dashboard interactions
try {
// Look for "Create Event" or "New Event" button
const createEventBtn = await page.locator('a[href*="events/new"], button:has-text("Create Event"), a:has-text("New Event")').first();
if (await createEventBtn.count() > 0) {
console.log('✅ Create Event button found');
}
// Check for event cards or tables
const eventElements = await page.locator('[data-testid*="event"], .event-card, table tr').count();
console.log(`📋 Found ${eventElements} event-related elements`);
} catch (error) {
console.log('⚠️ Dashboard interaction test failed:', error.message);
}
// Step 3: Test Events New Page
console.log('\n🎫 Step 3: Testing Event Creation...');
await page.goto('http://localhost:3001/events/new');
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: 'events-new-qa.png', fullPage: true });
console.log('📸 Screenshot: events-new-qa.png');
// Test form interactions
try {
const eventNameInput = await page.locator('input[name="name"], input[name="title"], input[placeholder*="event"], input[placeholder*="name"]').first();
if (await eventNameInput.count() > 0) {
await eventNameInput.fill('QA Test Event');
console.log('✅ Event name field working');
}
// Look for form submit button
const submitBtn = await page.locator('button[type="submit"], button:has-text("Create"), button:has-text("Save")').first();
if (await submitBtn.count() > 0) {
console.log('✅ Form submit button found');
}
} catch (error) {
console.log('⚠️ Event creation form test failed:', error.message);
}
// Step 4: Test QR Scan Page
console.log('\n📱 Step 4: Testing QR Scanner...');
await page.goto('http://localhost:3001/scan');
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: 'scan-qa.png', fullPage: true });
console.log('📸 Screenshot: scan-qa.png');
// Test scanner interactions
try {
// Look for camera permission or scanner elements
const scannerElements = await page.locator('[data-testid*="scanner"], video, canvas, .scanner').count();
console.log(`📷 Found ${scannerElements} scanner-related elements`);
} catch (error) {
console.log('⚠️ Scanner test failed:', error.message);
}
// Step 5: Test Templates Page
console.log('\n📋 Step 5: Testing Templates...');
await page.goto('http://localhost:3001/templates');
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: 'templates-qa.png', fullPage: true });
console.log('📸 Screenshot: templates-qa.png');
// Step 6: Test Admin Dashboard
console.log('\n🔧 Step 6: Testing Admin Dashboard...');
await page.goto('http://localhost:3001/admin/dashboard');
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: 'admin-dashboard-qa.png', fullPage: true });
console.log('📸 Screenshot: admin-dashboard-qa.png');
// Step 7: Test Calendar Page
console.log('\n📅 Step 7: Testing Calendar...');
await page.goto('http://localhost:3001/calendar');
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: 'calendar-qa.png', fullPage: true });
console.log('📸 Screenshot: calendar-qa.png');
// Test calendar interactions
try {
// Look for calendar navigation
const calendarNav = await page.locator('button:has-text("Today"), button:has-text("Next"), button:has-text("Previous"), .calendar-nav').count();
console.log(`📅 Found ${calendarNav} calendar navigation elements`);
} catch (error) {
console.log('⚠️ Calendar interaction test failed:', error.message);
}
// Step 8: Test Event Management (need an event ID)
console.log('\n⚙ Step 8: Testing Event Management...');
// First, try to get an event ID from the dashboard
await page.goto('http://localhost:3001/dashboard');
await page.waitForTimeout(2000);
let eventId = null;
try {
// Look for event links that might contain IDs
const eventLinks = await page.locator('a[href*="/events/"][href*="/manage"], a[href*="/events/"][href$="/manage"]').all();
if (eventLinks.length > 0) {
const href = await eventLinks[0].getAttribute('href');
const match = href.match(/\/events\/([^\/]+)\/manage/);
if (match) {
eventId = match[1];
console.log(`✅ Found event ID: ${eventId}`);
}
}
// If no existing event, check if we can create one quickly
if (!eventId) {
console.log('📝 No existing events found, will use test ID');
eventId = 'test-event-id'; // Use a test ID to see the error page
}
// Test the event management page
await page.goto(`http://localhost:3001/events/${eventId}/manage`);
await page.waitForSelector('body', { timeout: 10000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: 'event-manage-qa.png', fullPage: true });
console.log('📸 Screenshot: event-manage-qa.png');
// Test management tabs if present
const tabs = await page.locator('[role="tab"], .tab, button:has-text("Tickets"), button:has-text("Venue"), button:has-text("Analytics")').count();
console.log(`📑 Found ${tabs} management tab elements`);
} catch (error) {
console.log('⚠️ Event management test failed:', error.message);
}
// Step 9: Test Mobile Responsiveness
console.log('\n📱 Step 9: Testing Mobile Responsiveness...');
await page.setViewportSize({ width: 375, height: 667 }); // iPhone size
await page.goto('http://localhost:3001/dashboard');
await page.waitForTimeout(2000);
await page.screenshot({ path: 'dashboard-mobile-qa.png', fullPage: true });
console.log('📸 Screenshot: dashboard-mobile-qa.png');
await page.goto('http://localhost:3001/scan');
await page.waitForTimeout(2000);
await page.screenshot({ path: 'scan-mobile-qa.png', fullPage: true });
console.log('📸 Screenshot: scan-mobile-qa.png');
// Step 10: Test Navigation
console.log('\n🧭 Step 10: Testing Navigation...');
await page.setViewportSize({ width: 1280, height: 720 }); // Back to desktop
await page.goto('http://localhost:3001/dashboard');
await page.waitForTimeout(2000);
// Test navigation menu
try {
const navItems = await page.locator('nav a, .nav-item, [role="navigation"] a').count();
console.log(`🧭 Found ${navItems} navigation items`);
// Test menu toggle if present
const menuToggle = await page.locator('button[aria-label*="menu"], .menu-toggle, .hamburger').first();
if (await menuToggle.count() > 0) {
await menuToggle.click();
await page.waitForTimeout(1000);
await page.screenshot({ path: 'navigation-open-qa.png', fullPage: true });
console.log('📸 Screenshot: navigation-open-qa.png');
}
} catch (error) {
console.log('⚠️ Navigation test failed:', error.message);
}
// Final Report
console.log('\n📊 QA AUDIT RESULTS:');
console.log('=====================');
console.log(`✅ Total screenshots taken: 10+`);
console.log(`❌ Console errors: ${consoleErrors.length}`);
console.log(`🌐 Network errors: ${networkErrors.length}`);
if (consoleErrors.length > 0) {
console.log('\n🚨 CONSOLE ERRORS:');
consoleErrors.forEach(error => console.log(` - ${error}`));
}
if (networkErrors.length > 0) {
console.log('\n🌐 NETWORK ERRORS:');
networkErrors.forEach(error => console.log(` - ${error}`));
}
// Create summary report
const report = {
timestamp: new Date().toISOString(),
routes_tested: [
'/login',
'/dashboard',
'/events/new',
'/scan',
'/templates',
'/admin/dashboard',
'/calendar',
`/events/${eventId}/manage`
],
screenshots_taken: [
'login-form-qa.png',
'dashboard-qa.png',
'events-new-qa.png',
'scan-qa.png',
'templates-qa.png',
'admin-dashboard-qa.png',
'calendar-qa.png',
'event-manage-qa.png',
'dashboard-mobile-qa.png',
'scan-mobile-qa.png',
'navigation-open-qa.png'
],
console_errors: consoleErrors,
network_errors: networkErrors,
status: consoleErrors.length === 0 && networkErrors.length === 0 ? 'PASSED' : 'ISSUES_FOUND'
};
fs.writeFileSync('qa-audit-report.json', JSON.stringify(report, null, 2));
console.log('\n💾 Report saved to: qa-audit-report.json');
} catch (error) {
console.error('❌ QA Audit failed:', error);
} finally {
await browser.close();
console.log('\n🏁 QA Audit completed');
}
}
runComprehensiveQAAudit();