Files
blackcanyontickets/reactrebuild0825/tests/auth.spec.ts
dzinesco aa81eb5adb feat: add advanced analytics and territory management system
- 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>
2025-08-26 09:25:10 -06:00

262 lines
9.6 KiB
TypeScript

import path from 'path';
import { test, expect } from '@playwright/test';
import type { Page } from '@playwright/test';
const DEMO_ACCOUNTS = {
admin: { email: 'admin@example.com', password: 'demo123' },
organizer: { email: 'organizer@example.com', password: 'demo123' },
staff: { email: 'staff@example.com', password: 'demo123' },
};
async function takeScreenshot(page: Page, name: string) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const fileName = `auth_${name}_${timestamp}.png`;
await page.screenshot({
path: path.join('screenshots', fileName),
fullPage: true
});
return fileName;
}
async function clearAuthStorage(page: Page) {
await page.evaluate(() => {
localStorage.removeItem('bct_auth_user');
localStorage.removeItem('bct_auth_remember');
});
}
test.describe('Authentication Flows', () => {
test.beforeEach(async ({ page }) => {
// Clear any existing auth state
await clearAuthStorage(page);
await page.goto('/');
});
test('should redirect to login when accessing protected route', async ({ page }) => {
await page.goto('/dashboard');
// Should redirect to login page
await expect(page).toHaveURL('/login');
await expect(page.locator('h1')).toContainText('Sign In');
await takeScreenshot(page, 'protected-route-redirect');
});
test('should login successfully with valid admin credentials', async ({ page }) => {
await page.goto('/login');
await takeScreenshot(page, 'login-page-initial');
// Fill in admin credentials
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password);
await takeScreenshot(page, 'login-form-filled');
// Submit login form
await page.click('[data-testid="login-button"]');
// Wait for loading state
await expect(page.locator('[data-testid="login-button"]')).toBeDisabled();
await takeScreenshot(page, 'login-loading-state');
// Should redirect to dashboard
await expect(page).toHaveURL('/dashboard', { timeout: 10000 });
// Verify user is logged in
await expect(page.locator('[data-testid="user-menu"]')).toBeVisible();
await expect(page.locator('[data-testid="user-name"]')).toContainText('Sarah Admin');
await takeScreenshot(page, 'dashboard-logged-in-admin');
});
test('should login successfully with organizer credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.organizer.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.organizer.password);
await page.click('[data-testid="login-button"]');
await expect(page).toHaveURL('/dashboard', { timeout: 10000 });
await expect(page.locator('[data-testid="user-name"]')).toContainText('John Organizer');
await takeScreenshot(page, 'dashboard-logged-in-organizer');
});
test('should login successfully with staff credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.staff.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.staff.password);
await page.click('[data-testid="login-button"]');
await expect(page).toHaveURL('/dashboard', { timeout: 10000 });
await expect(page.locator('[data-testid="user-name"]')).toContainText('Emma Staff');
await takeScreenshot(page, 'dashboard-logged-in-staff');
});
test('should show error for invalid credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email-input"]', 'invalid@example.com');
await page.fill('[data-testid="password-input"]', 'wrongpassword');
await page.click('[data-testid="login-button"]');
// Should show error message
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
await expect(page.locator('[data-testid="error-message"]')).toContainText('Invalid email or password');
// Should remain on login page
await expect(page).toHaveURL('/login');
await takeScreenshot(page, 'login-error-state');
});
test('should show error for short password', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email);
await page.fill('[data-testid="password-input"]', '12'); // Too short
await page.click('[data-testid="login-button"]');
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
await expect(page.locator('[data-testid="error-message"]')).toContainText('Invalid email or password');
await takeScreenshot(page, 'login-short-password-error');
});
test('should toggle password visibility', async ({ page }) => {
await page.goto('/login');
const passwordInput = page.locator('[data-testid="password-input"]');
const toggleButton = page.locator('[data-testid="password-toggle"]');
// Password should be hidden initially
await expect(passwordInput).toHaveAttribute('type', 'password');
await page.fill('[data-testid="password-input"]', 'testpassword');
await takeScreenshot(page, 'password-hidden');
// Click toggle to show password
await toggleButton.click();
await expect(passwordInput).toHaveAttribute('type', 'text');
await takeScreenshot(page, 'password-visible');
// Click toggle to hide password again
await toggleButton.click();
await expect(passwordInput).toHaveAttribute('type', 'password');
});
test('should remember login when remember me is checked', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password);
// Check remember me
await page.check('[data-testid="remember-me"]');
await takeScreenshot(page, 'remember-me-checked');
await page.click('[data-testid="login-button"]');
await expect(page).toHaveURL('/dashboard', { timeout: 10000 });
// Verify localStorage has auth data
const authData = await page.evaluate(() => localStorage.getItem('bct_auth_user'));
const rememberMe = await page.evaluate(() => localStorage.getItem('bct_auth_remember'));
expect(authData).toBeTruthy();
expect(rememberMe).toBe('true');
// Refresh page - should stay logged in
await page.reload();
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('[data-testid="user-name"]')).toContainText('Sarah Admin');
await takeScreenshot(page, 'persistent-login-after-refresh');
});
test('should logout successfully', async ({ page }) => {
// First login
await page.goto('/login');
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password);
await page.click('[data-testid="login-button"]');
await expect(page).toHaveURL('/dashboard', { timeout: 10000 });
// Open user menu and logout
await page.click('[data-testid="user-menu"]');
await takeScreenshot(page, 'user-menu-open');
await page.click('[data-testid="logout-button"]');
// Should redirect to login
await expect(page).toHaveURL('/login', { timeout: 10000 });
// Verify localStorage is cleared
const authData = await page.evaluate(() => localStorage.getItem('bct_auth_user'));
const rememberMe = await page.evaluate(() => localStorage.getItem('bct_auth_remember'));
expect(authData).toBeNull();
expect(rememberMe).toBeNull();
await takeScreenshot(page, 'logout-complete');
});
test('should redirect back to intended route after login', async ({ page }) => {
// Try to access events page directly
await page.goto('/events');
// Should redirect to login with return URL
await expect(page).toHaveURL('/login');
// Login
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password);
await page.click('[data-testid="login-button"]');
// Should redirect back to events page
await expect(page).toHaveURL('/events', { timeout: 10000 });
await takeScreenshot(page, 'redirect-to-intended-route');
});
test('should handle form validation', async ({ page }) => {
await page.goto('/login');
// Try to submit empty form
await page.click('[data-testid="login-button"]');
// Should show validation errors
await expect(page.locator('[data-testid="email-error"]')).toBeVisible();
await expect(page.locator('[data-testid="password-error"]')).toBeVisible();
await takeScreenshot(page, 'form-validation-errors');
// Fill invalid email
await page.fill('[data-testid="email-input"]', 'invalidemail');
await page.click('[data-testid="login-button"]');
await expect(page.locator('[data-testid="email-error"]')).toContainText('Invalid email');
await takeScreenshot(page, 'invalid-email-error');
});
test('should handle network errors gracefully', async ({ page }) => {
await page.goto('/login');
// Simulate network failure by blocking requests
await page.route('**/api/**', route => route.abort());
await page.fill('[data-testid="email-input"]', DEMO_ACCOUNTS.admin.email);
await page.fill('[data-testid="password-input"]', DEMO_ACCOUNTS.admin.password);
await page.click('[data-testid="login-button"]');
// Should show network error
await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
await takeScreenshot(page, 'network-error-state');
});
});