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>
290 lines
8.7 KiB
JavaScript
290 lines
8.7 KiB
JavaScript
const { chromium } = require('playwright');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
async function debugEventManagePage() {
|
|
const browser = await chromium.launch({
|
|
headless: true,
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
});
|
|
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1280, height: 1024 },
|
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
|
});
|
|
|
|
const page = await context.newPage();
|
|
|
|
// Initialize data collection
|
|
const failedRequests = [];
|
|
const consoleErrors = [];
|
|
const networkRequests = [];
|
|
|
|
// Monitor console messages
|
|
page.on('console', msg => {
|
|
const text = msg.text();
|
|
const type = msg.type();
|
|
|
|
if (type === 'error' || type === 'warning') {
|
|
consoleErrors.push({
|
|
type: type,
|
|
message: text,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
console.log(`Console ${type}: ${text}`);
|
|
}
|
|
});
|
|
|
|
// Monitor page errors
|
|
page.on('pageerror', error => {
|
|
consoleErrors.push({
|
|
type: 'pageerror',
|
|
message: error.message,
|
|
stack: error.stack,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
console.log('Page error:', error.message);
|
|
});
|
|
|
|
// Monitor network requests
|
|
page.on('request', request => {
|
|
networkRequests.push({
|
|
url: request.url(),
|
|
method: request.method(),
|
|
headers: request.headers(),
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
});
|
|
|
|
page.on('response', response => {
|
|
const url = response.url();
|
|
const status = response.status();
|
|
|
|
// Track all API responses
|
|
if (url.includes('/api/')) {
|
|
console.log(`API Response: ${status} ${url}`);
|
|
|
|
if (status >= 400) {
|
|
failedRequests.push({
|
|
url: url,
|
|
status: status,
|
|
statusText: response.statusText(),
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
try {
|
|
console.log('Loading event management page...');
|
|
|
|
// Navigate to the event management page
|
|
const targetUrl = 'http://192.168.0.46:3000/events/7ac12bd2-8509-4db3-b1bc-98a808646311/manage';
|
|
await page.goto(targetUrl, {
|
|
waitUntil: 'networkidle',
|
|
timeout: 30000
|
|
});
|
|
|
|
console.log('Page loaded, waiting for components to stabilize...');
|
|
|
|
// Wait for the page to stabilize
|
|
await page.waitForTimeout(3000);
|
|
|
|
// Check for specific UI components
|
|
const componentChecks = {
|
|
'.stats-block': false,
|
|
'.attendee-list': false,
|
|
'.qr-code-preview': false,
|
|
'[data-testid="event-stats"]': false,
|
|
'[data-testid="ticket-types"]': false,
|
|
'[data-testid="orders-section"]': false,
|
|
'.tab-content': false,
|
|
'.event-management': false,
|
|
'.card': false,
|
|
'.glassmorphism': false
|
|
};
|
|
|
|
const missingComponents = [];
|
|
|
|
for (const [selector, _] of Object.entries(componentChecks)) {
|
|
try {
|
|
const element = await page.$(selector);
|
|
if (element) {
|
|
componentChecks[selector] = true;
|
|
console.log(`✓ Found component: ${selector}`);
|
|
} else {
|
|
missingComponents.push(selector);
|
|
console.log(`✗ Missing component: ${selector}`);
|
|
}
|
|
} catch (error) {
|
|
missingComponents.push(selector);
|
|
console.log(`✗ Error checking component ${selector}:`, error.message);
|
|
}
|
|
}
|
|
|
|
// Check for authentication state
|
|
const authState = await page.evaluate(() => {
|
|
return {
|
|
hasSupabaseClient: typeof window.supabase !== 'undefined',
|
|
hasAuthUser: window.authUser || null,
|
|
hasOrganizationId: window.organizationId || null,
|
|
cookies: document.cookie,
|
|
localStorage: Object.keys(localStorage).length,
|
|
sessionStorage: Object.keys(sessionStorage).length
|
|
};
|
|
});
|
|
|
|
console.log('Auth state:', authState);
|
|
|
|
// Wait a bit more for any async operations
|
|
await page.waitForTimeout(2000);
|
|
|
|
// Take screenshot
|
|
const screenshotDir = path.join(__dirname, 'screenshots');
|
|
if (!fs.existsSync(screenshotDir)) {
|
|
fs.mkdirSync(screenshotDir, { recursive: true });
|
|
}
|
|
|
|
const screenshotPath = path.join(screenshotDir, 'event-manage-debug.png');
|
|
await page.screenshot({
|
|
path: screenshotPath,
|
|
fullPage: true
|
|
});
|
|
|
|
console.log(`Screenshot saved to: ${screenshotPath}`);
|
|
|
|
// Get page title and URL for verification
|
|
const pageTitle = await page.title();
|
|
const currentUrl = page.url();
|
|
|
|
// Check for specific error messages in the page
|
|
const errorElements = await page.$$eval('[data-testid*="error"], .error, .alert-error',
|
|
elements => elements.map(el => el.textContent)
|
|
);
|
|
|
|
// Extract any visible error messages
|
|
const visibleErrors = await page.$$eval('*', elements => {
|
|
return elements
|
|
.filter(el => {
|
|
const text = el.textContent || '';
|
|
return text.includes('Error') || text.includes('Failed') || text.includes('404') || text.includes('500');
|
|
})
|
|
.map(el => ({
|
|
tag: el.tagName,
|
|
text: el.textContent.trim(),
|
|
className: el.className
|
|
}))
|
|
.slice(0, 10); // Limit to first 10 matches
|
|
});
|
|
|
|
// Generate diagnostic report
|
|
const report = {
|
|
route: '/events/7ac12bd2-8509-4db3-b1bc-98a808646311/manage',
|
|
status: failedRequests.length > 0 || missingComponents.length > 0 || consoleErrors.length > 0 ? 'fail' : 'pass',
|
|
timestamp: new Date().toISOString(),
|
|
page_info: {
|
|
title: pageTitle,
|
|
url: currentUrl,
|
|
loaded: true
|
|
},
|
|
screenshot: screenshotPath,
|
|
failed_requests: failedRequests,
|
|
missing_components: missingComponents,
|
|
found_components: Object.keys(componentChecks).filter(key => componentChecks[key]),
|
|
console_errors: consoleErrors,
|
|
visible_errors: visibleErrors,
|
|
auth_state: authState,
|
|
network_summary: {
|
|
total_requests: networkRequests.length,
|
|
api_requests: networkRequests.filter(req => req.url.includes('/api/')).length,
|
|
failed_requests: failedRequests.length
|
|
},
|
|
notes: generateNotes(failedRequests, missingComponents, consoleErrors, authState)
|
|
};
|
|
|
|
// Save detailed report
|
|
const reportPath = path.join(__dirname, 'event-manage-debug-report.json');
|
|
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
|
|
console.log('\n=== DIAGNOSTIC REPORT ===');
|
|
console.log(JSON.stringify(report, null, 2));
|
|
console.log(`\nFull report saved to: ${reportPath}`);
|
|
|
|
return report;
|
|
|
|
} catch (error) {
|
|
console.error('Error during page debugging:', error);
|
|
|
|
// Take screenshot even on error
|
|
try {
|
|
const screenshotDir = path.join(__dirname, 'screenshots');
|
|
if (!fs.existsSync(screenshotDir)) {
|
|
fs.mkdirSync(screenshotDir, { recursive: true });
|
|
}
|
|
|
|
const errorScreenshotPath = path.join(screenshotDir, 'event-manage-error.png');
|
|
await page.screenshot({
|
|
path: errorScreenshotPath,
|
|
fullPage: true
|
|
});
|
|
|
|
console.log(`Error screenshot saved to: ${errorScreenshotPath}`);
|
|
} catch (screenshotError) {
|
|
console.error('Failed to take error screenshot:', screenshotError);
|
|
}
|
|
|
|
return {
|
|
route: '/events/7ac12bd2-8509-4db3-b1bc-98a808646311/manage',
|
|
status: 'error',
|
|
error: error.message,
|
|
failed_requests: failedRequests,
|
|
console_errors: consoleErrors,
|
|
notes: `Critical error during page load: ${error.message}`
|
|
};
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
function generateNotes(failedRequests, missingComponents, consoleErrors, authState) {
|
|
const notes = [];
|
|
|
|
if (failedRequests.length > 0) {
|
|
notes.push(`${failedRequests.length} API requests failed`);
|
|
const apiErrors = failedRequests.map(req => `${req.status} ${req.url}`);
|
|
notes.push(`Failed APIs: ${apiErrors.join(', ')}`);
|
|
}
|
|
|
|
if (missingComponents.length > 0) {
|
|
notes.push(`${missingComponents.length} UI components missing: ${missingComponents.join(', ')}`);
|
|
}
|
|
|
|
if (consoleErrors.length > 0) {
|
|
notes.push(`${consoleErrors.length} console errors detected`);
|
|
}
|
|
|
|
if (!authState.hasSupabaseClient) {
|
|
notes.push('Supabase client not initialized');
|
|
}
|
|
|
|
if (!authState.hasAuthUser) {
|
|
notes.push('No authenticated user detected');
|
|
}
|
|
|
|
if (notes.length === 0) {
|
|
notes.push('Page appears to be loading correctly');
|
|
}
|
|
|
|
return notes.join('. ');
|
|
}
|
|
|
|
// Run the debugging
|
|
debugEventManagePage()
|
|
.then(report => {
|
|
console.log('\n=== DEBUGGING COMPLETE ===');
|
|
process.exit(report.status === 'error' ? 1 : 0);
|
|
})
|
|
.catch(error => {
|
|
console.error('Fatal error:', error);
|
|
process.exit(1);
|
|
}); |