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>
189 lines
7.3 KiB
JavaScript
189 lines
7.3 KiB
JavaScript
const playwright = require('playwright');
|
|
|
|
(async () => {
|
|
const browser = await playwright.chromium.launch();
|
|
const context = await browser.newContext();
|
|
const page = await context.newPage();
|
|
|
|
// Track console messages and errors
|
|
const consoleLogs = [];
|
|
const errors = [];
|
|
|
|
page.on('console', msg => {
|
|
consoleLogs.push(`[${msg.type()}] ${msg.text()}`);
|
|
});
|
|
|
|
page.on('pageerror', error => {
|
|
errors.push(`Page Error: ${error.message}`);
|
|
});
|
|
|
|
page.on('requestfailed', request => {
|
|
errors.push(`Network Error: ${request.url()} - ${request.failure().errorText}`);
|
|
});
|
|
|
|
try {
|
|
console.log('=== AUTHENTICATION FLOW TEST ===');
|
|
|
|
// Step 1: Navigate to login page
|
|
console.log('1. Navigating to login page...');
|
|
await page.goto('http://localhost:3000/login-new', { waitUntil: 'networkidle' });
|
|
|
|
// Check page title and elements
|
|
const title = await page.title();
|
|
console.log(` Page title: ${title}`);
|
|
|
|
// Check for form elements
|
|
const emailField = await page.locator('input[type="email"], input[name="email"]').first();
|
|
const passwordField = await page.locator('input[type="password"], input[name="password"]').first();
|
|
const submitButton = await page.locator('button[type="submit"], input[type="submit"]').first();
|
|
|
|
const hasEmailField = await emailField.count() > 0;
|
|
const hasPasswordField = await passwordField.count() > 0;
|
|
const hasSubmitButton = await submitButton.count() > 0;
|
|
|
|
console.log(` Email field found: ${hasEmailField}`);
|
|
console.log(` Password field found: ${hasPasswordField}`);
|
|
console.log(` Submit button found: ${hasSubmitButton}`);
|
|
|
|
if (!hasEmailField || !hasPasswordField || !hasSubmitButton) {
|
|
throw new Error('Required form elements not found');
|
|
}
|
|
|
|
// Step 2: Fill in credentials
|
|
console.log('2. Filling in credentials...');
|
|
await emailField.fill('tmartinez@gmail.com');
|
|
await passwordField.fill('Skittles@420');
|
|
|
|
console.log(' Credentials filled');
|
|
|
|
// Step 3: Submit form and wait for navigation
|
|
console.log('3. Submitting form...');
|
|
|
|
// Wait for either navigation or error message
|
|
const [response] = await Promise.all([
|
|
page.waitForResponse(response => response.url().includes('/api/auth/') || response.url().includes('/dashboard'), { timeout: 10000 }).catch(() => null),
|
|
submitButton.click()
|
|
]);
|
|
|
|
// Wait a bit for any redirects
|
|
await page.waitForTimeout(3000);
|
|
|
|
const currentUrl = page.url();
|
|
console.log(` Current URL after submit: ${currentUrl}`);
|
|
|
|
// Check for error messages on the page
|
|
const errorElements = await page.locator('.error, [role="alert"], .alert-error, .text-red-500').all();
|
|
if (errorElements.length > 0) {
|
|
console.log(' Error messages found:');
|
|
for (const errorEl of errorElements) {
|
|
const text = await errorEl.textContent();
|
|
if (text && text.trim()) {
|
|
console.log(` - ${text.trim()}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Step 4: Check if we're on dashboard or still on login
|
|
if (currentUrl.includes('/dashboard')) {
|
|
console.log('4. Successfully redirected to dashboard');
|
|
|
|
// Take screenshot of dashboard
|
|
await page.screenshot({ path: 'dashboard-page.png', fullPage: true });
|
|
console.log(' Dashboard screenshot saved: dashboard-page.png');
|
|
|
|
// Check for user info or logout button
|
|
const logoutButton = await page.locator('button:has-text("Logout"), a:has-text("Logout"), button:has-text("Sign out"), a:has-text("Sign out")').first();
|
|
const hasLogout = await logoutButton.count() > 0;
|
|
console.log(` Logout button found: ${hasLogout}`);
|
|
|
|
// Test logout if available
|
|
if (hasLogout) {
|
|
console.log('5. Testing logout functionality...');
|
|
await logoutButton.click();
|
|
await page.waitForTimeout(2000);
|
|
|
|
const afterLogoutUrl = page.url();
|
|
console.log(` URL after logout: ${afterLogoutUrl}`);
|
|
|
|
if (afterLogoutUrl.includes('/login')) {
|
|
console.log(' Logout successful - redirected to login');
|
|
} else {
|
|
console.log(' Logout may have failed - not redirected to login');
|
|
}
|
|
}
|
|
|
|
// Test session persistence
|
|
console.log('6. Testing session persistence...');
|
|
await page.goto('http://localhost:3000/dashboard');
|
|
await page.waitForTimeout(2000);
|
|
const persistenceUrl = page.url();
|
|
console.log(` After direct navigation to dashboard: ${persistenceUrl}`);
|
|
|
|
} else if (currentUrl.includes('/login')) {
|
|
console.log('4. Still on login page - authentication may have failed');
|
|
|
|
// Take screenshot of login page with any errors
|
|
await page.screenshot({ path: 'login-error.png', fullPage: true });
|
|
console.log(' Error screenshot saved: login-error.png');
|
|
|
|
} else {
|
|
console.log(`4. Unexpected redirect to: ${currentUrl}`);
|
|
await page.screenshot({ path: 'unexpected-redirect.png', fullPage: true });
|
|
}
|
|
|
|
// Step 5: Test form validation (go back to fresh login page)
|
|
console.log('7. Testing form validation...');
|
|
await page.goto('http://localhost:3000/login-new');
|
|
await page.waitForTimeout(1000);
|
|
|
|
const emailFieldValid = await page.locator('input[type="email"], input[name="email"]').first();
|
|
const passwordFieldValid = await page.locator('input[type="password"], input[name="password"]').first();
|
|
const submitButtonValid = await page.locator('button[type="submit"], input[type="submit"]').first();
|
|
|
|
// Clear fields and try empty submission
|
|
await emailFieldValid.fill('');
|
|
await passwordFieldValid.fill('');
|
|
await submitButtonValid.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
const validationErrors = await page.locator('.error, [role="alert"], .alert-error, .text-red-500, :invalid').all();
|
|
console.log(` Validation errors found: ${validationErrors.length}`);
|
|
|
|
// Test invalid email
|
|
await emailFieldValid.fill('invalid-email');
|
|
await passwordFieldValid.fill('test');
|
|
await submitButtonValid.click();
|
|
await page.waitForTimeout(1000);
|
|
|
|
const emailValidationErrors = await page.locator(':invalid, .error').all();
|
|
console.log(` Email validation working: ${emailValidationErrors.length > 0}`);
|
|
|
|
// Step 6: Check accessibility
|
|
console.log('8. Checking accessibility...');
|
|
const formLabels = await page.locator('label').count();
|
|
const ariaLabels = await page.locator('[aria-label]').count();
|
|
const focusableElements = await page.locator('button, input, select, textarea, a[href]').count();
|
|
|
|
console.log(` Form labels: ${formLabels}`);
|
|
console.log(` ARIA labels: ${ariaLabels}`);
|
|
console.log(` Focusable elements: ${focusableElements}`);
|
|
|
|
} catch (error) {
|
|
console.error('Test failed:', error.message);
|
|
await page.screenshot({ path: 'test-error.png', fullPage: true });
|
|
} finally {
|
|
// Report console logs and errors
|
|
console.log('\n=== CONSOLE LOGS ===');
|
|
consoleLogs.forEach(log => console.log(log));
|
|
|
|
console.log('\n=== ERRORS ===');
|
|
if (errors.length === 0) {
|
|
console.log('No errors detected');
|
|
} else {
|
|
errors.forEach(error => console.log(error));
|
|
}
|
|
|
|
await browser.close();
|
|
console.log('\n=== TEST COMPLETE ===');
|
|
}
|
|
})(); |