feat: add comprehensive authentication debug test suite
Add automated authentication testing infrastructure: - AUTH-DEBUG-GUIDE.md: Complete guide for auth debugging - auth-debug.spec.ts: Comprehensive auth flow validation tests - playwright.auth.config.ts: Specialized config with extended timeouts - auth-debug-setup.ts: Global test environment setup - auth-debug-teardown.ts: Test cleanup and environment reset Features: - Admin user validation and permissions testing - Email format validation including localhost domains - User registration and OAuth integration testing - Database connectivity and session management - Password security and error handling validation - Cross-browser testing with mobile support - Enhanced reporting and interactive debugging - CI/CD integration with artifacts and JUnit reports Replaces manual browser console debugging scripts with automated, cross-browser E2E tests for better reliability and maintainability.
This commit is contained in:
206
tests/e2e/auth-debug-setup.ts
Normal file
206
tests/e2e/auth-debug-setup.ts
Normal file
@@ -0,0 +1,206 @@
|
||||
/* eslint-disable no-console */
|
||||
import { chromium, FullConfig } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Global setup for authentication debug tests
|
||||
* Ensures services are running and database is properly initialized
|
||||
*/
|
||||
async function globalSetup(_config: FullConfig) {
|
||||
console.log('🔧 Setting up authentication debug test environment...');
|
||||
|
||||
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;
|
||||
console.log(`✅ Auth debug setup completed in ${duration}ms`);
|
||||
} catch (error) {
|
||||
console.error('❌ Auth debug setup failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for required services to be available
|
||||
*/
|
||||
async function waitForServices(): Promise<void> {
|
||||
console.log('⏳ Waiting for services to be ready...');
|
||||
|
||||
// Wait for frontend
|
||||
await waitForService('http://localhost:8080', 'Frontend');
|
||||
|
||||
// Wait for CouchDB
|
||||
await waitForService('http://localhost:5984', 'CouchDB');
|
||||
|
||||
console.log('✅ All services are ready');
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a specific service to be available
|
||||
*/
|
||||
async function waitForService(url: string, serviceName: string): Promise<void> {
|
||||
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'),
|
||||
},
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
console.log(`✅ ${serviceName} is ready at ${url}`);
|
||||
return;
|
||||
}
|
||||
} catch (_error) {
|
||||
// Service not ready yet
|
||||
}
|
||||
|
||||
if (attempt === maxAttempts) {
|
||||
throw new Error(
|
||||
`${serviceName} not available at ${url} after ${maxAttempts} attempts`
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`⏳ ${serviceName} not ready, attempt ${attempt}/${maxAttempts}...`
|
||||
);
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize test data and ensure databases exist
|
||||
*/
|
||||
async function initializeTestData(): Promise<void> {
|
||||
console.log('🔧 Initializing test data...');
|
||||
|
||||
try {
|
||||
// Check if databases exist, create if needed
|
||||
const databases = [
|
||||
'users',
|
||||
'medications',
|
||||
'settings',
|
||||
'taken_doses',
|
||||
'reminders',
|
||||
];
|
||||
|
||||
for (const dbName of databases) {
|
||||
await ensureDatabaseExists(dbName);
|
||||
}
|
||||
|
||||
console.log('✅ Test data initialization completed');
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Test data initialization had issues:', 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<void> {
|
||||
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',
|
||||
},
|
||||
});
|
||||
console.log(`📊 Created database: ${dbName}`);
|
||||
} else if (response.ok) {
|
||||
console.log(`✅ Database exists: ${dbName}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`⚠️ Could not verify/create database ${dbName}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify admin user exists for testing
|
||||
*/
|
||||
async function verifyAdminUser(): Promise<void> {
|
||||
console.log('🔧 Verifying admin user exists...');
|
||||
|
||||
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,
|
||||
});
|
||||
console.log('✅ Admin user verified and functional');
|
||||
} catch (_error) {
|
||||
console.warn(
|
||||
'⚠️ Admin user may not exist or credentials may be incorrect'
|
||||
);
|
||||
console.warn(
|
||||
' Tests will attempt to create/verify admin user during execution'
|
||||
);
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
} catch (_error) {
|
||||
console.warn('⚠️ Could not verify admin user');
|
||||
// Don't fail setup, let individual tests handle this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log environment information
|
||||
*/
|
||||
function logEnvironmentInfo(): void {
|
||||
console.log('🌍 Environment Information:');
|
||||
console.log(` Node.js: ${process.version}`);
|
||||
console.log(` Platform: ${process.platform}`);
|
||||
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`);
|
||||
console.log(` CI: ${process.env.CI || 'false'}`);
|
||||
console.log(` Frontend URL: http://localhost:8080`);
|
||||
console.log(` CouchDB URL: http://localhost:5984`);
|
||||
}
|
||||
|
||||
// Execute setup
|
||||
export default async function (config: FullConfig) {
|
||||
logEnvironmentInfo();
|
||||
await globalSetup(config);
|
||||
}
|
||||
Reference in New Issue
Block a user