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
This commit is contained in:
William Valentin
2025-09-08 22:18:25 -07:00
parent 5e749b8982
commit 930e044144
6 changed files with 0 additions and 2042 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -1,354 +0,0 @@
import { chromium } from 'playwright';
import { logger } from '../../services/logging';
interface GlobalSetupConfig {
projects?: Array<{
name: string;
use?: Record<string, unknown>;
}>;
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<void> {
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<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'),
},
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<void> {
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<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',
},
});
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<void> {
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<void> {
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);
}

View File

@@ -1,403 +0,0 @@
/* eslint-disable no-console */
interface GlobalTeardownConfig {
projects?: Array<{
name: string;
use?: Record<string, unknown>;
}>;
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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();
}
}

View File

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

View File

@@ -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',
},
});