- Add comprehensive analytics components with export functionality - Implement territory management with manager performance tracking - Add seatmap components for venue layout management - Create customer management features with modal interface - Add advanced hooks for dashboard flags and territory data - Implement seat selection and venue management utilities - Add type definitions for ticketing and seatmap systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
259 lines
10 KiB
JavaScript
259 lines
10 KiB
JavaScript
/**
|
|
* Playwright test to diagnose ticket creation button issues
|
|
* on the event management page
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
test('Diagnose ticket creation button issues', async ({ page }) => {
|
|
// Enable console logging to catch React errors
|
|
const consoleMessages = [];
|
|
const consoleErrors = [];
|
|
|
|
page.on('console', msg => {
|
|
const text = msg.text();
|
|
consoleMessages.push({ type: msg.type(), text });
|
|
|
|
if (msg.type() === 'error') {
|
|
consoleErrors.push(text);
|
|
console.log(`❌ Console Error: ${text}`);
|
|
} else if (msg.type() === 'warn') {
|
|
console.log(`⚠️ Console Warning: ${text}`);
|
|
} else if (text.includes('TicketsTab') || text.includes('ticket') || text.includes('React')) {
|
|
console.log(`🔍 Relevant Console: [${msg.type()}] ${text}`);
|
|
}
|
|
});
|
|
|
|
// Catch page errors
|
|
page.on('pageerror', error => {
|
|
console.log(`❌ Page Error: ${error.message}`);
|
|
consoleErrors.push(`Page Error: ${error.message}`);
|
|
});
|
|
|
|
console.log('🚀 Starting diagnosis...');
|
|
|
|
// Step 1: Navigate to login page
|
|
console.log('📝 Step 1: Navigating to login page...');
|
|
await page.goto('http://localhost:3000/login');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Step 2: Login with provided credentials
|
|
console.log('🔐 Step 2: Logging in...');
|
|
await page.fill('input[type="email"]', 'tyler@zest.is');
|
|
await page.fill('input[type="password"]', 'Test123!');
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Wait for redirect to dashboard
|
|
await page.waitForURL('**/dashboard', { timeout: 10000 });
|
|
console.log('✅ Successfully logged in and redirected to dashboard');
|
|
|
|
// Step 3: Find and navigate to an event management page
|
|
console.log('🎪 Step 3: Looking for events to manage...');
|
|
|
|
// Wait for events to load
|
|
await page.waitForTimeout(2000);
|
|
|
|
// Look for event links
|
|
const eventLinks = await page.locator('a[href*="/events/"][href*="/manage"]').all();
|
|
|
|
if (eventLinks.length === 0) {
|
|
console.log('⚠️ No event management links found. Looking for alternative navigation...');
|
|
|
|
// Try to find "Create Event" or other event-related buttons
|
|
const createEventBtn = page.locator('text="Create Event"').first();
|
|
if (await createEventBtn.isVisible()) {
|
|
console.log('📋 Found "Create Event" button, but we need an existing event. Creating one for testing...');
|
|
// This would require creating an event first, which is complex
|
|
// For now, let's check if there are any events at all
|
|
}
|
|
|
|
// Check if there are any events displayed
|
|
const eventCards = await page.locator('[data-testid="event-card"], .event-card, .bg-white\\/10').all();
|
|
console.log(`Found ${eventCards.length} potential event cards`);
|
|
|
|
if (eventCards.length === 0) {
|
|
console.log('❌ No events found. Cannot proceed with ticket creation diagnosis.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Navigate to first available event management page
|
|
let eventManageUrl;
|
|
if (eventLinks.length > 0) {
|
|
eventManageUrl = await eventLinks[0].getAttribute('href');
|
|
} else {
|
|
// Try to construct URL from event cards
|
|
const eventCard = page.locator('.bg-white\\/10, [class*="glass"], .backdrop-blur').first();
|
|
const eventLink = eventCard.locator('a').first();
|
|
const eventHref = await eventLink.getAttribute('href');
|
|
if (eventHref) {
|
|
eventManageUrl = eventHref.includes('/manage') ? eventHref : `${eventHref}/manage`;
|
|
}
|
|
}
|
|
|
|
if (!eventManageUrl) {
|
|
console.log('❌ Could not find event management URL');
|
|
return;
|
|
}
|
|
|
|
console.log(`🎯 Step 4: Navigating to event management: ${eventManageUrl}`);
|
|
await page.goto(`http://localhost:3000${eventManageUrl}`);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Wait a bit for React components to mount
|
|
await page.waitForTimeout(3000);
|
|
|
|
// Step 5: Check current tab and navigate to Ticketing & Access if needed
|
|
console.log('📋 Step 5: Checking current tab...');
|
|
|
|
// Look for tab navigation
|
|
const tabs = await page.locator('[role="tablist"], .tab, [data-tab], button[class*="tab"], a[class*="tab"]').all();
|
|
console.log(`Found ${tabs.length} potential tabs`);
|
|
|
|
// Look for Ticketing & Access tab specifically
|
|
const ticketingTab = page.locator('text="Ticketing & Access"').or(
|
|
page.locator('text="Tickets"')
|
|
).or(
|
|
page.locator('[data-tab="tickets"]')
|
|
).first();
|
|
|
|
if (await ticketingTab.isVisible()) {
|
|
console.log('🎫 Found Ticketing & Access tab, clicking it...');
|
|
await ticketingTab.click();
|
|
await page.waitForTimeout(2000);
|
|
} else {
|
|
console.log('⚠️ Ticketing & Access tab not found. Looking for alternative navigation...');
|
|
|
|
// List all visible text that might be tabs
|
|
const allText = await page.locator('button, a, [role="tab"]').allTextContents();
|
|
console.log('Available clickable elements:', allText.slice(0, 20)); // Limit output
|
|
}
|
|
|
|
// Step 6: Inspect DOM for TicketsTab component
|
|
console.log('🔍 Step 6: Inspecting DOM for TicketsTab component...');
|
|
|
|
// Check for React component indicators
|
|
const reactElements = await page.locator('[data-reactroot], [data-react-component], [class*="TicketsTab"]').all();
|
|
console.log(`Found ${reactElements.length} React-related elements`);
|
|
|
|
// Check for ticket-related elements
|
|
const ticketElements = await page.locator('[class*="ticket"], [data-testid*="ticket"], [id*="ticket"]').all();
|
|
console.log(`Found ${ticketElements.length} ticket-related elements`);
|
|
|
|
// Step 7: Look for ticket creation buttons
|
|
console.log('🔘 Step 7: Looking for ticket creation buttons...');
|
|
|
|
const ticketCreationButtons = await page.locator(
|
|
'text="Create Your First Ticket Type"'
|
|
).or(
|
|
page.locator('text="Add Ticket Type"')
|
|
).or(
|
|
page.locator('text="Create Ticket"')
|
|
).or(
|
|
page.locator('button[class*="ticket"]')
|
|
).all();
|
|
|
|
console.log(`Found ${ticketCreationButtons.length} potential ticket creation buttons`);
|
|
|
|
for (let i = 0; i < ticketCreationButtons.length; i++) {
|
|
const button = ticketCreationButtons[i];
|
|
const text = await button.textContent();
|
|
const isVisible = await button.isVisible();
|
|
const isEnabled = await button.isEnabled();
|
|
console.log(`Button ${i + 1}: "${text}" - Visible: ${isVisible}, Enabled: ${isEnabled}`);
|
|
}
|
|
|
|
// Step 8: Check for TicketsTab component specifically
|
|
console.log('⚛️ Step 8: Checking for TicketsTab React component...');
|
|
|
|
// Evaluate JavaScript to check for React components
|
|
const reactCheck = await page.evaluate(() => {
|
|
// Check for React DevTools
|
|
const hasReactDevTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__ !== undefined;
|
|
|
|
// Check for React roots
|
|
const reactRoots = document.querySelectorAll('[data-reactroot]');
|
|
|
|
// Check for any elements with React-like attributes
|
|
const reactElements = document.querySelectorAll('[data-react*], [class*="react"], [class*="React"]');
|
|
|
|
// Look for TicketsTab specifically
|
|
const ticketsTabElements = document.querySelectorAll('[class*="TicketsTab"], [data-component*="TicketsTab"]');
|
|
|
|
return {
|
|
hasReactDevTools,
|
|
reactRootsCount: reactRoots.length,
|
|
reactElementsCount: reactElements.length,
|
|
ticketsTabElementsCount: ticketsTabElements.length,
|
|
bodyClasses: document.body.className,
|
|
scriptTags: Array.from(document.scripts).map(s => s.src).filter(src => src)
|
|
};
|
|
});
|
|
|
|
console.log('React Environment Check:', reactCheck);
|
|
|
|
// Step 9: Try clicking ticket creation buttons
|
|
console.log('🖱️ Step 9: Attempting to click ticket creation buttons...');
|
|
|
|
if (ticketCreationButtons.length > 0) {
|
|
for (let i = 0; i < Math.min(ticketCreationButtons.length, 3); i++) {
|
|
const button = ticketCreationButtons[i];
|
|
const isVisible = await button.isVisible();
|
|
const isEnabled = await button.isEnabled();
|
|
|
|
if (isVisible && isEnabled) {
|
|
console.log(`Clicking button ${i + 1}...`);
|
|
|
|
// Clear any previous console messages for this click
|
|
const beforeClick = consoleMessages.length;
|
|
|
|
await button.click();
|
|
await page.waitForTimeout(2000);
|
|
|
|
// Check for new console messages
|
|
const newMessages = consoleMessages.slice(beforeClick);
|
|
if (newMessages.length > 0) {
|
|
console.log('New console messages after click:', newMessages);
|
|
}
|
|
|
|
// Check if a modal or form appeared
|
|
const modals = await page.locator('[role="dialog"], .modal, [class*="modal"], [class*="popup"]').all();
|
|
console.log(`Found ${modals.length} potential modals after click`);
|
|
|
|
// Check for form elements
|
|
const forms = await page.locator('form, [class*="form"]').all();
|
|
console.log(`Found ${forms.length} forms after click`);
|
|
|
|
break; // Only try the first working button
|
|
}
|
|
}
|
|
} else {
|
|
console.log('❌ No ticket creation buttons found to click');
|
|
}
|
|
|
|
// Step 10: Final summary
|
|
console.log('\n📊 DIAGNOSIS SUMMARY:');
|
|
console.log('='.repeat(50));
|
|
console.log(`Console Errors: ${consoleErrors.length}`);
|
|
if (consoleErrors.length > 0) {
|
|
consoleErrors.forEach((error, i) => console.log(` ${i + 1}. ${error}`));
|
|
}
|
|
|
|
console.log(`Total Console Messages: ${consoleMessages.length}`);
|
|
console.log(`React Environment: ${reactCheck.hasReactDevTools ? '✅ Detected' : '❌ Not detected'}`);
|
|
console.log(`Ticket Creation Buttons Found: ${ticketCreationButtons.length}`);
|
|
console.log(`React Elements Found: ${reactCheck.reactElementsCount}`);
|
|
console.log(`TicketsTab Elements Found: ${reactCheck.ticketsTabElementsCount}`);
|
|
|
|
// Step 11: Take screenshot for visual debugging
|
|
console.log('📸 Taking screenshot for visual debugging...');
|
|
await page.screenshot({
|
|
path: '/home/tyler/apps/bct-whitelabel/ticket-creation-diagnosis.png',
|
|
fullPage: true
|
|
});
|
|
console.log('Screenshot saved as ticket-creation-diagnosis.png');
|
|
|
|
// Keep browser open for manual inspection
|
|
console.log('\n🔍 Test complete. Browser will remain open for manual inspection...');
|
|
await page.waitForTimeout(30000); // Keep open for 30 seconds
|
|
}); |