Best landing page yet, lost logged in links to lists of bets
130
frontend/tests/app.spec.ts
Normal file
@ -0,0 +1,130 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('H2H Application', () => {
|
||||
test('should load the homepage', async ({ page }) => {
|
||||
// Listen for page errors only (ignore 401 for public API)
|
||||
const pageErrors: Error[] = [];
|
||||
page.on('pageerror', error => {
|
||||
pageErrors.push(error);
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
|
||||
// Wait for the page to load
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
if (pageErrors.length > 0) {
|
||||
console.log('Page Errors:', pageErrors.map(e => e.message));
|
||||
}
|
||||
|
||||
// Take a screenshot
|
||||
await page.screenshot({ path: 'tests/screenshots/homepage.png', fullPage: true });
|
||||
|
||||
// Basic assertions
|
||||
await expect(page).toHaveTitle(/H2H/);
|
||||
// Should show the header with H2H logo
|
||||
await expect(page.locator('h1:has-text("H2H")')).toBeVisible();
|
||||
});
|
||||
|
||||
test('should navigate to login page', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Look for login button in header (first one)
|
||||
const loginButton = page.getByRole('link', { name: /log in/i }).first();
|
||||
await loginButton.click();
|
||||
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.screenshot({ path: 'tests/screenshots/login.png', fullPage: true });
|
||||
|
||||
await expect(page).toHaveURL(/login/);
|
||||
});
|
||||
|
||||
test('should login as admin and see events on home page', async ({ page }) => {
|
||||
const pageErrors: Error[] = [];
|
||||
page.on('pageerror', error => {
|
||||
pageErrors.push(error);
|
||||
});
|
||||
|
||||
// Go to login page
|
||||
await page.goto('/login');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Fill in login form
|
||||
await page.fill('input[type="email"]', 'admin@h2h.com');
|
||||
await page.fill('input[type="password"]', 'admin123');
|
||||
|
||||
// Submit form
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Wait for navigation after login - now redirects to home page with events
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.screenshot({ path: 'tests/screenshots/after-login.png', fullPage: true });
|
||||
|
||||
// Home page should now show events heading
|
||||
await expect(page.getByRole('heading', { name: 'Upcoming Events' })).toBeVisible({ timeout: 5000 });
|
||||
|
||||
if (pageErrors.length > 0) {
|
||||
console.log('Page Errors during flow:', pageErrors.map(e => e.message));
|
||||
}
|
||||
|
||||
expect(pageErrors.length).toBe(0);
|
||||
});
|
||||
|
||||
test('should complete full spread betting flow', async ({ page }) => {
|
||||
const pageErrors: Error[] = [];
|
||||
page.on('pageerror', error => {
|
||||
pageErrors.push(error);
|
||||
});
|
||||
|
||||
// Login as alice
|
||||
await page.goto('/login');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.fill('input[type="email"]', 'alice@example.com');
|
||||
await page.fill('input[type="password"]', 'password123');
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Wait for home page to load with events
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Events are now shown on the home page
|
||||
await expect(page.getByRole('heading', { name: 'Upcoming Events' })).toBeVisible({ timeout: 5000 });
|
||||
|
||||
await page.screenshot({ path: 'tests/screenshots/events-list.png', fullPage: true });
|
||||
|
||||
// Click on first event in the table
|
||||
const firstEventRow = page.locator('.divide-y button').first();
|
||||
if (await firstEventRow.isVisible()) {
|
||||
await firstEventRow.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
await page.screenshot({ path: 'tests/screenshots/spread-grid.png', fullPage: true });
|
||||
|
||||
// Check if spread grid is visible
|
||||
const spreadButtons = page.locator('button').filter({ hasText: /^[+-]?\d+\.?\d*$/ });
|
||||
const count = await spreadButtons.count();
|
||||
console.log(`Found ${count} spread buttons`);
|
||||
|
||||
// Try to create a bet by clicking an empty spread
|
||||
if (count > 0) {
|
||||
await spreadButtons.first().click({ timeout: 5000 }).catch(() => {
|
||||
console.log('Could not click spread button - might be occupied');
|
||||
});
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: 'tests/screenshots/create-bet-modal.png', fullPage: true });
|
||||
}
|
||||
}
|
||||
|
||||
if (pageErrors.length > 0) {
|
||||
console.log('Page Errors during spread betting flow:', pageErrors.map(e => e.message));
|
||||
}
|
||||
|
||||
expect(pageErrors.length).toBe(0);
|
||||
});
|
||||
});
|
||||
65
frontend/tests/browser-errors.spec.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('Capture actual browser errors', async ({ page }) => {
|
||||
console.log('\n=== CAPTURING ALL BROWSER CONSOLE OUTPUT ===\n');
|
||||
|
||||
const allMessages: any[] = [];
|
||||
|
||||
page.on('console', msg => {
|
||||
const msgData = {
|
||||
type: msg.type(),
|
||||
text: msg.text(),
|
||||
location: msg.location()
|
||||
};
|
||||
allMessages.push(msgData);
|
||||
|
||||
const prefix = msg.type() === 'error' ? '❌ ERROR' :
|
||||
msg.type() === 'warning' ? '⚠️ WARNING' :
|
||||
msg.type() === 'log' ? '📝 LOG' :
|
||||
`ℹ️ ${msg.type().toUpperCase()}`;
|
||||
|
||||
console.log(`${prefix}: ${msg.text()}`);
|
||||
if (msg.location().url) {
|
||||
console.log(` Location: ${msg.location().url}:${msg.location().lineNumber}`);
|
||||
}
|
||||
});
|
||||
|
||||
page.on('pageerror', error => {
|
||||
console.log(`\n💥 PAGE ERROR: ${error.message}`);
|
||||
console.log(` Stack: ${error.stack}\n`);
|
||||
});
|
||||
|
||||
page.on('requestfailed', request => {
|
||||
console.log(`\n🔴 REQUEST FAILED: ${request.url()}`);
|
||||
console.log(` Failure: ${request.failure()?.errorText}\n`);
|
||||
});
|
||||
|
||||
console.log('\nLoading: /\n');
|
||||
|
||||
try {
|
||||
await page.goto('/', { waitUntil: 'networkidle', timeout: 30000 });
|
||||
} catch (e) {
|
||||
console.log(`\n❌ Failed to load page: ${e}\n`);
|
||||
}
|
||||
|
||||
// Wait a bit more to capture any delayed errors
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('\n=== SUMMARY ===');
|
||||
console.log(`Total console messages: ${allMessages.length}`);
|
||||
console.log(`Errors: ${allMessages.filter(m => m.type === 'error').length}`);
|
||||
console.log(`Warnings: ${allMessages.filter(m => m.type === 'warning').length}`);
|
||||
|
||||
const errors = allMessages.filter(m => m.type === 'error');
|
||||
if (errors.length > 0) {
|
||||
console.log('\n=== ALL ERRORS ===');
|
||||
errors.forEach((err, i) => {
|
||||
console.log(`\n${i + 1}. ${err.text}`);
|
||||
if (err.location.url) {
|
||||
console.log(` ${err.location.url}:${err.location.lineNumber}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await page.screenshot({ path: 'tests/screenshots/browser-state.png', fullPage: true });
|
||||
});
|
||||
88
frontend/tests/debug.spec.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Debug application errors', async ({ page }) => {
|
||||
// Collect all console messages
|
||||
const consoleMessages: Array<{ type: string; text: string }> = [];
|
||||
page.on('console', msg => {
|
||||
consoleMessages.push({
|
||||
type: msg.type(),
|
||||
text: msg.text()
|
||||
});
|
||||
});
|
||||
|
||||
// Collect page errors
|
||||
const pageErrors: Error[] = [];
|
||||
page.on('pageerror', error => {
|
||||
pageErrors.push(error);
|
||||
});
|
||||
|
||||
// Collect network errors
|
||||
const networkErrors: Array<{ url: string; status: number }> = [];
|
||||
page.on('response', response => {
|
||||
if (response.status() >= 400) {
|
||||
networkErrors.push({
|
||||
url: response.url(),
|
||||
status: response.status()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\n=== Loading Homepage ===');
|
||||
await page.goto('/');
|
||||
|
||||
// Wait a bit for any errors to show up
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Take screenshot
|
||||
await page.screenshot({ path: 'tests/screenshots/debug-homepage.png', fullPage: true });
|
||||
|
||||
// Print all collected information
|
||||
console.log('\n=== Console Messages ===');
|
||||
consoleMessages.forEach(msg => {
|
||||
console.log(`[${msg.type.toUpperCase()}] ${msg.text}`);
|
||||
});
|
||||
|
||||
console.log('\n=== Page Errors ===');
|
||||
if (pageErrors.length > 0) {
|
||||
pageErrors.forEach(error => {
|
||||
console.log(`ERROR: ${error.message}`);
|
||||
console.log(`Stack: ${error.stack}`);
|
||||
});
|
||||
} else {
|
||||
console.log('No page errors!');
|
||||
}
|
||||
|
||||
console.log('\n=== Network Errors ===');
|
||||
if (networkErrors.length > 0) {
|
||||
networkErrors.forEach(error => {
|
||||
console.log(`${error.status} - ${error.url}`);
|
||||
});
|
||||
} else {
|
||||
console.log('No network errors!');
|
||||
}
|
||||
|
||||
// Check if the page has rendered properly
|
||||
console.log('\n=== Page Content Check ===');
|
||||
const bodyText = await page.textContent('body');
|
||||
console.log(`Page has content: ${bodyText ? 'YES' : 'NO'}`);
|
||||
console.log(`Body text length: ${bodyText?.length || 0} characters`);
|
||||
|
||||
// Try to find the H2H title
|
||||
const h2hTitle = await page.locator('h1:has-text("H2H")').count();
|
||||
console.log(`Found H2H title: ${h2hTitle > 0 ? 'YES' : 'NO'}`);
|
||||
|
||||
// Check for error messages in the page
|
||||
const errorText = bodyText?.toLowerCase() || '';
|
||||
if (errorText.includes('error') || errorText.includes('failed')) {
|
||||
console.log(`\nWARNING: Page contains error text!`);
|
||||
console.log('First 500 chars of body:', bodyText?.substring(0, 500));
|
||||
}
|
||||
|
||||
// Verify no critical errors
|
||||
const criticalErrors = pageErrors.filter(e =>
|
||||
!e.message.includes('Warning') &&
|
||||
!e.message.includes('DevTools')
|
||||
);
|
||||
|
||||
expect(criticalErrors.length).toBe(0);
|
||||
});
|
||||
97
frontend/tests/e2e-spread-betting.spec.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('End-to-End Spread Betting Flow', () => {
|
||||
test('should allow admin to create event and user to place bet', async ({ page, context }) => {
|
||||
// Track errors
|
||||
const pageErrors: string[] = [];
|
||||
page.on('pageerror', error => {
|
||||
pageErrors.push(error.message);
|
||||
});
|
||||
|
||||
console.log('\n=== Step 1: Login as Admin ===');
|
||||
await page.goto('/login');
|
||||
await page.fill('input[type="email"]', 'admin@h2h.com');
|
||||
await page.fill('input[type="password"]', 'admin123');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-01-admin-login.png', fullPage: true });
|
||||
console.log('✓ Admin logged in successfully');
|
||||
|
||||
console.log('\n=== Step 2: Navigate to Admin Panel ===');
|
||||
const adminLink = page.getByRole('link', { name: /admin/i });
|
||||
if (await adminLink.isVisible()) {
|
||||
await adminLink.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-02-admin-panel.png', fullPage: true });
|
||||
console.log('✓ Admin panel loaded');
|
||||
} else {
|
||||
console.log('! Admin link not visible - user might not have admin privileges');
|
||||
}
|
||||
|
||||
console.log('\n=== Step 3: View Sport Events on Home Page ===');
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-03-sport-events.png', fullPage: true });
|
||||
console.log('✓ Sport events page loaded');
|
||||
|
||||
// Count available events in the table
|
||||
const eventRows = page.locator('.divide-y button');
|
||||
const eventCount = await eventRows.count();
|
||||
console.log(`✓ Found ${eventCount} sport events`);
|
||||
|
||||
if (eventCount > 0) {
|
||||
console.log('\n=== Step 4: View Event Spread Grid ===');
|
||||
await eventRows.first().click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-04-spread-grid.png', fullPage: true });
|
||||
console.log('✓ Spread grid displayed');
|
||||
|
||||
// Check for spread grid
|
||||
const gridExists = await page.locator('.grid').count() > 0;
|
||||
console.log(`Grid container found: ${gridExists}`);
|
||||
|
||||
// Log page content for debugging
|
||||
const pageContent = await page.textContent('body');
|
||||
if (pageContent?.includes('Wake Forest') || pageContent?.includes('Lakers') || pageContent?.includes('Chiefs')) {
|
||||
console.log('✓ Event details are visible on page');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n=== Step 5: Logout and Login as Regular User ===');
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('button', { name: /logout/i }).click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-05-logged-out.png', fullPage: true });
|
||||
console.log('✓ Logged out successfully');
|
||||
|
||||
// Login as Alice
|
||||
await page.goto('/login');
|
||||
await page.fill('input[type="email"]', 'alice@example.com');
|
||||
await page.fill('input[type="password"]', 'password123');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-06-alice-login.png', fullPage: true });
|
||||
console.log('✓ Alice logged in successfully');
|
||||
|
||||
console.log('\n=== Step 6: Alice Views Sport Events on Home ===');
|
||||
// Events are now on the home page
|
||||
await expect(page.getByRole('heading', { name: 'Upcoming Events' })).toBeVisible({ timeout: 5000 });
|
||||
await page.screenshot({ path: 'tests/screenshots/e2e-07-alice-events.png', fullPage: true });
|
||||
console.log('✓ Alice can view sport events');
|
||||
|
||||
console.log('\n=== Error Summary ===');
|
||||
if (pageErrors.length > 0) {
|
||||
console.log('Page Errors:', pageErrors);
|
||||
} else {
|
||||
console.log('✓ No page errors!');
|
||||
}
|
||||
|
||||
// Verify no critical errors
|
||||
expect(pageErrors.length).toBe(0);
|
||||
});
|
||||
});
|
||||
46
frontend/tests/open-browser.spec.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('Open browser and wait for manual inspection', async ({ page }) => {
|
||||
console.log('\n🌐 Opening browser');
|
||||
console.log('📋 Watching console for errors...\n');
|
||||
|
||||
const errors: string[] = [];
|
||||
const warnings: string[] = [];
|
||||
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
const errorMsg = msg.text();
|
||||
errors.push(errorMsg);
|
||||
console.log(`❌ ERROR: ${errorMsg}`);
|
||||
} else if (msg.type() === 'warning') {
|
||||
warnings.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
page.on('pageerror', error => {
|
||||
const errorMsg = `PAGE ERROR: ${error.message}`;
|
||||
errors.push(errorMsg);
|
||||
console.log(`\n💥 ${errorMsg}`);
|
||||
console.log(`Stack: ${error.stack}\n`);
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
|
||||
console.log('\n✅ Page loaded');
|
||||
console.log('⏳ Waiting 10 seconds to capture any async errors...\n');
|
||||
|
||||
await page.waitForTimeout(10000);
|
||||
|
||||
console.log('\n📊 FINAL REPORT:');
|
||||
console.log(` Errors: ${errors.length}`);
|
||||
console.log(` Warnings: ${warnings.length}`);
|
||||
|
||||
if (errors.length > 0) {
|
||||
console.log('\n🔴 ERRORS FOUND:');
|
||||
errors.forEach((err, i) => console.log(` ${i + 1}. ${err}`));
|
||||
} else {
|
||||
console.log('\n✅ NO ERRORS FOUND!');
|
||||
}
|
||||
|
||||
await page.screenshot({ path: 'tests/screenshots/final-browser-state.png', fullPage: true });
|
||||
});
|
||||
BIN
frontend/tests/screenshots/after-login.png
Normal file
|
After Width: | Height: | Size: 542 KiB |
BIN
frontend/tests/screenshots/browser-state.png
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
frontend/tests/screenshots/create-bet-modal.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
frontend/tests/screenshots/debug-homepage.png
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
frontend/tests/screenshots/e2e-01-admin-login.png
Normal file
|
After Width: | Height: | Size: 542 KiB |
BIN
frontend/tests/screenshots/e2e-02-admin-panel.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
frontend/tests/screenshots/e2e-03-sport-events.png
Normal file
|
After Width: | Height: | Size: 542 KiB |
BIN
frontend/tests/screenshots/e2e-04-spread-grid.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
frontend/tests/screenshots/e2e-05-logged-out.png
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
frontend/tests/screenshots/e2e-06-alice-login.png
Normal file
|
After Width: | Height: | Size: 541 KiB |
BIN
frontend/tests/screenshots/e2e-07-alice-events.png
Normal file
|
After Width: | Height: | Size: 541 KiB |
BIN
frontend/tests/screenshots/events-list.png
Normal file
|
After Width: | Height: | Size: 541 KiB |
BIN
frontend/tests/screenshots/final-browser-state.png
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
frontend/tests/screenshots/flow-01-homepage.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
frontend/tests/screenshots/flow-02-login.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
frontend/tests/screenshots/flow-03-logged-in.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
frontend/tests/screenshots/flow-04-events-home.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
frontend/tests/screenshots/flow-04-sport-events.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
frontend/tests/screenshots/flow-05-spread-grid.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
frontend/tests/screenshots/flow-06-alice-login.png
Normal file
|
After Width: | Height: | Size: 238 KiB |
BIN
frontend/tests/screenshots/homepage.png
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
frontend/tests/screenshots/login.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
frontend/tests/screenshots/sport-events-list.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
frontend/tests/screenshots/sport-events.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
frontend/tests/screenshots/spread-grid.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
108
frontend/tests/simple-flow.spec.ts
Normal file
@ -0,0 +1,108 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Complete application flow verification', async ({ page }) => {
|
||||
const errors: string[] = [];
|
||||
page.on('pageerror', error => errors.push(`PAGE ERROR: ${error.message}`));
|
||||
|
||||
console.log('\n====================================');
|
||||
console.log(' TESTING H2H APPLICATION');
|
||||
console.log('====================================\n');
|
||||
|
||||
// Test 1: Homepage loads
|
||||
console.log('TEST 1: Loading homepage...');
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const title = await page.title();
|
||||
console.log(`✓ Homepage loaded: "${title}"`);
|
||||
await page.screenshot({ path: 'tests/screenshots/flow-01-homepage.png' });
|
||||
|
||||
// Test 2: Can navigate to login (button in header now)
|
||||
console.log('\nTEST 2: Navigating to login...');
|
||||
await page.getByRole('link', { name: /log in/i }).first().click();
|
||||
await page.waitForURL('**/login');
|
||||
console.log('✓ Login page loaded');
|
||||
await page.screenshot({ path: 'tests/screenshots/flow-02-login.png' });
|
||||
|
||||
// Test 3: Can login as admin
|
||||
console.log('\nTEST 3: Logging in as admin...');
|
||||
await page.fill('input[type="email"]', 'admin@h2h.com');
|
||||
await page.fill('input[type="password"]', 'admin123');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
const currentUrl = page.url();
|
||||
console.log(`✓ Logged in successfully, redirected to: ${currentUrl}`);
|
||||
await page.screenshot({ path: 'tests/screenshots/flow-03-logged-in.png' });
|
||||
|
||||
// Test 4: Check navigation links (events are now on home page)
|
||||
console.log('\nTEST 4: Checking available navigation links...');
|
||||
const links = await page.locator('nav a').allTextContents();
|
||||
console.log('Available links:', links);
|
||||
const hasAdmin = links.some(l => l.toLowerCase().includes('admin'));
|
||||
const hasMyBets = links.some(l => l.toLowerCase().includes('my bets'));
|
||||
const hasWallet = links.some(l => l.toLowerCase().includes('wallet'));
|
||||
console.log(` - Admin link: ${hasAdmin ? '✓ Found' : '✗ Not found'}`);
|
||||
console.log(` - My Bets link: ${hasMyBets ? '✓ Found' : '✗ Not found'}`);
|
||||
console.log(` - Wallet link: ${hasWallet ? '✓ Found' : '✗ Not found'}`);
|
||||
|
||||
// Test 5: Home page shows events for authenticated users
|
||||
console.log('\nTEST 5: Checking events on home page...');
|
||||
await expect(page.getByRole('heading', { name: 'Upcoming Events' })).toBeVisible({ timeout: 5000 });
|
||||
console.log('✓ Upcoming Events section visible');
|
||||
|
||||
// Check for events in the table
|
||||
const eventRows = page.locator('.divide-y button');
|
||||
const eventCount = await eventRows.count();
|
||||
console.log(`✓ Found ${eventCount} sport events`);
|
||||
await page.screenshot({ path: 'tests/screenshots/flow-04-events-home.png' });
|
||||
|
||||
if (eventCount > 0) {
|
||||
console.log('\nTEST 6: Viewing event spread grid...');
|
||||
await eventRows.first().click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log('✓ Event details loaded');
|
||||
await page.screenshot({ path: 'tests/screenshots/flow-05-spread-grid.png' });
|
||||
|
||||
// Check if spread grid is visible
|
||||
const bodyText = await page.textContent('body');
|
||||
const hasEventName = bodyText?.includes('Wake Forest') || bodyText?.includes('Lakers') || bodyText?.includes('Chiefs');
|
||||
console.log(` - Event details visible: ${hasEventName ? '✓ Yes' : '✗ No'}`);
|
||||
|
||||
// Go back to home
|
||||
await page.click('button:has-text("Back to Events")');
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
// Test 7: Can login as regular user
|
||||
console.log('\nTEST 7: Testing regular user login...');
|
||||
await page.getByRole('button', { name: /logout/i }).click();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto('/login');
|
||||
await page.fill('input[type="email"]', 'alice@example.com');
|
||||
await page.fill('input[type="password"]', 'password123');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
console.log('✓ Alice logged in successfully');
|
||||
await page.screenshot({ path: 'tests/screenshots/flow-06-alice-login.png' });
|
||||
|
||||
// Check alice's navigation - should NOT have admin link
|
||||
const aliceLinks = await page.locator('nav a').allTextContents();
|
||||
const aliceHasAdmin = aliceLinks.some(l => l.toLowerCase().includes('admin'));
|
||||
console.log(` - Admin link for Alice: ${aliceHasAdmin ? '✗ SHOULD NOT BE VISIBLE' : '✓ Correctly hidden'}`);
|
||||
|
||||
console.log('\n====================================');
|
||||
console.log(' ERROR SUMMARY');
|
||||
console.log('====================================');
|
||||
if (errors.length > 0) {
|
||||
console.log('\nErrors found:');
|
||||
errors.forEach(e => console.log(` ✗ ${e}`));
|
||||
} else {
|
||||
console.log('\n✓ NO ERRORS - Application is working correctly!');
|
||||
}
|
||||
console.log('\n====================================\n');
|
||||
|
||||
// Final assertion
|
||||
expect(errors.length).toBe(0);
|
||||
});
|
||||