Files
blackcanyontickets/test-theme-and-interactions.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

324 lines
14 KiB
JavaScript
Raw Permalink 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 runQATests() {
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
viewport: { width: 1280, height: 720 }
});
const page = await context.newPage();
// Monitor console errors
const consoleErrors = [];
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push({
timestamp: new Date().toISOString(),
message: msg.text(),
url: page.url()
});
}
});
const results = {
themeTests: {},
interactiveTests: {},
mobileTests: {},
consoleErrors: []
};
try {
console.log('🚀 Starting QA Tests - Theme Functionality and Interactive Components');
// Navigate to login page
console.log('\n📋 Step 1: Logging in...');
await page.goto('http://localhost:3001/login');
await page.waitForLoadState('networkidle');
// Take screenshot of login page
await page.screenshot({ path: 'login-page-qa.png', fullPage: true });
// Login
await page.fill('input[type="email"]', 'tmartinez@gmail.com');
await page.fill('input[type="password"]', 'Skittles@420');
await page.click('button[type="submit"]');
// Wait for dashboard
await page.waitForURL('**/dashboard', { timeout: 10000 });
await page.waitForLoadState('networkidle');
console.log('✅ Successfully logged in');
// THEME TESTING
console.log('\n🎨 Step 2: Testing Theme Functionality...');
results.themeTests.startingTheme = 'Testing for theme toggle elements';
// Look for theme toggle elements
const themeToggleSelectors = [
'[data-theme-toggle]',
'.theme-toggle',
'.dark-mode-toggle',
'button[aria-label*="theme"]',
'button[aria-label*="dark"]',
'button[aria-label*="light"]',
'[role="switch"]'
];
let themeToggleFound = false;
let themeToggleElement = null;
for (const selector of themeToggleSelectors) {
try {
const element = await page.$(selector);
if (element) {
themeToggleFound = true;
themeToggleElement = element;
results.themeTests.toggleSelector = selector;
console.log(`✅ Found theme toggle: ${selector}`);
break;
}
} catch (e) {
// Continue checking other selectors
}
}
if (!themeToggleFound) {
// Check navigation area for any button that might be a theme toggle
const navButtons = await page.$$('nav button, header button');
console.log(`🔍 Checking ${navButtons.length} navigation buttons for theme toggle...`);
for (let i = 0; i < navButtons.length; i++) {
const button = navButtons[i];
const text = await button.textContent();
const ariaLabel = await button.getAttribute('aria-label');
console.log(`Button ${i}: text="${text}", aria-label="${ariaLabel}"`);
if (text && (text.toLowerCase().includes('theme') || text.toLowerCase().includes('dark') || text.toLowerCase().includes('light'))) {
themeToggleFound = true;
themeToggleElement = button;
results.themeTests.toggleSelector = `nav button:nth-child(${i+1})`;
break;
}
if (ariaLabel && (ariaLabel.toLowerCase().includes('theme') || ariaLabel.toLowerCase().includes('dark') || ariaLabel.toLowerCase().includes('light'))) {
themeToggleFound = true;
themeToggleElement = button;
results.themeTests.toggleSelector = `button[aria-label="${ariaLabel}"]`;
break;
}
}
}
if (themeToggleFound && themeToggleElement) {
console.log('🎨 Testing theme toggle functionality...');
// Take screenshot before toggle
await page.screenshot({ path: 'theme-before-toggle.png', fullPage: true });
results.themeTests.beforeToggleScreenshot = 'theme-before-toggle.png';
// Get initial theme state
const initialTheme = await page.evaluate(() => {
return {
documentClass: document.documentElement.className,
bodyClass: document.body.className,
localStorage: localStorage.getItem('theme') || localStorage.getItem('dark-mode') || localStorage.getItem('color-theme'),
dataTheme: document.documentElement.getAttribute('data-theme')
};
});
results.themeTests.initialState = initialTheme;
// Click theme toggle
await themeToggleElement.click();
await page.waitForTimeout(500); // Wait for theme transition
// Get state after toggle
const afterToggleTheme = await page.evaluate(() => {
return {
documentClass: document.documentElement.className,
bodyClass: document.body.className,
localStorage: localStorage.getItem('theme') || localStorage.getItem('dark-mode') || localStorage.getItem('color-theme'),
dataTheme: document.documentElement.getAttribute('data-theme')
};
});
results.themeTests.afterToggleState = afterToggleTheme;
// Take screenshot after toggle
await page.screenshot({ path: 'theme-after-toggle.png', fullPage: true });
results.themeTests.afterToggleScreenshot = 'theme-after-toggle.png';
// Test persistence - reload page
await page.reload();
await page.waitForLoadState('networkidle');
const afterReloadTheme = await page.evaluate(() => {
return {
documentClass: document.documentElement.className,
bodyClass: document.body.className,
localStorage: localStorage.getItem('theme') || localStorage.getItem('dark-mode') || localStorage.getItem('color-theme'),
dataTheme: document.documentElement.getAttribute('data-theme')
};
});
results.themeTests.afterReloadState = afterReloadTheme;
results.themeTests.persistenceWorks = JSON.stringify(afterToggleTheme) === JSON.stringify(afterReloadTheme);
console.log(`✅ Theme toggle found and tested. Persistence: ${results.themeTests.persistenceWorks ? '✅' : '❌'}`);
} else {
console.log('❌ No theme toggle found');
results.themeTests.status = 'No theme toggle functionality found';
}
// INTERACTIVE COMPONENTS TESTING
console.log('\n🖱 Step 3: Testing Interactive Components...');
// Test navigation menu
console.log('Testing navigation menu...');
const navLinks = await page.$$('nav a, header a');
results.interactiveTests.navigationLinks = navLinks.length;
console.log(`Found ${navLinks.length} navigation links`);
// Test event creation form
console.log('Testing event creation form...');
try {
await page.goto('http://localhost:3001/events/new');
await page.waitForLoadState('networkidle');
// Take screenshot of form
await page.screenshot({ path: 'event-creation-form.png', fullPage: true });
// Test form fields
const formFields = await page.$$('input, textarea, select');
results.interactiveTests.eventFormFields = formFields.length;
console.log(`Found ${formFields.length} form fields`);
// Test form validation - submit empty form
console.log('Testing form validation...');
const submitButton = await page.$('button[type="submit"], input[type="submit"]');
if (submitButton) {
await submitButton.click();
await page.waitForTimeout(1000);
// Check for validation messages
const validationMessages = await page.$$('.error, .invalid, [role="alert"], .text-red-500, .text-red-600');
results.interactiveTests.validationMessages = validationMessages.length;
console.log(`Found ${validationMessages.length} validation messages`);
// Take screenshot with validation
await page.screenshot({ path: 'form-validation-test.png', fullPage: true });
}
} catch (e) {
console.log('❌ Error testing event creation form:', e.message);
results.interactiveTests.eventFormError = e.message;
}
// Test dashboard interactive elements
console.log('Testing dashboard interactions...');
await page.goto('http://localhost:3001/dashboard');
await page.waitForLoadState('networkidle');
// Look for buttons, links, and interactive elements
const buttons = await page.$$('button');
const links = await page.$$('a');
const inputs = await page.$$('input, select, textarea');
results.interactiveTests.dashboardButtons = buttons.length;
results.interactiveTests.dashboardLinks = links.length;
results.interactiveTests.dashboardInputs = inputs.length;
console.log(`Dashboard: ${buttons.length} buttons, ${links.length} links, ${inputs.length} inputs`);
// Look for modals or dropdowns
console.log('Looking for modals and dropdowns...');
const modalTriggers = await page.$$('[data-modal], [data-toggle="modal"], .modal-trigger');
const dropdownTriggers = await page.$$('[data-dropdown], .dropdown-toggle, [aria-haspopup]');
results.interactiveTests.modalTriggers = modalTriggers.length;
results.interactiveTests.dropdownTriggers = dropdownTriggers.length;
// Test any dropdown that exists
if (dropdownTriggers.length > 0) {
console.log('Testing dropdown functionality...');
try {
await dropdownTriggers[0].click();
await page.waitForTimeout(500);
const dropdownMenu = await page.$('.dropdown-menu, [role="menu"], .dropdown-content');
results.interactiveTests.dropdownWorks = !!dropdownMenu;
if (dropdownMenu) {
await page.screenshot({ path: 'dropdown-open.png', fullPage: true });
}
} catch (e) {
results.interactiveTests.dropdownError = e.message;
}
}
// MOBILE RESPONSIVENESS TESTING
console.log('\n📱 Step 4: Testing Mobile Responsiveness...');
// Switch to mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await page.reload();
await page.waitForLoadState('networkidle');
// Test mobile navigation
await page.screenshot({ path: 'mobile-dashboard.png', fullPage: true });
// Look for mobile menu toggle
const mobileMenuToggle = await page.$('.mobile-menu-toggle, .hamburger, [aria-label*="menu"]');
if (mobileMenuToggle) {
console.log('Testing mobile menu...');
await mobileMenuToggle.click();
await page.waitForTimeout(500);
await page.screenshot({ path: 'mobile-menu-open.png', fullPage: true });
results.mobileTests.mobileMenuWorks = true;
} else {
results.mobileTests.mobileMenuWorks = false;
}
// Test mobile form
await page.goto('http://localhost:3001/events/new');
await page.waitForLoadState('networkidle');
await page.screenshot({ path: 'mobile-form.png', fullPage: true });
// Check for horizontal scroll
const hasHorizontalScroll = await page.evaluate(() => {
return document.body.scrollWidth > window.innerWidth;
});
results.mobileTests.hasHorizontalScroll = hasHorizontalScroll;
console.log(`Mobile menu: ${results.mobileTests.mobileMenuWorks ? '✅' : '❌'}`);
console.log(`Horizontal scroll: ${hasHorizontalScroll ? '❌' : '✅'}`);
} catch (error) {
console.error('❌ Test execution error:', error);
results.error = error.message;
} finally {
// Collect final console errors
results.consoleErrors = consoleErrors;
// Write results to file
fs.writeFileSync('qa-test-results.json', JSON.stringify(results, null, 2));
console.log('\n📊 QA Test Summary:');
console.log('Theme Tests:', Object.keys(results.themeTests).length, 'checks');
console.log('Interactive Tests:', Object.keys(results.interactiveTests).length, 'checks');
console.log('Mobile Tests:', Object.keys(results.mobileTests).length, 'checks');
console.log('Console Errors:', consoleErrors.length);
if (consoleErrors.length > 0) {
console.log('\n❌ Console Errors Found:');
consoleErrors.forEach((error, i) => {
console.log(`${i+1}. ${error.message} (${error.url})`);
});
}
console.log('\n📄 Results saved to qa-test-results.json');
console.log('🖼️ Screenshots saved with descriptive names');
await browser.close();
}
}
// Run the tests
runQATests().catch(console.error);