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>
352 lines
11 KiB
JavaScript
352 lines
11 KiB
JavaScript
const { chromium } = require('playwright');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
async function testEditButton() {
|
|
const browser = await chromium.launch({
|
|
headless: false, // Set to false to see what's happening
|
|
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
});
|
|
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1280, height: 1024 }
|
|
});
|
|
|
|
const page = await context.newPage();
|
|
|
|
// Monitor console messages and errors
|
|
const consoleMessages = [];
|
|
page.on('console', msg => {
|
|
consoleMessages.push({
|
|
type: msg.type(),
|
|
text: msg.text(),
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
console.log(`Console ${msg.type()}: ${msg.text()}`);
|
|
});
|
|
|
|
page.on('pageerror', error => {
|
|
consoleMessages.push({
|
|
type: 'pageerror',
|
|
text: error.message,
|
|
stack: error.stack,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
console.log('Page error:', error.message);
|
|
});
|
|
|
|
try {
|
|
console.log('🔑 Step 1: Authenticating...');
|
|
|
|
// Login first
|
|
await page.goto('http://192.168.0.46:3000/login-new');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Accept cookies if needed
|
|
const cookieBanner = await page.$('#cookie-consent-banner');
|
|
if (cookieBanner) {
|
|
console.log('Accepting cookies...');
|
|
await page.click('#cookie-accept-btn');
|
|
await page.waitForTimeout(1000);
|
|
}
|
|
|
|
// Fill login form
|
|
await page.fill('#email', 'tmartinez@gmail.com');
|
|
await page.fill('#password', 'TestPassword123!');
|
|
|
|
console.log('Submitting login...');
|
|
await page.click('#login-btn');
|
|
|
|
// Wait for redirect after login
|
|
await page.waitForTimeout(3000);
|
|
|
|
const postLoginUrl = page.url();
|
|
console.log('Post-login URL:', postLoginUrl);
|
|
|
|
if (!postLoginUrl.includes('/dashboard') && !postLoginUrl.includes('/events/')) {
|
|
console.error('❌ Login failed');
|
|
return;
|
|
}
|
|
|
|
console.log('✅ Authentication successful');
|
|
|
|
console.log('\n🎯 Step 2: Navigating to 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...');
|
|
await page.waitForTimeout(3000);
|
|
|
|
console.log('\n🔍 Step 3: Looking for edit event button...');
|
|
|
|
// Take initial screenshot
|
|
const screenshotDir = path.join(__dirname, 'screenshots');
|
|
if (!fs.existsSync(screenshotDir)) {
|
|
fs.mkdirSync(screenshotDir, { recursive: true });
|
|
}
|
|
|
|
await page.screenshot({
|
|
path: path.join(screenshotDir, 'before-edit-button-test.png'),
|
|
fullPage: true
|
|
});
|
|
|
|
// Look for various possible edit button selectors
|
|
const editButtonSelectors = [
|
|
'button:has-text("Edit")',
|
|
'button:has-text("Edit Event")',
|
|
'[data-testid="edit-event"]',
|
|
'[data-testid="edit-button"]',
|
|
'.edit-button',
|
|
'.edit-event-button',
|
|
'button[aria-label*="edit"]',
|
|
'button[title*="edit"]',
|
|
'a:has-text("Edit")',
|
|
'a:has-text("Edit Event")'
|
|
];
|
|
|
|
let editButton = null;
|
|
let foundSelector = null;
|
|
|
|
for (const selector of editButtonSelectors) {
|
|
try {
|
|
const element = await page.$(selector);
|
|
if (element) {
|
|
editButton = element;
|
|
foundSelector = selector;
|
|
console.log(`✓ Found edit button with selector: ${selector}`);
|
|
break;
|
|
}
|
|
} catch (error) {
|
|
// Selector failed, try next
|
|
}
|
|
}
|
|
|
|
if (!editButton) {
|
|
console.log('❌ No edit button found with common selectors');
|
|
|
|
// Look for any buttons or links that might be the edit button
|
|
console.log('\n🔍 Searching for all buttons and links...');
|
|
|
|
const allButtons = await page.$$eval('button, a[href], [role="button"]', elements => {
|
|
return elements.map(el => ({
|
|
tagName: el.tagName,
|
|
textContent: el.textContent?.trim(),
|
|
className: el.className,
|
|
href: el.href || null,
|
|
id: el.id || null,
|
|
'data-testid': el.getAttribute('data-testid') || null,
|
|
title: el.title || null,
|
|
ariaLabel: el.getAttribute('aria-label') || null
|
|
})).filter(el => el.textContent && el.textContent.length > 0);
|
|
});
|
|
|
|
console.log('All interactive elements:');
|
|
allButtons.forEach((btn, index) => {
|
|
if (btn.textContent.toLowerCase().includes('edit') ||
|
|
btn.className.toLowerCase().includes('edit') ||
|
|
btn.id.toLowerCase().includes('edit')) {
|
|
console.log(` ${index}: [${btn.tagName}] "${btn.textContent}" (${btn.className})`);
|
|
}
|
|
});
|
|
|
|
// Look for any element containing "edit" in text
|
|
const editElements = allButtons.filter(btn =>
|
|
btn.textContent?.toLowerCase().includes('edit') ||
|
|
btn.className?.toLowerCase().includes('edit') ||
|
|
btn.id?.toLowerCase().includes('edit')
|
|
);
|
|
|
|
if (editElements.length > 0) {
|
|
console.log('\nFound potential edit elements:');
|
|
editElements.forEach((el, i) => {
|
|
console.log(` ${i + 1}. [${el.tagName}] "${el.textContent}" - ${el.className}`);
|
|
});
|
|
|
|
// Try to click the first edit element
|
|
try {
|
|
const firstEditText = editElements[0].textContent;
|
|
editButton = await page.$(`button:has-text("${firstEditText}"), a:has-text("${firstEditText}")`);
|
|
if (editButton) {
|
|
foundSelector = `button/a with text "${firstEditText}"`;
|
|
console.log(`✓ Will try to click: "${firstEditText}"`);
|
|
}
|
|
} catch (error) {
|
|
console.log('❌ Could not find clickable edit element');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!editButton) {
|
|
console.log('\n❌ No edit button found anywhere on the page');
|
|
|
|
// Get the page HTML to analyze
|
|
const pageTitle = await page.title();
|
|
console.log('Page title:', pageTitle);
|
|
|
|
// Check if page is actually loaded
|
|
const mainContent = await page.$('main');
|
|
if (mainContent) {
|
|
const mainText = await mainContent.textContent();
|
|
console.log('Main content preview:', mainText?.slice(0, 200) + '...');
|
|
}
|
|
|
|
await page.screenshot({
|
|
path: path.join(screenshotDir, 'no-edit-button-found.png'),
|
|
fullPage: true
|
|
});
|
|
|
|
return {
|
|
success: false,
|
|
error: 'Edit button not found',
|
|
consoleMessages,
|
|
foundElements: allButtons.filter(btn =>
|
|
btn.textContent?.toLowerCase().includes('edit')
|
|
)
|
|
};
|
|
}
|
|
|
|
console.log(`\n🖱️ Step 4: Testing edit button click (${foundSelector})...`);
|
|
|
|
// Get button details before clicking
|
|
const buttonInfo = await editButton.evaluate(el => ({
|
|
tagName: el.tagName,
|
|
textContent: el.textContent?.trim(),
|
|
className: el.className,
|
|
href: el.href || null,
|
|
disabled: el.disabled || false,
|
|
onclick: el.onclick ? 'has onclick' : 'no onclick',
|
|
style: el.style.cssText
|
|
}));
|
|
|
|
console.log('Button details:', buttonInfo);
|
|
|
|
// Check if button is visible and enabled
|
|
const isVisible = await editButton.isVisible();
|
|
const isEnabled = await editButton.isEnabled();
|
|
|
|
console.log(`Button visible: ${isVisible}, enabled: ${isEnabled}`);
|
|
|
|
if (!isVisible) {
|
|
console.log('❌ Edit button is not visible');
|
|
return { success: false, error: 'Edit button not visible' };
|
|
}
|
|
|
|
if (!isEnabled) {
|
|
console.log('❌ Edit button is disabled');
|
|
return { success: false, error: 'Edit button disabled' };
|
|
}
|
|
|
|
// Take screenshot before clicking
|
|
await page.screenshot({
|
|
path: path.join(screenshotDir, 'before-edit-click.png'),
|
|
fullPage: true
|
|
});
|
|
|
|
// Try clicking the edit button
|
|
console.log('Clicking edit button...');
|
|
|
|
const beforeUrl = page.url();
|
|
await editButton.click();
|
|
|
|
// Wait for any potential navigation or modal
|
|
await page.waitForTimeout(2000);
|
|
|
|
const afterUrl = page.url();
|
|
console.log('URL before click:', beforeUrl);
|
|
console.log('URL after click:', afterUrl);
|
|
|
|
// Check if URL changed (navigation)
|
|
if (beforeUrl !== afterUrl) {
|
|
console.log('✅ Navigation occurred after clicking edit button');
|
|
console.log('New page title:', await page.title());
|
|
} else {
|
|
console.log('🤔 No navigation detected, checking for modal or other changes...');
|
|
|
|
// Check for modals or overlays
|
|
const modal = await page.$('.modal, .overlay, [role="dialog"], .popup, .edit-form');
|
|
if (modal) {
|
|
const isModalVisible = await modal.isVisible();
|
|
console.log(`✓ Modal/form detected, visible: ${isModalVisible}`);
|
|
} else {
|
|
console.log('❌ No modal or form detected');
|
|
}
|
|
|
|
// Check for any form elements that might have appeared
|
|
const forms = await page.$$('form');
|
|
console.log(`Forms on page: ${forms.length}`);
|
|
|
|
// Check for any new input fields
|
|
const inputs = await page.$$('input[type="text"], input[type="email"], textarea');
|
|
console.log(`Input fields: ${inputs.length}`);
|
|
}
|
|
|
|
// Take screenshot after clicking
|
|
await page.screenshot({
|
|
path: path.join(screenshotDir, 'after-edit-click.png'),
|
|
fullPage: true
|
|
});
|
|
|
|
// Wait a bit more to see if anything loads
|
|
await page.waitForTimeout(3000);
|
|
|
|
// Final analysis
|
|
const finalUrl = page.url();
|
|
const finalTitle = await page.title();
|
|
|
|
console.log('\n📊 Final Results:');
|
|
console.log('Final URL:', finalUrl);
|
|
console.log('Final title:', finalTitle);
|
|
console.log('Console messages:', consoleMessages.length);
|
|
|
|
const result = {
|
|
success: beforeUrl !== finalUrl || consoleMessages.some(msg => msg.text.includes('edit')),
|
|
buttonFound: true,
|
|
buttonSelector: foundSelector,
|
|
buttonInfo,
|
|
navigation: beforeUrl !== finalUrl,
|
|
beforeUrl,
|
|
afterUrl: finalUrl,
|
|
consoleMessages,
|
|
screenshots: [
|
|
'before-edit-button-test.png',
|
|
'before-edit-click.png',
|
|
'after-edit-click.png'
|
|
]
|
|
};
|
|
|
|
console.log('\n=== TEST COMPLETE ===');
|
|
return result;
|
|
|
|
} catch (error) {
|
|
console.error('❌ Test failed with error:', error);
|
|
|
|
await page.screenshot({
|
|
path: path.join(screenshotDir, 'edit-button-test-error.png'),
|
|
fullPage: true
|
|
});
|
|
|
|
return {
|
|
success: false,
|
|
error: error.message,
|
|
consoleMessages
|
|
};
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
}
|
|
|
|
// Run the test
|
|
testEditButton()
|
|
.then(result => {
|
|
console.log('\n🎯 EDIT BUTTON TEST RESULTS:');
|
|
console.log(JSON.stringify(result, null, 2));
|
|
})
|
|
.catch(error => {
|
|
console.error('💥 Test suite failed:', error);
|
|
process.exit(1);
|
|
}); |