From 930e044144eef897225dd2ca7e1aa77e31ccb7e9 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Mon, 8 Sep 2025 22:18:25 -0700 Subject: [PATCH] remove: obsolete auth debug test infrastructure - Remove auth-debug.spec.ts (functionality merged into auth.spec.ts) - Remove auth-debug-setup.ts and auth-debug-teardown.ts - Remove AUTH-DEBUG-GUIDE.md and AUTH-DEBUG-SETUP-GUIDE.md documentation - Remove specialized playwright.auth.config.ts configuration - Consolidates testing into main E2E test suite for better maintainability --- tests/e2e/AUTH-DEBUG-GUIDE.md | 421 ---------------------------- tests/e2e/AUTH-DEBUG-SETUP-GUIDE.md | 316 --------------------- tests/e2e/auth-debug-setup.ts | 354 ----------------------- tests/e2e/auth-debug-teardown.ts | 403 -------------------------- tests/e2e/auth-debug.spec.ts | 390 -------------------------- tests/e2e/playwright.auth.config.ts | 158 ----------- 6 files changed, 2042 deletions(-) delete mode 100644 tests/e2e/AUTH-DEBUG-GUIDE.md delete mode 100644 tests/e2e/AUTH-DEBUG-SETUP-GUIDE.md delete mode 100644 tests/e2e/auth-debug-setup.ts delete mode 100644 tests/e2e/auth-debug-teardown.ts delete mode 100644 tests/e2e/auth-debug.spec.ts delete mode 100644 tests/e2e/playwright.auth.config.ts diff --git a/tests/e2e/AUTH-DEBUG-GUIDE.md b/tests/e2e/AUTH-DEBUG-GUIDE.md deleted file mode 100644 index b648190..0000000 --- a/tests/e2e/AUTH-DEBUG-GUIDE.md +++ /dev/null @@ -1,421 +0,0 @@ -# ๐Ÿ” Authentication Debug Testing Guide - -## Overview - -The authentication debug test suite (`auth-debug.spec.ts`) provides comprehensive automated testing and debugging capabilities for all authentication flows in the Medication Reminder App. This replaces the previous manual browser console debugging scripts with fully automated, cross-browser tests. - -## ๐ŸŽฏ What This Replaces - -### Before (Manual Tests) - -- `tests/manual/admin-login-debug.js` - Browser console script -- `tests/manual/auth-db-debug.js` - Database debugging script -- `tests/manual/debug-email-validation.js` - Email validation script - -### After (Automated Tests) - -- `tests/e2e/auth-debug.spec.ts` - Comprehensive E2E test suite -- Cross-browser automated testing -- CI/CD pipeline integration -- Interactive debugging capabilities - -## ๐Ÿงช Test Coverage - -### 1. Admin User Validation - -- Verifies admin@localhost account exists -- Tests admin login flow -- Validates admin permissions and UI access -- Checks admin interface functionality - -### 2. Email Format Validation - -- Tests various email formats including localhost domains -- Validates email input validation rules -- Covers edge cases and invalid formats -- Ensures proper error messaging - -### 3. User Registration - -- Tests user creation with password -- Validates registration form fields -- Checks verification flow -- Ensures unique user handling - -### 4. OAuth Integration - -- Verifies OAuth buttons are present -- Tests OAuth flow initiation -- Handles OAuth redirects and errors -- Validates OAuth user creation - -### 5. Database Connection - -- Checks system status indicators -- Validates database connectivity -- Ensures app loads properly -- Tests service health - -### 6. Password Security - -- Tests password strength requirements -- Validates weak password rejection -- Ensures strong password acceptance -- Checks security messaging - -### 7. Session Management - -- Tests session persistence across page reloads -- Validates login state maintenance -- Checks automatic logout scenarios -- Ensures proper session handling - -### 8. Error Handling - -- Tests invalid login attempts -- Validates error messaging -- Checks form validation -- Ensures proper feedback - -### 9. User Management - -- Tests admin user lookup functionality -- Validates user search capabilities -- Checks user list display -- Ensures admin tools work - -## ๐Ÿš€ Running Auth Debug Tests - -### Quick Commands - -```bash -# Run auth debug tests (headless) -make test-auth-debug - -# Run with interactive UI for debugging -make test-auth-debug-ui - -# Run specific test with debug mode -bunx playwright test auth-debug.spec.ts --debug - -# Run on specific browser -bunx playwright test auth-debug.spec.ts --project=auth-debug-firefox -``` - -### Full Command Options - -```bash -# All browsers with full reporting -bunx playwright test --config=tests/e2e/playwright.auth.config.ts - -# Single browser with trace -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --project=auth-debug-chromium --trace=on - -# Headed mode for visual debugging -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --headed - -# Debug specific failing test -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --debug -g "should validate admin user" -``` - -## ๐Ÿ”ง Test Configuration - -The auth debug tests use a specialized Playwright configuration (`playwright.auth.config.ts`) with: - -- **Extended timeouts** for auth operations (60s per test) -- **Sequential execution** to avoid auth conflicts -- **Enhanced reporting** with multiple output formats -- **Service auto-start** for dependencies -- **Cross-browser testing** on desktop and mobile -- **Detailed tracing** on failures - -### Browser Coverage - -- **Desktop**: Chrome, Firefox, Safari -- **Mobile**: Chrome on Android, Safari on iOS -- **Special configs** for auth-specific browser settings - -## ๐Ÿ“Š Reports and Output - -### Generated Reports - -1. **HTML Report**: `playwright-report-auth/index.html` - - Interactive test results - - Screenshots and videos - - Detailed failure analysis - -2. **JSON Report**: `playwright-report-auth.json` - - Machine-readable results - - Integration with CI/CD - - Detailed test metadata - -3. **Summary Report**: `auth-debug-summary.json` - - High-level test statistics - - Environment information - - Quick status overview - -4. **JUnit Report**: `playwright-auth-results.xml` - - CI/CD integration format - - Test result parsing - - Build system integration - -### Viewing Reports - -```bash -# Open HTML report -npx playwright show-report playwright-report-auth - -# View summary -cat auth-debug-summary.json | jq - -# Check specific failures -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --reporter=list -``` - -## ๐Ÿ› Debugging Workflows - -### Interactive Debugging - -```bash -# Launch interactive debug mode -make test-auth-debug-ui - -# Debug specific test -bunx playwright test auth-debug.spec.ts --debug -g "admin user" - -# Step through test with browser open -bunx playwright test auth-debug.spec.ts --headed --debug -``` - -### Common Debugging Scenarios - -#### 1. Admin Login Issues - -```bash -# Debug admin login specifically -bunx playwright test --debug -g "should validate admin user exists" - -# Check with different browser -bunx playwright test --project=auth-debug-firefox --debug -g "admin user" -``` - -#### 2. Email Validation Problems - -```bash -# Debug email validation -bunx playwright test --debug -g "email format" - -# Run with console output -bunx playwright test -g "email format" --reporter=line -``` - -#### 3. OAuth Flow Issues - -```bash -# Debug OAuth with network logs -bunx playwright test --debug -g "OAuth" --trace=on - -# Check OAuth buttons -bunx playwright test --headed -g "OAuth user creation" -``` - -#### 4. Database Connection Problems - -```bash -# Debug database connectivity -bunx playwright test --debug -g "database connection" - -# Check service status -bunx playwright test -g "database" --reporter=line -``` - -### Debug Output Interpretation - -The tests include extensive console logging: - -``` -Testing email validation for: admin@localhost -โœ… Admin user verified and functional -โš ๏ธ Search functionality not implemented - this is optional -Testing weak password (too short): 123 -๐Ÿ“Š Found 1 users in the system -``` - -**Log Levels:** - -- `โœ…` Success/verification messages -- `โš ๏ธ` Warnings (expected issues) -- `โŒ` Errors requiring attention -- `๐Ÿ“Š` Information and statistics - -## ๐Ÿ”„ CI/CD Integration - -### Pipeline Configuration - -```yaml -# GitHub Actions example -name: Auth Debug Tests -on: [push, pull_request] - -jobs: - auth-tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - - run: bun install - - run: bunx playwright install --with-deps - - run: make test-auth-debug - - uses: actions/upload-artifact@v3 - if: always() - with: - name: auth-test-results - path: | - playwright-report-auth/ - auth-debug-summary.json -``` - -### Environment Variables - -```bash -# Required for CI -NODE_ENV=test -CI=true -VITE_COUCHDB_URL=http://localhost:5984 -VITE_COUCHDB_USERNAME=admin -VITE_COUCHDB_PASSWORD=password -``` - -## ๐Ÿ› ๏ธ Maintenance and Updates - -### Adding New Auth Tests - -1. **Add test case** to `auth-debug.spec.ts` -2. **Follow naming convention**: `should [action] [expected result]` -3. **Include console logging** for debugging -4. **Handle timeouts** appropriately -5. **Clean up test data** if needed - -### Example New Test - -```typescript -test('should validate two-factor authentication', async ({ page }) => { - console.log('Testing 2FA validation...'); - - // Test implementation - await page.fill('input[type="email"]', 'admin@localhost'); - await page.fill('input[type="password"]', 'admin123!'); - await page.click('button[type="submit"]'); - - // Check for 2FA prompt - await expect(page.locator('text=Enter verification code')).toBeVisible({ - timeout: 10000, - }); - - console.log('โœ… 2FA prompt displayed correctly'); -}); -``` - -### Updating Test Credentials - -If admin credentials change, update: - -- Test files: `auth-debug.spec.ts` -- Setup files: `auth-debug-setup.ts` -- Documentation: This guide - -## ๐Ÿšจ Troubleshooting - -### Common Issues - -#### 1. Tests Timeout - -**Symptoms**: Tests hang or timeout -**Solutions**: - -- Check service availability (`http://localhost:8080`, `http://localhost:5984`) -- Increase timeouts in config -- Run with `--headed` to see what's happening - -#### 2. Admin User Not Found - -**Symptoms**: Admin login fails -**Solutions**: - -- Verify admin user exists in database -- Check credentials in test file -- Run database initialization - -#### 3. Service Not Ready - -**Symptoms**: Cannot connect to app/database -**Solutions**: - -- Start services manually: `make dev` and CouchDB -- Check Docker containers -- Verify ports are not blocked - -#### 4. Browser Issues - -**Symptoms**: Tests fail in specific browsers -**Solutions**: - -- Update Playwright: `bunx playwright install` -- Check browser-specific configurations -- Run single browser: `--project=auth-debug-chromium` - -### Debug Commands - -```bash -# Check service status -curl http://localhost:8080 -curl http://localhost:5984 - -# Verify test setup -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --list - -# Run with maximum verbosity -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --reporter=line --verbose - -# Check configuration -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --reporter=json | jq '.config' -``` - -## ๐Ÿ“š Related Documentation - -- **Main E2E Guide**: `tests/e2e/README.md` -- **Test Cleanup Info**: `tests/README-CLEANUP.md` -- **Migration Summary**: `CLEANUP-SUMMARY.md` -- **Quick Reference**: `QUICK-REFERENCE.md` - -## ๐Ÿ’ก Best Practices - -### Writing Auth Tests - -1. **Use unique identifiers** (timestamps) for test data -2. **Include descriptive console logging** -3. **Handle both success and failure cases** -4. **Clean up test artifacts** -5. **Use appropriate timeouts** - -### Debugging Process - -1. **Start with interactive mode** (`--ui` or `--debug`) -2. **Check service availability** first -3. **Review console logs** for clues -4. **Use browser dev tools** when needed -5. **Isolate failing tests** - -### Maintenance - -1. **Run tests regularly** to catch regressions -2. **Update credentials** when changed -3. **Add tests for new auth features** -4. **Monitor test performance** -5. **Review failure patterns** - ---- - -**Quick Start**: Run `make test-auth-debug-ui` to launch interactive debugging mode and explore the authentication flows visually. - -**Need Help?**: Check the generated HTML report for detailed test results and failure analysis. diff --git a/tests/e2e/AUTH-DEBUG-SETUP-GUIDE.md b/tests/e2e/AUTH-DEBUG-SETUP-GUIDE.md deleted file mode 100644 index 70574f3..0000000 --- a/tests/e2e/AUTH-DEBUG-SETUP-GUIDE.md +++ /dev/null @@ -1,316 +0,0 @@ -# Authentication Debug Setup Guide - -This guide explains the `auth-debug-setup.ts` file and how to use it for debugging authentication flows in the Medication Reminder application. - -## Overview - -The `auth-debug-setup.ts` file is a Playwright global setup script specifically designed for debugging authentication-related issues. It ensures that all required services are running and properly configured before running authentication tests. - -## What It Does - -### ๐Ÿ”ง Service Initialization - -- **Frontend Service**: Verifies the app is running on `http://localhost:8080` -- **CouchDB Database**: Ensures CouchDB is accessible on `http://localhost:5984` -- **Database Setup**: Creates necessary databases if they don't exist -- **Admin User Verification**: Tests admin login functionality end-to-end - -### ๐Ÿ“Š Diagnostics - -- **Service Health Checks**: Comprehensive connectivity testing -- **Database Status**: Lists available databases and connection status -- **Environment Information**: Logs Node.js version, platform, and environment variables -- **Network Connectivity**: Tests various endpoints for accessibility - -## File Structure - -```typescript -// Main setup functions -globalSetup(); // Orchestrates all setup tasks -waitForServices(); // Waits for services to be ready -initializeTestData(); // Creates required databases -verifyAdminUser(); // Tests admin login flow -logEnvironmentInfo(); // Logs debugging information - -// Diagnostic utilities -runServiceDiagnostics(); // Comprehensive service testing -testDatabaseConnectivity(); // Detailed database status -``` - -## Configuration - -### Required Services - -Before running auth debug tests, ensure these services are running: - -1. **Frontend Application** - - ```bash - bun run dev - # Runs on http://localhost:8080 - ``` - -2. **CouchDB Database** - - ```bash - docker-compose -f docker/docker-compose.yaml up -d - # Runs on http://localhost:5984 - ``` - -### Environment Variables - -The setup respects these environment variables: - -- `NODE_ENV`: Environment mode (development/test/production) -- `CI`: CI/CD environment flag -- `DEBUG_MODE`: Enables additional debugging features - -### Database Configuration - -The setup creates these databases automatically: - -- `users` - User accounts and authentication data -- `medications` - Medication information -- `settings` - Application settings -- `taken_doses` - Medication intake records -- `reminders` - Reminder configurations - -### Default Credentials - -The setup uses these default credentials for testing: - -- **CouchDB**: `admin:password` -- **Test Admin User**: `admin@localhost:admin123!` - -## Usage - -### Running Auth Debug Tests - -```bash -# Run auth debug tests specifically -bunx playwright test --config=tests/e2e/playwright.auth.config.ts - -# Run with UI for interactive debugging -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --ui - -# Run in debug mode -bunx playwright test --config=tests/e2e/playwright.auth.config.ts --debug -``` - -### Manual Setup Verification - -You can verify the setup manually: - -```bash -# Check frontend -curl http://localhost:8080 - -# Check CouchDB -curl -u admin:password http://localhost:5984 - -# List databases -curl -u admin:password http://localhost:5984/_all_dbs -``` - -## Troubleshooting - -### Common Issues - -#### 1. Services Not Ready - -**Symptoms**: Setup fails with service connection errors -**Solutions**: - -```bash -# Check if services are running -docker ps -netstat -tlnp | grep 8080 -netstat -tlnp | grep 5984 - -# Restart services -docker-compose -f docker/docker-compose.yaml restart -bun run dev -``` - -#### 2. Database Connection Failed - -**Symptoms**: CouchDB authentication or connection errors -**Solutions**: - -```bash -# Check CouchDB logs -docker-compose -f docker/docker-compose.yaml logs couchdb - -# Reset CouchDB data -docker-compose -f docker/docker-compose.yaml down -v -docker-compose -f docker/docker-compose.yaml up -d -``` - -#### 3. Admin User Not Found - -**Symptoms**: Admin login verification fails -**Solutions**: - -- Check if admin user exists in the users database -- Verify credentials match the expected format -- Create admin user manually if needed - -#### 4. Timeout Issues - -**Symptoms**: Setup times out waiting for services -**Solutions**: - -```bash -# Increase timeout values in setup -# Check system resources -free -h -docker stats - -# Reduce parallel processes -pkill -f "node.*vite" -pkill -f "playwright" -``` - -### Debug Logs - -The setup provides detailed logging at different levels: - -```typescript -// Enable debug logging -logger.setLevel(LogLevel.DEBUG); - -// View specific context logs -logger.getLogs('SETUP'); -logger.getLogs('AUTH'); -logger.getLogs('DATABASE'); -``` - -### Diagnostic Output - -The setup generates comprehensive diagnostic information: - -``` -๐ŸŒ Environment Information: - Node.js: v18.17.0 - Platform: linux - NODE_ENV: test - CI: false - Frontend URL: http://localhost:8080 - CouchDB URL: http://localhost:5984 - -๐Ÿ” Running comprehensive service diagnostics... - Frontend status: 200 OK - Database connected with 5 databases - Health endpoint accessible - -โœ… Auth debug setup completed in 2847ms -``` - -## Integration with Test Suite - -### Playwright Configuration - -The setup integrates with `playwright.auth.config.ts`: - -```typescript -export default defineConfig({ - globalSetup: require.resolve('./auth-debug-setup.ts'), - globalTeardown: require.resolve('./auth-debug-teardown.ts'), - // ... other config -}); -``` - -### Test Dependencies - -Tests that depend on this setup: - -- `auth-debug.spec.ts` - Main authentication validation tests -- `admin.spec.ts` - Admin functionality tests -- `auth.spec.ts` - General authentication tests - -## Best Practices - -### 1. Environment Isolation - -- Use dedicated test databases -- Clean up test data between runs -- Avoid production credentials - -### 2. Robust Error Handling - -- Don't fail setup for non-critical issues -- Log warnings for optional features -- Provide helpful error messages - -### 3. Service Dependencies - -- Wait for all required services -- Test actual connectivity, not just port availability -- Verify service functionality, not just status - -### 4. Debugging Support - -- Comprehensive logging at appropriate levels -- Detailed diagnostic information -- Clear failure messages with next steps - -## Development - -### Modifying the Setup - -When modifying the setup script: - -1. **Test thoroughly** in different environments -2. **Maintain backward compatibility** with existing tests -3. **Update documentation** for any new features -4. **Add appropriate logging** for debugging - -### Adding New Services - -To add new service checks: - -```typescript -// Add to waitForServices() -await waitForService('http://localhost:9000', 'NewService'); - -// Add diagnostic check -async function checkNewService() { - // Implementation -} -``` - -### Environment-Specific Configuration - -For different environments: - -```typescript -const config = { - development: { - timeout: 60000, - retries: 3, - }, - ci: { - timeout: 120000, - retries: 5, - }, -}; -``` - -## Related Files - -- `auth-debug-teardown.ts` - Cleanup and reporting -- `auth-debug.spec.ts` - Main authentication tests -- `playwright.auth.config.ts` - Playwright configuration -- `AUTH-DEBUG-GUIDE.md` - Test execution guide - -## Support - -For issues with the auth debug setup: - -1. Check the diagnostic output for specific error messages -2. Verify all required services are running -3. Review the troubleshooting section above -4. Check related test files for configuration examples -5. Enable debug logging for detailed information - -The setup is designed to be self-diagnosing and should provide clear information about any issues encountered during initialization. diff --git a/tests/e2e/auth-debug-setup.ts b/tests/e2e/auth-debug-setup.ts deleted file mode 100644 index e70f9f1..0000000 --- a/tests/e2e/auth-debug-setup.ts +++ /dev/null @@ -1,354 +0,0 @@ -import { chromium } from 'playwright'; -import { logger } from '../../services/logging'; - -interface GlobalSetupConfig { - projects?: Array<{ - name: string; - use?: Record; - }>; - webServer?: Array<{ - command: string; - port: number; - timeout: number; - reuseExistingServer: boolean; - }>; - use?: { - baseURL?: string; - trace?: string; - screenshot?: string; - }; - [key: string]: unknown; -} - -/** - * Global setup for authentication debug tests - * Ensures services are running and database is properly initialized - */ -async function globalSetup(_config: GlobalSetupConfig) { - logger.info( - '๐Ÿ”ง Setting up authentication debug test environment...', - 'SETUP' - ); - - const startTime = Date.now(); - - try { - // Wait for services to be ready - await waitForServices(); - - // Initialize test data if needed - await initializeTestData(); - - // Verify admin user exists - await verifyAdminUser(); - - const duration = Date.now() - startTime; - logger.info(`โœ… Auth debug setup completed in ${duration}ms`, 'SETUP'); - } catch (error) { - logger.error('โŒ Auth debug setup failed:', 'SETUP', error); - throw error; - } -} - -/** - * Wait for required services to be available - */ -async function waitForServices(): Promise { - logger.info('โณ Waiting for services to be ready...', 'SETUP'); - - // Wait for frontend - await waitForService('http://localhost:8080', 'Frontend'); - - // Wait for CouchDB - await waitForService('http://localhost:5984', 'CouchDB'); - - logger.info('โœ… All services are ready', 'SETUP'); -} - -/** - * Wait for a specific service to be available - */ -async function waitForService(url: string, serviceName: string): Promise { - const maxAttempts = 30; - const delay = 2000; // 2 seconds - - for (let attempt = 1; attempt <= maxAttempts; attempt++) { - try { - const response = await fetch(url, { - method: 'GET', - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - signal: AbortSignal.timeout(5000), // 5 second timeout per request - }); - - if (response.ok) { - logger.info(`โœ… ${serviceName} is ready at ${url}`, 'SETUP'); - return; - } - } catch (error) { - // Log specific error types for better debugging - if (error instanceof Error) { - logger.debug( - `โณ ${serviceName} connection failed: ${error.message}`, - 'SETUP' - ); - } - } - - if (attempt === maxAttempts) { - throw new Error( - `${serviceName} not available at ${url} after ${maxAttempts} attempts` - ); - } - - logger.debug( - `โณ ${serviceName} not ready, attempt ${attempt}/${maxAttempts}...`, - 'SETUP' - ); - await new Promise(resolve => setTimeout(resolve, delay)); - } -} - -/** - * Initialize test data and ensure databases exist - */ -async function initializeTestData(): Promise { - logger.info('๐Ÿ”ง Initializing test data...', 'SETUP'); - - try { - // Check if databases exist, create if needed - const databases = [ - 'users', - 'medications', - 'settings', - 'taken_doses', - 'reminders', - ]; - - for (const dbName of databases) { - await ensureDatabaseExists(dbName); - } - - logger.info('โœ… Test data initialization completed', 'SETUP'); - } catch (error) { - logger.warn('โš ๏ธ Test data initialization had issues:', 'SETUP', error); - // Don't fail setup for database issues as the app should handle missing DBs - } -} - -/** - * Ensure a database exists - */ -async function ensureDatabaseExists(dbName: string): Promise { - const url = `http://localhost:5984/${dbName}`; - - try { - const response = await fetch(url, { - method: 'HEAD', - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - }); - - if (response.status === 404) { - // Database doesn't exist, create it - await fetch(url, { - method: 'PUT', - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - 'Content-Type': 'application/json', - }, - }); - logger.info(`๐Ÿ“Š Created database: ${dbName}`, 'SETUP'); - } else if (response.ok) { - logger.info(`โœ… Database exists: ${dbName}`, 'SETUP'); - } - } catch (error) { - logger.warn( - `โš ๏ธ Could not verify/create database ${dbName}:`, - 'SETUP', - error - ); - } -} - -/** - * Verify admin user exists for testing - */ -async function verifyAdminUser(): Promise { - logger.info('๐Ÿ”ง Verifying admin user exists...', 'SETUP'); - - try { - const browser = await chromium.launch(); - const context = await browser.newContext(); - const page = await context.newPage(); - - // Navigate to the app - await page.goto('http://localhost:8080'); - - // Wait for login form - await page.waitForSelector('input[type="email"]', { timeout: 10000 }); - - // Try to login with admin credentials - await page.fill('input[type="email"]', 'admin@localhost'); - await page.fill('input[type="password"]', 'admin123!'); - await page.click('button[type="submit"]'); - - // Check if login was successful - try { - await page.waitForSelector('h1:has-text("Medication Reminder")', { - timeout: 15000, - }); - logger.info('โœ… Admin user verified and functional', 'SETUP'); - } catch (error) { - logger.warn( - 'โš ๏ธ Admin user may not exist or credentials may be incorrect', - 'SETUP' - ); - logger.warn( - ' Tests will attempt to create/verify admin user during execution', - 'SETUP' - ); - if (error instanceof Error) { - logger.debug(`Login verification error: ${error.message}`, 'SETUP'); - } - } - - await browser.close(); - } catch (error) { - logger.warn('โš ๏ธ Could not verify admin user', 'SETUP'); - if (error instanceof Error) { - logger.debug(`Admin verification error: ${error.message}`, 'SETUP'); - } - // Don't fail setup, let individual tests handle this - } -} - -/** - * Log environment information - */ -function logEnvironmentInfo(): void { - logger.info('๐ŸŒ Environment Information:', 'SETUP'); - logger.info(` Node.js: ${process.version}`, 'SETUP'); - logger.info(` Platform: ${process.platform}`, 'SETUP'); - logger.info(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`, 'SETUP'); - logger.info(` CI: ${process.env.CI || 'false'}`, 'SETUP'); - logger.info(` Frontend URL: http://localhost:8080`, 'SETUP'); - logger.info(` CouchDB URL: http://localhost:5984`, 'SETUP'); -} - -/** - * Test database connectivity and return detailed status - */ -async function testDatabaseConnectivity(): Promise<{ - connected: boolean; - databases: string[]; - errors: string[]; -}> { - const result = { - connected: false, - databases: [] as string[], - errors: [] as string[], - }; - - try { - // Test basic connectivity - const response = await fetch('http://localhost:5984/', { - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - signal: AbortSignal.timeout(5000), - }); - - if (response.ok) { - result.connected = true; - const info = await response.json(); - logger.debug(`CouchDB version: ${info.version}`, 'SETUP'); - - // Get list of databases - const dbResponse = await fetch('http://localhost:5984/_all_dbs', { - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - }); - - if (dbResponse.ok) { - result.databases = await dbResponse.json(); - logger.debug( - `Found databases: ${result.databases.join(', ')}`, - 'SETUP' - ); - } - } else { - result.errors.push(`HTTP ${response.status}: ${response.statusText}`); - } - } catch (error) { - if (error instanceof Error) { - result.errors.push(error.message); - } - } - - return result; -} - -/** - * Perform comprehensive service diagnostics - */ -async function runServiceDiagnostics(): Promise { - logger.info('๐Ÿ” Running comprehensive service diagnostics...', 'SETUP'); - - // Test frontend - try { - const frontendResponse = await fetch('http://localhost:8080', { - signal: AbortSignal.timeout(5000), - }); - logger.info( - `Frontend status: ${frontendResponse.status} ${frontendResponse.statusText}`, - 'SETUP' - ); - } catch (error) { - logger.warn( - `Frontend not accessible: ${error instanceof Error ? error.message : 'Unknown error'}`, - 'SETUP' - ); - } - - // Test database with detailed info - const dbStatus = await testDatabaseConnectivity(); - if (dbStatus.connected) { - logger.info( - `Database connected with ${dbStatus.databases.length} databases`, - 'SETUP' - ); - } else { - logger.warn( - `Database connection failed: ${dbStatus.errors.join(', ')}`, - 'SETUP' - ); - } - - // Test network connectivity - try { - const response = await fetch('http://localhost:8080/health', { - signal: AbortSignal.timeout(3000), - }); - if (response.ok) { - logger.info('Health endpoint accessible', 'SETUP'); - } - } catch { - logger.debug('Health endpoint not available (this is optional)', 'SETUP'); - } -} - -// Execute setup -export default async function (config: GlobalSetupConfig) { - logEnvironmentInfo(); - await runServiceDiagnostics(); - await globalSetup(config); -} diff --git a/tests/e2e/auth-debug-teardown.ts b/tests/e2e/auth-debug-teardown.ts deleted file mode 100644 index c4dddc5..0000000 --- a/tests/e2e/auth-debug-teardown.ts +++ /dev/null @@ -1,403 +0,0 @@ -/* eslint-disable no-console */ - -interface GlobalTeardownConfig { - projects?: Array<{ - name: string; - use?: Record; - }>; - webServer?: Array<{ - command: string; - port: number; - timeout: number; - reuseExistingServer: boolean; - }>; - use?: { - baseURL?: string; - trace?: string; - screenshot?: string; - }; - [key: string]: unknown; -} - -/** - * Global teardown for authentication debug tests - * Cleans up test environment and generates summary report - */ -async function globalTeardown(_config: GlobalTeardownConfig) { - console.log('๐Ÿงน Starting authentication debug test teardown...'); - - const startTime = Date.now(); - - try { - // Clean up test data - await cleanupTestData(); - - // Generate test summary - await generateTestSummary(); - - // Clean up test artifacts - await cleanupTestArtifacts(); - - // Log final status - await logFinalStatus(); - - const duration = Date.now() - startTime; - console.log(`โœ… Auth debug teardown completed in ${duration}ms`); - } catch (error) { - console.error('โŒ Auth debug teardown failed:', error); - // Don't throw error to avoid masking test failures - } -} - -/** - * Clean up test data created during tests - */ -async function cleanupTestData(): Promise { - console.log('๐Ÿ—‘๏ธ Cleaning up test data...'); - - try { - // Clean up test users created during the test run - await cleanupTestUsers(); - - // Clean up any temporary files - await cleanupTempFiles(); - - console.log('โœ… Test data cleanup completed'); - } catch (error) { - console.warn('โš ๏ธ Test data cleanup had issues:', error); - } -} - -/** - * Remove test users created during testing - */ -async function cleanupTestUsers(): Promise { - console.log('๐Ÿ‘ฅ Cleaning up test users...'); - - try { - // Get list of databases - const response = await fetch('http://localhost:5984/_all_dbs', { - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - }); - - if (!response.ok) { - console.warn('โš ๏ธ Could not access CouchDB for user cleanup'); - return; - } - - // Look for users database - const databases = await response.json(); - if (databases.includes('users')) { - await cleanupUsersFromDatabase(); - } - - console.log('โœ… Test users cleanup completed'); - } catch (error) { - console.warn('โš ๏ธ Could not cleanup test users:', error); - } -} - -/** - * Clean up test users from the users database - */ -async function cleanupUsersFromDatabase(): Promise { - try { - // Get all users - const response = await fetch( - 'http://localhost:5984/users/_all_docs?include_docs=true', - { - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - } - ); - - if (!response.ok) { - return; - } - - const data = await response.json(); - const testUserPattern = - /debug-test.*@localhost|test.*@localhost|strong.*@localhost/; - - // Find and delete test users - for (const row of data.rows) { - if (row.doc && row.doc.email && testUserPattern.test(row.doc.email)) { - await deleteTestUser(row.doc._id, row.doc._rev); - } - } - } catch (error) { - console.warn('โš ๏ธ Error cleaning users database:', error); - } -} - -/** - * Delete a specific test user - */ -async function deleteTestUser(userId: string, rev: string): Promise { - try { - const response = await fetch( - `http://localhost:5984/users/${userId}?rev=${rev}`, - { - method: 'DELETE', - headers: { - Authorization: - 'Basic ' + Buffer.from('admin:password').toString('base64'), - }, - } - ); - - if (response.ok) { - console.log(`๐Ÿ—‘๏ธ Deleted test user: ${userId}`); - } - } catch (error) { - console.warn(`โš ๏ธ Could not delete test user ${userId}:`, error); - } -} - -/** - * Clean up temporary files created during tests - */ -async function cleanupTempFiles(): Promise { - console.log('๐Ÿ“‚ Cleaning up temporary files...'); - - try { - const fs = await import('fs').then(m => m.promises); - const path = await import('path'); - - // Clean up any temporary screenshots or videos from failed tests - const tempDirs = [ - 'test-results-auth', - 'playwright-report-auth', - 'screenshots-temp', - 'videos-temp', - ]; - - for (const dir of tempDirs) { - try { - const fullPath = path.join(process.cwd(), dir); - await fs.access(fullPath); - // Directory exists, but don't delete it as it may contain useful debug info - console.log(`๐Ÿ“ Preserved test artifacts in: ${dir}`); - } catch { - // Directory doesn't exist, which is fine - } - } - - console.log('โœ… Temporary files cleanup completed'); - } catch (error) { - console.warn('โš ๏ธ Temporary files cleanup had issues:', error); - } -} - -/** - * Generate test summary report - */ -async function generateTestSummary(): Promise { - console.log('๐Ÿ“Š Generating test summary...'); - - try { - const fs = await import('fs').then(m => m.promises); - const path = await import('path'); - - // Check if test results exist - const reportPath = path.join(process.cwd(), 'playwright-report-auth.json'); - - try { - await fs.access(reportPath); - const reportData = await fs.readFile(reportPath, 'utf-8'); - const report = JSON.parse(reportData); - - // Generate summary - const summary = { - timestamp: new Date().toISOString(), - testType: 'Authentication Debug', - totalTests: - report.suites?.reduce( - (total: number, suite: { specs?: unknown[] }) => - total + (suite.specs?.length || 0), - 0 - ) || 0, - passedTests: 0, - failedTests: 0, - skippedTests: 0, - duration: report.stats?.duration || 0, - environment: { - nodeVersion: process.version, - platform: process.platform, - ci: !!process.env.CI, - }, - }; - - // Count test results - if (report.suites) { - for (const suite of report.suites) { - if (suite.specs) { - for (const spec of suite.specs) { - if (spec.tests) { - for (const test of spec.tests) { - switch (test.status) { - case 'passed': - summary.passedTests++; - break; - case 'failed': - summary.failedTests++; - break; - case 'skipped': - summary.skippedTests++; - break; - } - } - } - } - } - } - } - - // Save summary - const summaryPath = path.join(process.cwd(), 'auth-debug-summary.json'); - await fs.writeFile(summaryPath, JSON.stringify(summary, null, 2)); - - console.log('๐Ÿ“ˆ Test Summary:'); - console.log(` Total Tests: ${summary.totalTests}`); - console.log(` Passed: ${summary.passedTests}`); - console.log(` Failed: ${summary.failedTests}`); - console.log(` Skipped: ${summary.skippedTests}`); - console.log(` Duration: ${summary.duration}ms`); - console.log(` Summary saved to: auth-debug-summary.json`); - } catch (_error) { - console.warn('โš ๏ธ Could not find test report for summary generation'); - } - - console.log('โœ… Test summary generation completed'); - } catch (error) { - console.warn('โš ๏ธ Test summary generation had issues:', error); - } -} - -/** - * Clean up test artifacts but preserve important debug information - */ -async function cleanupTestArtifacts(): Promise { - console.log('๐Ÿงน Managing test artifacts...'); - - try { - const fs = await import('fs').then(m => m.promises); - const path = await import('path'); - - // Archive old test results if they exist - const testResultsDir = 'test-results-auth'; - const archiveDir = 'test-results-archive'; - - try { - await fs.access(testResultsDir); - - // Create archive directory if it doesn't exist - try { - await fs.mkdir(archiveDir, { recursive: true }); - } catch { - // Directory might already exist - } - - // Move current results to archive with timestamp - const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); - const archivePath = path.join(archiveDir, `auth-debug-${timestamp}`); - - await fs.rename(testResultsDir, archivePath); - console.log(`๐Ÿ“ฆ Archived test results to: ${archivePath}`); - } catch { - // No test results to archive - } - - console.log('โœ… Test artifacts management completed'); - } catch (error) { - console.warn('โš ๏ธ Test artifacts cleanup had issues:', error); - } -} - -/** - * Log final status and cleanup recommendations - */ -async function logFinalStatus(): Promise { - console.log('๐Ÿ“‹ Auth Debug Test Session Complete'); - console.log(''); - console.log('๐Ÿ“ Available Reports:'); - console.log(' โ€ข HTML Report: playwright-report-auth/index.html'); - console.log(' โ€ข JSON Report: playwright-report-auth.json'); - console.log(' โ€ข Summary: auth-debug-summary.json'); - console.log(''); - console.log('๐Ÿ”ง Debug Commands:'); - console.log( - ' โ€ข View HTML report: npx playwright show-report playwright-report-auth' - ); - console.log( - ' โ€ข Run specific test: bunx playwright test auth-debug.spec.ts --debug' - ); - console.log(' โ€ข Interactive mode: make test-e2e-ui'); - console.log(''); - console.log('๐Ÿงน Cleanup Status:'); - console.log(' โ€ข Test users: Cleaned up'); - console.log(' โ€ข Temporary files: Preserved for debugging'); - console.log(' โ€ข Test artifacts: Archived'); - console.log(''); - - // Check for failed tests and provide guidance - try { - const fs = await import('fs').then(m => m.promises); - const path = await import('path'); - const summaryPath = path.join(process.cwd(), 'auth-debug-summary.json'); - - const summaryData = await fs.readFile(summaryPath, 'utf-8'); - const summary = JSON.parse(summaryData); - - if (summary.failedTests > 0) { - console.log('โš ๏ธ Test Failures Detected:'); - console.log(` ${summary.failedTests} test(s) failed`); - console.log(' Check the HTML report for detailed failure information'); - console.log(' Use --debug flag to interactively debug failing tests'); - console.log(''); - } else if (summary.passedTests > 0) { - console.log('โœ… All Authentication Tests Passed!'); - console.log(' Authentication flows are working correctly'); - console.log(''); - } - } catch { - // Summary file might not exist - } - - console.log('๐ŸŽฏ Next Steps:'); - console.log(' โ€ข Review test reports for any issues'); - console.log(' โ€ข Update authentication tests as features evolve'); - console.log(' โ€ข Run tests regularly in CI/CD pipeline'); - console.log(''); -} - -/** - * Emergency cleanup in case of critical errors - */ -async function emergencyCleanup(): Promise { - console.log('๐Ÿšจ Running emergency cleanup...'); - - try { - // Force cleanup of any hanging processes or connections - // This is a safety net for test environments - - console.log('โœ… Emergency cleanup completed'); - } catch (error) { - console.error('โŒ Emergency cleanup failed:', error); - } -} - -// Execute teardown -export default async function (config: GlobalTeardownConfig) { - try { - await globalTeardown(config); - } catch (_error) { - console.error('โŒ Teardown failed, running emergency cleanup...'); - await emergencyCleanup(); - } -} diff --git a/tests/e2e/auth-debug.spec.ts b/tests/e2e/auth-debug.spec.ts deleted file mode 100644 index 62b3d8e..0000000 --- a/tests/e2e/auth-debug.spec.ts +++ /dev/null @@ -1,390 +0,0 @@ - -import { test, expect } from '@playwright/test'; - -test.describe('Authentication Debug and Validation', () => { - test.beforeEach(async ({ page }) => { - await page.goto('/'); - // Wait for login form to be ready - await page.waitForSelector('input[type="email"]', { timeout: 10000 }); - }); - - test('should validate admin user exists in system', async ({ page }) => { - // Check if admin user exists by attempting login - await page.fill('input[type="email"]', 'admin@localhost'); - await page.fill('input[type="password"]', 'admin123!'); - await page.click('button[type="submit"]'); - - // Should successfully login and reach main app - await expect(page.locator('h1')).toContainText('Medication Reminder', { - timeout: 15000, - }); - await expect(page.locator('text=Admin')).toBeVisible({ timeout: 10000 }); - - // Verify admin role and permissions - await page.click('button:has-text("Admin")'); - await expect(page.locator('text=Admin Interface')).toBeVisible({ - timeout: 10000, - }); - await expect(page.locator('text=User Management')).toBeVisible(); - }); - - test('should validate email format with localhost domain', async ({ - page, - }) => { - const testEmails = [ - { email: 'admin@localhost', valid: true }, - { email: 'user@localhost', valid: true }, - { email: 'test@example.com', valid: true }, - { email: 'invalid-email', valid: false }, - { email: '@localhost', valid: false }, - { email: 'user@', valid: false }, - { email: '', valid: false }, - ]; - - for (const { email, valid } of testEmails) { - console.log(`Testing email validation for: ${email}`); - - // Clear form - await page.fill('input[type="email"]', ''); - await page.fill('input[type="password"]', ''); - - // Fill email - await page.fill('input[type="email"]', email); - await page.fill('input[type="password"]', 'testpass123'); - - // Try to submit - await page.click('button[type="submit"]'); - - if (valid) { - // Should not show validation error for valid emails - await expect(page.locator('text=Invalid email format')).not.toBeVisible( - { timeout: 3000 } - ); - } else { - // Should show validation error for invalid emails - await expect(page.locator('text=Invalid')).toBeVisible({ - timeout: 3000, - }); - } - - // Wait a bit between tests and reload to reset state - await page.waitForTimeout(1000); - await page.reload(); - await page.waitForSelector('input[type="email"]'); - } - }); - - test('should validate user creation with password', async ({ page }) => { - // Go to registration - await page.click('text=Register'); - await page.waitForSelector('input[name="username"]', { timeout: 5000 }); - - // Test user data with timestamp to ensure uniqueness - const timestamp = Date.now(); - const testUser = { - email: `debug-test-${timestamp}@localhost`, - username: `debugtest${timestamp}`, - password: 'DebugTest123!', - }; - - console.log(`Testing user creation for: ${testUser.email}`); - - // Fill registration form - await page.fill('input[type="email"]', testUser.email); - await page.fill('input[name="username"]', testUser.username); - await page.fill('input[type="password"]', testUser.password); - - // Submit registration - await page.click('button[type="submit"]'); - - // Should show success or verification message - await expect( - page - .locator('text=verification') - .or(page.locator('text=registered')) - .or(page.locator('text=success')) - ).toBeVisible({ timeout: 10000 }); - }); - - test('should handle OAuth user creation flow', async ({ page }) => { - // Check OAuth buttons are present - await expect(page.locator('button:has-text("Google")')).toBeVisible({ - timeout: 5000, - }); - await expect(page.locator('button:has-text("GitHub")')).toBeVisible({ - timeout: 5000, - }); - - // Store current URL to verify navigation attempt - const currentUrl = page.url(); - - // Click OAuth button (won't actually authenticate in test) - await page.click('button:has-text("Google")'); - - // Should either redirect to OAuth provider or show error in test environment - await page.waitForTimeout(2000); - - // Verify some action was taken (URL change or error message) - const newUrl = page.url(); - const hasError = await page.locator('text=error').isVisible(); - - // One of these should be true: URL changed (redirect) or error shown - const actionTaken = newUrl !== currentUrl || hasError; - expect(actionTaken).toBeTruthy(); - }); - - test('should validate database connection status', async ({ page }) => { - // Login as admin to access system status - await page.fill('input[type="email"]', 'admin@localhost'); - await page.fill('input[type="password"]', 'admin123!'); - await page.click('button[type="submit"]'); - - await expect(page.locator('h1')).toContainText('Medication Reminder', { - timeout: 15000, - }); - - // Check if there's a system status indicator - const statusIndicator = page.locator('[data-testid="system-status"]'); - const statusVisible = await statusIndicator.isVisible(); - - if (statusVisible) { - await expect(statusIndicator).toContainText('Connected'); - console.log('System status indicator found and shows: Connected'); - } else { - console.log( - 'System status indicator not found - this is optional functionality' - ); - } - - // Alternative: Check if app loads successfully (indicates DB connection) - await expect(page.locator('button:has-text("Add Medication")')).toBeVisible( - { timeout: 5000 } - ); - console.log( - 'App loaded successfully - database connection presumed working' - ); - }); - - test('should validate password strength requirements', async ({ page }) => { - await page.click('text=Register'); - await page.waitForSelector('input[name="username"]', { timeout: 5000 }); - - const weakPasswords = [ - { password: '123', description: 'too short' }, - { password: 'password', description: 'common word' }, - { password: 'admin', description: 'common admin' }, - { password: 'abc123', description: 'simple pattern' }, - { password: 'PASSWORD', description: 'all caps, no numbers' }, - ]; - - const strongPasswords = [ - { - password: 'StrongPass123!', - description: 'mixed case, numbers, symbols', - }, - { - password: 'MySecure@Password1', - description: 'long with special chars', - }, - { password: 'Complex#Pass9', description: 'complex pattern' }, - ]; - - // Test weak passwords - for (const { password, description } of weakPasswords) { - console.log(`Testing weak password (${description}): ${password}`); - - const timestamp = Date.now(); - await page.fill('input[type="email"]', `test${timestamp}@localhost`); - await page.fill('input[name="username"]', `testuser${timestamp}`); - await page.fill('input[type="password"]', password); - - await page.click('button[type="submit"]'); - - // Should show password strength error - const errorVisible = await page - .locator('text=Password must') - .or(page.locator('text=weak')) - .or(page.locator('text=strength')) - .isVisible(); - if (!errorVisible) { - console.log( - `Warning: Password strength validation may not be implemented for: ${password}` - ); - } - - // Clear form for next test - await page.fill('input[type="password"]', ''); - await page.waitForTimeout(500); - } - - // Test strong passwords - for (const { password, description } of strongPasswords) { - console.log(`Testing strong password (${description}): ${password}`); - - const timestamp = Date.now(); - await page.fill('input[type="email"]', `strong${timestamp}@localhost`); - await page.fill('input[name="username"]', `stronguser${timestamp}`); - await page.fill('input[type="password"]', password); - - await page.click('button[type="submit"]'); - - // Should not show password strength error, but might show other validation - await page.waitForTimeout(1000); - - const hasPasswordError = await page - .locator('text=Password must') - .or(page.locator('text=weak')) - .isVisible(); - if (hasPasswordError) { - console.log(`Unexpected: Strong password rejected: ${password}`); - } - - // Clear form for next test - await page.fill('input[type="password"]', ''); - await page.waitForTimeout(500); - } - }); - - test('should validate session persistence', async ({ page }) => { - console.log('Testing session persistence...'); - - // Login - await page.fill('input[type="email"]', 'admin@localhost'); - await page.fill('input[type="password"]', 'admin123!'); - await page.click('button[type="submit"]'); - - await expect(page.locator('h1')).toContainText('Medication Reminder', { - timeout: 15000, - }); - console.log('Initial login successful'); - - // Refresh page - await page.reload(); - await page.waitForLoadState('networkidle'); - - // Should still be logged in - try { - await expect(page.locator('h1')).toContainText('Medication Reminder', { - timeout: 10000, - }); - await expect(page.locator('text=Admin')).toBeVisible({ timeout: 5000 }); - console.log( - 'Session persistence verified - user remains logged in after refresh' - ); - } catch (_error) { - console.log( - 'Session persistence not implemented - user was logged out after refresh' - ); - // This might be expected behavior depending on implementation - await expect(page.locator('input[type="email"]')).toBeVisible(); - } - }); - - test('should handle invalid login attempts', async ({ page }) => { - const invalidCredentials = [ - { - email: 'nonexistent@localhost', - password: 'password123', - type: 'nonexistent user', - }, - { - email: 'admin@localhost', - password: 'wrongpassword', - type: 'wrong password', - }, - { - email: 'invalid-email', - password: 'password123', - type: 'invalid email format', - }, - { email: '', password: 'password123', type: 'empty email' }, - { email: 'admin@localhost', password: '', type: 'empty password' }, - ]; - - for (const { email, password, type } of invalidCredentials) { - console.log(`Testing invalid login: ${type}`); - - await page.fill('input[type="email"]', email); - await page.fill('input[type="password"]', password); - await page.click('button[type="submit"]'); - - // Wait for response - await page.waitForTimeout(2000); - - // Should show error message or stay on login page - const hasError = await page - .locator('text=Invalid') - .or(page.locator('text=error')) - .or(page.locator('text=failed')) - .isVisible(); - const staysOnLogin = await page - .locator('input[type="email"]') - .isVisible(); - - if (!hasError && !staysOnLogin) { - console.log(`Warning: No clear error indication for ${type}`); - } - - // Should not redirect to main app - const redirectedToApp = await page - .locator('h1:has-text("Medication Reminder")') - .isVisible(); - expect(redirectedToApp).toBeFalsy(); - - // Clear form for next test - await page.fill('input[type="email"]', ''); - await page.fill('input[type="password"]', ''); - await page.waitForTimeout(1000); - } - }); - - test('should validate user lookup functionality', async ({ page }) => { - console.log('Testing user lookup functionality...'); - - // Login as admin first - await page.fill('input[type="email"]', 'admin@localhost'); - await page.fill('input[type="password"]', 'admin123!'); - await page.click('button[type="submit"]'); - - await expect(page.locator('h1')).toContainText('Medication Reminder', { - timeout: 15000, - }); - - // Open admin interface - await page.click('button:has-text("Admin")'); - await expect(page.locator('text=User Management')).toBeVisible({ - timeout: 10000, - }); - - // Should show admin user in user list - await expect(page.locator('text=admin@localhost')).toBeVisible({ - timeout: 5000, - }); - console.log('Admin user found in user list'); - - // Test user search if available - const searchBox = page - .locator('input[placeholder*="search"]') - .or(page.locator('input[type="search"]')); - const searchVisible = await searchBox.isVisible(); - - if (searchVisible) { - console.log('Search functionality found, testing...'); - await searchBox.fill('admin'); - await page.waitForTimeout(1000); // Allow for search debouncing - await expect(page.locator('text=admin@localhost')).toBeVisible(); - console.log('Search functionality works correctly'); - } else { - console.log('Search functionality not implemented - this is optional'); - } - - // Test user count or list functionality - const userRows = page.locator( - 'tr:has-text("@"), .user-item, [data-testid*="user"]' - ); - const userCount = await userRows.count(); - console.log(`Found ${userCount} users in the system`); - - expect(userCount).toBeGreaterThan(0); // At least admin should be present - }); -}); diff --git a/tests/e2e/playwright.auth.config.ts b/tests/e2e/playwright.auth.config.ts deleted file mode 100644 index 071311e..0000000 --- a/tests/e2e/playwright.auth.config.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { defineConfig, devices } from '@playwright/test'; - -/** - * Specialized Playwright configuration for authentication debug tests - * Optimized for debugging auth flows with extended timeouts and detailed reporting - */ -export default defineConfig({ - testDir: './', - testMatch: 'tests/e2e/auth-debug.spec.ts', - - /* Run tests in files in parallel */ - fullyParallel: false, // Auth tests should run sequentially to avoid conflicts - - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : 1, // Auth tests work better with single worker - - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: [ - ['html', { outputFolder: 'playwright-report-auth' }], - ['json', { outputFile: 'playwright-report-auth.json' }], - ['list'], - ['junit', { outputFile: 'playwright-auth-results.xml' }], - ], - - /* Shared settings for all the projects below. */ - use: { - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: 'http://localhost:8080', - - /* Collect trace when retrying the failed test. */ - trace: 'retain-on-failure', - - /* Take screenshot on failure */ - screenshot: 'only-on-failure', - - /* Record video on failure */ - video: 'retain-on-failure', - - /* Extended timeouts for auth operations */ - actionTimeout: 15000, - navigationTimeout: 30000, - - /* Ignore HTTPS errors */ - ignoreHTTPSErrors: true, - - /* Accept downloads */ - acceptDownloads: false, - - /* Viewport settings */ - viewport: { width: 1280, height: 720 }, - - /* Locale for testing */ - locale: 'en-US', - - /* Timezone for consistent testing */ - timezoneId: 'America/New_York', - }, - - /* Configure projects for major browsers */ - projects: [ - { - name: 'auth-debug-chromium', - use: { - ...devices['Desktop Chrome'], - // Additional Chrome flags for debugging - launchOptions: { - args: [ - '--disable-web-security', - '--disable-features=VizDisplayCompositor', - '--no-sandbox', - '--disable-dev-shm-usage', - ], - }, - }, - }, - - { - name: 'auth-debug-firefox', - use: { - ...devices['Desktop Firefox'], - // Firefox specific settings - launchOptions: { - firefoxUserPrefs: { - 'security.tls.insecure_fallback_hosts': 'localhost', - 'network.stricttransportsecurity.preloadlist': false, - }, - }, - }, - }, - - { - name: 'auth-debug-webkit', - use: { ...devices['Desktop Safari'] }, - }, - - /* Test against mobile viewports for responsive auth */ - { - name: 'auth-debug-mobile-chrome', - use: { ...devices['Pixel 5'] }, - }, - { - name: 'auth-debug-mobile-safari', - use: { ...devices['iPhone 12'] }, - }, - ], - - /* Global setup and teardown */ - globalSetup: './auth-debug-setup.ts', - globalTeardown: './auth-debug-teardown.ts', - - /* Test timeout for auth operations */ - timeout: 60000, // 1 minute per test - expect: { - timeout: 10000, // 10 seconds for assertions - }, - - /* Run your local dev server before starting the tests */ - webServer: [ - { - command: 'bun run dev', - port: 8080, - timeout: 120000, - reuseExistingServer: !process.env.CI, - stdout: 'pipe', - stderr: 'pipe', - env: { - NODE_ENV: 'test', - VITE_COUCHDB_URL: 'http://localhost:5984', - VITE_COUCHDB_USERNAME: 'admin', - VITE_COUCHDB_PASSWORD: 'password', - }, - }, - { - command: 'docker-compose -f docker/docker-compose.yaml up -d', - timeout: 60000, - reuseExistingServer: !process.env.CI, - }, - ], - - /* Output directories */ - outputDir: 'test-results-auth/', - - /* Metadata for reporting */ - metadata: { - testType: 'Authentication Debug', - environment: process.env.NODE_ENV || 'test', - version: process.env.APP_VERSION || 'development', - author: 'Medication Reminder App Team', - description: - 'Comprehensive authentication flow debugging and validation tests', - }, -});