upskill-event-manager/tests/integration/master-test-runner.js
Ben 7c9ca65cf2
Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
feat: add comprehensive test framework and test files
- Add 90+ test files including E2E, unit, and integration tests
- Implement Page Object Model (POM) architecture
- Add Docker testing environment with comprehensive services
- Include modernized test framework with error recovery
- Add specialized test suites for master trainer and trainer workflows
- Update .gitignore to properly track test infrastructure

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 23:23:26 -03:00

806 lines
No EOL
30 KiB
JavaScript
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* Master Test Runner - Phase 3 Integration & Validation
*
* Production-ready execution script that demonstrates the complete E2E test integration
* for all 5 agent implementations with cross-functional workflows, performance monitoring,
* and comprehensive error recovery.
*
* Usage:
* node tests/integration/master-test-runner.js
* node tests/integration/master-test-runner.js --environment=docker
* node tests/integration/master-test-runner.js --agents=A,B,C --headed
* node tests/integration/master-test-runner.js --performance-only
*
* @package HVAC_Community_Events
* @version 3.0.0
* @created 2025-08-27
*/
const path = require('path');
const fs = require('fs').promises;
const { Command } = require('commander');
// Core integration components
const MasterTestOrchestrator = require('./master-test-orchestrator');
const CrossFunctionalWorkflows = require('./cross-functional-workflows');
const PerformanceMonitor = require('../framework/monitoring/PerformanceMonitor');
const ErrorRecoveryManager = require('../framework/recovery/ErrorRecoveryManager');
// Configuration
const DEFAULT_CONFIG = {
environment: 'staging',
baseUrl: process.env.BASE_URL || 'https://upskill-staging.measurequick.com',
dockerUrl: process.env.DOCKER_BASE_URL || 'http://localhost:8080',
headless: process.env.HEADLESS !== 'false',
slowMo: parseInt(process.env.PLAYWRIGHT_SLOW_MO) || 0,
timeout: 30 * 60 * 1000, // 30 minutes
evidenceDir: path.join(__dirname, '../evidence/master-test-run'),
reportDir: path.join(__dirname, '../reports'),
display: process.env.DISPLAY || ':0',
xAuthority: process.env.XAUTHORITY || '/run/user/1000/.mutter-Xwaylandauth.U8VEB3'
};
class MasterTestRunner {
constructor(options = {}) {
this.config = { ...DEFAULT_CONFIG, ...options };
this.startTime = Date.now();
this.orchestrator = null;
this.workflows = null;
this.performanceMonitor = null;
this.errorRecoveryManager = null;
this.results = {
orchestration: null,
workflows: null,
performance: null,
recovery: null,
summary: null
};
}
/**
* Execute complete integration test suite
*/
async execute() {
console.log('════════════════════════════════════════════════════════');
console.log(' HVAC E2E Integration & Validation - Master Test Runner');
console.log('════════════════════════════════════════════════════════');
console.log('Phase 3: Agent Implementation Coordination');
console.log(`Environment: ${this.config.environment}`);
console.log(`Base URL: ${this.config.baseUrl}`);
console.log(`Headless: ${this.config.headless}`);
console.log(`Target Duration: <${this.config.timeout / 60000} minutes`);
console.log(`Evidence Directory: ${this.config.evidenceDir}`);
console.log('════════════════════════════════════════════════════════');
try {
// Initialize all components
await this.initializeComponents();
// Execute test phases
if (this.config.skipOrchestration !== true) {
await this.executeOrchestration();
}
if (this.config.skipWorkflows !== true) {
await this.executeWorkflows();
}
if (this.config.skipPerformance !== true) {
await this.executePerformanceTesting();
}
if (this.config.skipRecovery !== true) {
await this.executeRecoveryTesting();
}
// Generate final report
await this.generateFinalReport();
// Display results
this.displayResults();
const success = this.evaluateOverallSuccess();
console.log(`\n🏁 Master Test Runner: ${success ? 'SUCCESS' : 'FAILED'}`);
return success;
} catch (error) {
console.error('\n💥 Master Test Runner failed:', error.message);
console.error('Stack trace:', error.stack);
await this.handleExecutionError(error);
return false;
} finally {
await this.cleanup();
}
}
/**
* Initialize all test components
*/
async initializeComponents() {
console.log('\n🔧 Initializing test components...');
// Create evidence directories
await this.createDirectories();
// Initialize Master Test Orchestrator
if (!this.config.skipOrchestration) {
console.log(' Initializing Master Test Orchestrator...');
this.orchestrator = new MasterTestOrchestrator();
await this.orchestrator.setUp();
console.log(' ✓ Master Test Orchestrator ready');
}
// Initialize Cross-Functional Workflows
if (!this.config.skipWorkflows) {
console.log(' Initializing Cross-Functional Workflows...');
this.workflows = new CrossFunctionalWorkflows();
await this.workflows.setUp();
console.log(' ✓ Cross-Functional Workflows ready');
}
// Initialize Performance Monitor
if (!this.config.skipPerformance) {
console.log(' Initializing Performance Monitor...');
this.performanceMonitor = new PerformanceMonitor();
await this.performanceMonitor.initialize();
console.log(' ✓ Performance Monitor ready');
}
// Initialize Error Recovery Manager
if (!this.config.skipRecovery) {
console.log(' Initializing Error Recovery Manager...');
this.errorRecoveryManager = new ErrorRecoveryManager();
const browserManager = this.orchestrator ? this.orchestrator.browserManager : null;
await this.errorRecoveryManager.initialize(browserManager);
console.log(' ✓ Error Recovery Manager ready');
}
console.log('✓ All components initialized successfully');
}
/**
* Execute master test orchestration
*/
async executeOrchestration() {
console.log('\n🎭 Executing Master Test Orchestration...');
const orchestrationStart = Date.now();
try {
// Start performance monitoring for orchestration
if (this.performanceMonitor) {
await this.performanceMonitor.startAgentMonitoring('MasterOrchestration');
}
// Execute orchestration
const orchestrationResults = await this.orchestrator.executeIntegrationValidation();
// Stop performance monitoring
if (this.performanceMonitor) {
await this.performanceMonitor.stopAgentMonitoring('MasterOrchestration');
}
const orchestrationDuration = Date.now() - orchestrationStart;
this.results.orchestration = {
status: 'completed',
duration: orchestrationDuration,
results: orchestrationResults,
timestamp: new Date().toISOString()
};
console.log(`✓ Master Test Orchestration completed in ${(orchestrationDuration / 1000).toFixed(1)}s`);
} catch (error) {
const orchestrationDuration = Date.now() - orchestrationStart;
this.results.orchestration = {
status: 'failed',
duration: orchestrationDuration,
error: error.message,
timestamp: new Date().toISOString()
};
console.error(`✗ Master Test Orchestration failed after ${(orchestrationDuration / 1000).toFixed(1)}s:`, error.message);
if (this.config.continueOnFailure !== true) {
throw error;
}
}
}
/**
* Execute cross-functional workflows
*/
async executeWorkflows() {
console.log('\n🔄 Executing Cross-Functional Workflows...');
const workflowsStart = Date.now();
try {
// Start performance monitoring for workflows
if (this.performanceMonitor) {
await this.performanceMonitor.startAgentMonitoring('CrossFunctionalWorkflows');
}
// Execute workflows
const workflowResults = await this.workflows.executeAllWorkflows();
// Stop performance monitoring
if (this.performanceMonitor) {
await this.performanceMonitor.stopAgentMonitoring('CrossFunctionalWorkflows');
}
const workflowsDuration = Date.now() - workflowsStart;
this.results.workflows = {
status: 'completed',
duration: workflowsDuration,
results: workflowResults,
timestamp: new Date().toISOString()
};
const passedWorkflows = workflowResults.filter(w => w.status === 'passed').length;
console.log(`✓ Cross-Functional Workflows completed: ${passedWorkflows}/${workflowResults.length} passed in ${(workflowsDuration / 1000).toFixed(1)}s`);
} catch (error) {
const workflowsDuration = Date.now() - workflowsStart;
this.results.workflows = {
status: 'failed',
duration: workflowsDuration,
error: error.message,
timestamp: new Date().toISOString()
};
console.error(`✗ Cross-Functional Workflows failed after ${(workflowsDuration / 1000).toFixed(1)}s:`, error.message);
if (this.config.continueOnFailure !== true) {
throw error;
}
}
}
/**
* Execute performance testing
*/
async executePerformanceTesting() {
console.log('\n📊 Executing Performance Testing...');
const performanceStart = Date.now();
try {
// Concurrent load testing
const concurrentSessionConfigs = [
{
sessionId: 'trainer_session_1',
actions: [
{ type: 'login', duration: 2000 },
{ type: 'navigate', url: '/trainer/dashboard', duration: 1500 },
{ type: 'create_event', duration: 5000 }
]
},
{
sessionId: 'trainer_session_2',
actions: [
{ type: 'login', duration: 2000 },
{ type: 'navigate', url: '/trainer/my-events', duration: 1500 },
{ type: 'form_submit', duration: 3000 }
]
},
{
sessionId: 'master_session_1',
actions: [
{ type: 'login', duration: 2000 },
{ type: 'navigate', url: '/master-trainer/pending-approvals', duration: 2000 },
{ type: 'form_submit', duration: 2000 }
]
}
];
const loadTestResults = await this.performanceMonitor.executeConcurrentLoadTest(concurrentSessionConfigs);
// Generate performance benchmark
const performanceBenchmark = await this.performanceMonitor.generatePerformanceBenchmark();
const performanceDuration = Date.now() - performanceStart;
this.results.performance = {
status: 'completed',
duration: performanceDuration,
loadTest: loadTestResults,
benchmark: performanceBenchmark,
timestamp: new Date().toISOString()
};
console.log(`✓ Performance Testing completed in ${(performanceDuration / 1000).toFixed(1)}s`);
console.log(` Concurrent Sessions: ${loadTestResults.successfulSessions}/${loadTestResults.totalSessions} successful`);
console.log(` Performance Rating: ${loadTestResults.concurrentPerformanceRating}`);
} catch (error) {
const performanceDuration = Date.now() - performanceStart;
this.results.performance = {
status: 'failed',
duration: performanceDuration,
error: error.message,
timestamp: new Date().toISOString()
};
console.error(`✗ Performance Testing failed after ${(performanceDuration / 1000).toFixed(1)}s:`, error.message);
if (this.config.continueOnFailure !== true) {
throw error;
}
}
}
/**
* Execute error recovery testing
*/
async executeRecoveryTesting() {
console.log('\n🛡 Executing Error Recovery Testing...');
const recoveryStart = Date.now();
try {
// Execute comprehensive recovery tests
const recoveryResults = await this.errorRecoveryManager.executeComprehensiveRecoveryTests(this.config.baseUrl);
// Get recovery statistics
const recoveryStats = this.errorRecoveryManager.getRecoveryStatistics();
const recoveryDuration = Date.now() - recoveryStart;
this.results.recovery = {
status: 'completed',
duration: recoveryDuration,
results: recoveryResults,
statistics: recoveryStats,
timestamp: new Date().toISOString()
};
console.log(`✓ Error Recovery Testing completed in ${(recoveryDuration / 1000).toFixed(1)}s`);
console.log(` Recovery Tests: ${recoveryResults.summary.passed}/${recoveryResults.summary.total} passed`);
console.log(` Success Rate: ${recoveryResults.summary.successRate.toFixed(1)}%`);
} catch (error) {
const recoveryDuration = Date.now() - recoveryStart;
this.results.recovery = {
status: 'failed',
duration: recoveryDuration,
error: error.message,
timestamp: new Date().toISOString()
};
console.error(`✗ Error Recovery Testing failed after ${(recoveryDuration / 1000).toFixed(1)}s:`, error.message);
if (this.config.continueOnFailure !== true) {
throw error;
}
}
}
/**
* Generate final comprehensive report
*/
async generateFinalReport() {
console.log('\n📋 Generating final integration report...');
const totalDuration = Date.now() - this.startTime;
const finalReport = {
meta: {
version: '3.0.0',
generatedAt: new Date().toISOString(),
totalDuration: totalDuration,
environment: this.config.environment,
baseUrl: this.config.baseUrl,
configuration: this.config
},
summary: {
overallStatus: this.evaluateOverallSuccess() ? 'SUCCESS' : 'FAILED',
totalDuration: totalDuration,
targetDuration: this.config.timeout,
performanceMet: totalDuration <= this.config.timeout,
phases: {
orchestration: this.results.orchestration?.status || 'skipped',
workflows: this.results.workflows?.status || 'skipped',
performance: this.results.performance?.status || 'skipped',
recovery: this.results.recovery?.status || 'skipped'
}
},
results: this.results,
recommendations: this.generateRecommendations()
};
// Export performance report if available
if (this.performanceMonitor) {
const performanceReportPath = path.join(this.config.reportDir, `performance-report-${Date.now()}.json`);
await this.performanceMonitor.exportPerformanceReport(performanceReportPath);
finalReport.performanceReportPath = performanceReportPath;
}
// Save final report
const finalReportPath = path.join(this.config.reportDir, `master-test-report-${Date.now()}.json`);
await fs.writeFile(finalReportPath, JSON.stringify(finalReport, null, 2));
// Generate executive summary
const summaryPath = await this.generateExecutiveSummary(finalReport);
console.log(`✓ Final integration report generated:`);
console.log(` Report: ${finalReportPath}`);
console.log(` Summary: ${summaryPath}`);
this.results.summary = finalReport;
return finalReport;
}
/**
* Generate executive summary
*/
async generateExecutiveSummary(finalReport) {
const summary = `
# HVAC E2E Integration & Validation - Executive Summary
**Generated:** ${new Date().toISOString()}
**Environment:** ${this.config.environment}
**Base URL:** ${this.config.baseUrl}
**Total Duration:** ${(finalReport.meta.totalDuration / 1000).toFixed(1)} seconds
## Overall Status: ${finalReport.summary.overallStatus}
### Phase Execution Results
**Master Test Orchestration:** ${finalReport.summary.phases.orchestration.toUpperCase()}
- Status: ${this.results.orchestration?.status || 'Not executed'}
- Duration: ${this.results.orchestration ? (this.results.orchestration.duration / 1000).toFixed(1) + 's' : 'N/A'}
**Cross-Functional Workflows:** ${finalReport.summary.phases.workflows.toUpperCase()}
- Status: ${this.results.workflows?.status || 'Not executed'}
- Duration: ${this.results.workflows ? (this.results.workflows.duration / 1000).toFixed(1) + 's' : 'N/A'}
**Performance Testing:** ${finalReport.summary.phases.performance.toUpperCase()}
- Status: ${this.results.performance?.status || 'Not executed'}
- Duration: ${this.results.performance ? (this.results.performance.duration / 1000).toFixed(1) + 's' : 'N/A'}
**Error Recovery Testing:** ${finalReport.summary.phases.recovery.toUpperCase()}
- Status: ${this.results.recovery?.status || 'Not executed'}
- Duration: ${this.results.recovery ? (this.results.recovery.duration / 1000).toFixed(1) + 's' : 'N/A'}
### Performance Summary
**Total Execution Time:** ${(finalReport.meta.totalDuration / 1000).toFixed(1)}s
**Target Execution Time:** ${(this.config.timeout / 1000).toFixed(1)}s
**Performance Target Met:** ${finalReport.summary.performanceMet ? 'YES' : 'NO'}
### Key Findings
${this.generateKeyFindings()}
### Recommendations
${finalReport.recommendations.map(r => `- ${r}`).join('\n')}
---
*Generated by Master Test Runner v3.0.0*
`;
const summaryPath = path.join(this.config.reportDir, `executive-summary-${Date.now()}.md`);
await fs.writeFile(summaryPath, summary.trim());
return summaryPath;
}
/**
* Generate key findings
*/
generateKeyFindings() {
const findings = [];
// Orchestration findings
if (this.results.orchestration?.status === 'completed') {
findings.push('✓ Master test orchestration successfully coordinated all agent implementations');
} else if (this.results.orchestration?.status === 'failed') {
findings.push('✗ Master test orchestration encountered failures');
}
// Workflow findings
if (this.results.workflows?.results) {
const passedWorkflows = this.results.workflows.results.filter(w => w.status === 'passed').length;
const totalWorkflows = this.results.workflows.results.length;
findings.push(`✓ Cross-functional workflows: ${passedWorkflows}/${totalWorkflows} passed`);
}
// Performance findings
if (this.results.performance?.benchmark) {
const benchmark = this.results.performance.benchmark;
findings.push(`✓ Performance rating: ${benchmark.overall.rating}`);
findings.push(`✓ Page load performance: ${benchmark.pageLoads.rating}`);
}
// Recovery findings
if (this.results.recovery?.results) {
const recovery = this.results.recovery.results;
findings.push(`✓ Error recovery tests: ${recovery.summary.passed}/${recovery.summary.total} passed (${recovery.summary.successRate.toFixed(1)}%)`);
}
if (findings.length === 0) {
findings.push('No significant findings to report');
}
return findings.join('\n');
}
/**
* Generate recommendations
*/
generateRecommendations() {
const recommendations = [];
// Performance recommendations
const totalDuration = Date.now() - this.startTime;
if (totalDuration > this.config.timeout) {
recommendations.push(`Optimize execution time - exceeded ${this.config.timeout / 60000} minute target by ${((totalDuration - this.config.timeout) / 1000).toFixed(1)}s`);
}
// Phase-specific recommendations
if (this.results.orchestration?.status === 'failed') {
recommendations.push('Review and fix master test orchestration failures');
}
if (this.results.workflows?.results) {
const failedWorkflows = this.results.workflows.results.filter(w => w.status === 'failed');
if (failedWorkflows.length > 0) {
recommendations.push(`Address ${failedWorkflows.length} failed cross-functional workflow(s)`);
}
}
if (this.results.performance?.benchmark) {
const perfRecommendations = this.results.performance.benchmark.recommendations;
if (perfRecommendations && perfRecommendations.length > 0) {
recommendations.push(...perfRecommendations.map(r => r.message));
}
}
if (this.results.recovery?.results) {
const recovery = this.results.recovery.results;
if (recovery.summary.successRate < 90) {
recommendations.push('Improve error recovery mechanisms - success rate below 90%');
}
}
if (recommendations.length === 0) {
recommendations.push('All integration criteria met - continue with regular maintenance');
}
return recommendations;
}
/**
* Display results summary
*/
displayResults() {
console.log('\n' + '═'.repeat(60));
console.log(' MASTER TEST RUNNER - EXECUTION SUMMARY');
console.log('═'.repeat(60));
const totalDuration = Date.now() - this.startTime;
console.log(`Total Execution Time: ${(totalDuration / 1000).toFixed(1)}s`);
console.log(`Performance Target: ${totalDuration <= this.config.timeout ? 'MET' : 'EXCEEDED'}`);
console.log('');
// Phase results
const phases = [
['Master Orchestration', this.results.orchestration],
['Cross-Functional Workflows', this.results.workflows],
['Performance Testing', this.results.performance],
['Error Recovery Testing', this.results.recovery]
];
phases.forEach(([name, result]) => {
if (result) {
const status = result.status === 'completed' ? '✓' :
result.status === 'failed' ? '✗' : '○';
const duration = result.duration ? `(${(result.duration / 1000).toFixed(1)}s)` : '';
console.log(`${status} ${name}: ${result.status.toUpperCase()} ${duration}`);
if (result.error) {
console.log(` Error: ${result.error}`);
}
} else {
console.log(`${name}: SKIPPED`);
}
});
console.log('');
// Success metrics
const success = this.evaluateOverallSuccess();
console.log(`Overall Status: ${success ? '🎉 SUCCESS' : '❌ FAILED'}`);
console.log(`Evidence Directory: ${this.config.evidenceDir}`);
console.log(`Reports Directory: ${this.config.reportDir}`);
}
/**
* Evaluate overall success
*/
evaluateOverallSuccess() {
const phaseResults = [
this.results.orchestration,
this.results.workflows,
this.results.performance,
this.results.recovery
].filter(Boolean); // Only include executed phases
if (phaseResults.length === 0) {
return false; // No phases executed
}
// All executed phases must be completed (not failed)
const allPhasesSuccessful = phaseResults.every(result => result.status === 'completed');
// Performance target should be met
const totalDuration = Date.now() - this.startTime;
const performanceTargetMet = totalDuration <= this.config.timeout;
return allPhasesSuccessful && (this.config.ignorePerformanceTarget || performanceTargetMet);
}
/**
* Handle execution error
*/
async handleExecutionError(error) {
const errorReport = {
timestamp: new Date().toISOString(),
error: error.message,
stack: error.stack,
config: this.config,
results: this.results,
executionDuration: Date.now() - this.startTime
};
const errorReportPath = path.join(this.config.reportDir, `error-report-${Date.now()}.json`);
await fs.writeFile(errorReportPath, JSON.stringify(errorReport, null, 2));
console.error(`\nError report saved: ${errorReportPath}`);
}
/**
* Create necessary directories
*/
async createDirectories() {
const dirs = [
this.config.evidenceDir,
this.config.reportDir,
path.join(this.config.evidenceDir, 'screenshots'),
path.join(this.config.evidenceDir, 'videos'),
path.join(this.config.evidenceDir, 'logs')
];
for (const dir of dirs) {
try {
await fs.mkdir(dir, { recursive: true });
} catch (error) {
console.warn(`Failed to create directory ${dir}: ${error.message}`);
}
}
}
/**
* Cleanup all components
*/
async cleanup() {
console.log('\n🧹 Cleaning up components...');
try {
if (this.orchestrator) {
await this.orchestrator.tearDown();
console.log(' ✓ Master Test Orchestrator cleanup complete');
}
if (this.workflows) {
await this.workflows.tearDown();
console.log(' ✓ Cross-Functional Workflows cleanup complete');
}
if (this.performanceMonitor) {
await this.performanceMonitor.cleanup();
console.log(' ✓ Performance Monitor cleanup complete');
}
if (this.errorRecoveryManager) {
await this.errorRecoveryManager.cleanup();
console.log(' ✓ Error Recovery Manager cleanup complete');
}
console.log('✓ All components cleaned up successfully');
} catch (error) {
console.warn('Cleanup error:', error.message);
}
}
}
// CLI Configuration
function setupCLI() {
const program = new Command();
program
.version('3.0.0')
.description('HVAC E2E Integration & Validation - Master Test Runner')
.option('-e, --environment <env>', 'Test environment (staging|docker|production)', 'staging')
.option('-u, --base-url <url>', 'Base URL for testing')
.option('-h, --headed', 'Run in headed mode (show browser)')
.option('-s, --slow-mo <ms>', 'Slow motion delay in milliseconds', parseInt)
.option('-t, --timeout <ms>', 'Total execution timeout in milliseconds', parseInt)
.option('-c, --continue-on-failure', 'Continue execution even if phases fail')
.option('--skip-orchestration', 'Skip master test orchestration phase')
.option('--skip-workflows', 'Skip cross-functional workflows phase')
.option('--skip-performance', 'Skip performance testing phase')
.option('--skip-recovery', 'Skip error recovery testing phase')
.option('--performance-only', 'Run only performance testing')
.option('--recovery-only', 'Run only error recovery testing')
.option('--ignore-performance-target', 'Ignore performance target for success evaluation')
.parse();
return program.opts();
}
// Main execution
async function main() {
const cliOptions = setupCLI();
// Configure based on CLI options
const config = {
...DEFAULT_CONFIG,
...cliOptions
};
// Handle environment-specific URLs
if (config.environment === 'docker') {
config.baseUrl = config.baseUrl || config.dockerUrl;
}
// Handle specialized execution modes
if (config.performanceOnly) {
config.skipOrchestration = true;
config.skipWorkflows = true;
config.skipRecovery = true;
}
if (config.recoveryOnly) {
config.skipOrchestration = true;
config.skipWorkflows = true;
config.skipPerformance = true;
}
// Set display environment for headed mode
if (!config.headless) {
process.env.DISPLAY = config.display;
process.env.XAUTHORITY = config.xAuthority;
}
// Initialize and execute
const runner = new MasterTestRunner(config);
const success = await runner.execute();
process.exit(success ? 0 : 1);
}
// Execute if run directly
if (require.main === module) {
main().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});
}
module.exports = MasterTestRunner;