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 }); });