/**
* Orchestrators for running multiple tests across categories
*/
import { analyzePageSpeed, PageSpeedResult } from '../performance/pagespeed.js';
import { analyzeWebPageTest, WebPageTestResult } from '../performance/webpagetest.js';
import { analyzeGTmetrix, GTmetrixResult } from '../performance/gtmetrix.js';
import { analyzeWAVE, WAVEResult } from '../accessibility/wave.js';
import { analyzeAxe, AxeResult } from '../accessibility/axe.js';
import { analyzeMozillaObservatory, MozillaObservatoryResult } from '../security/mozilla-observatory.js';
import { analyzeSSLLabs, analyzeSSLLabsComplete, SSLLabsResult } from '../security/ssl-labs.js';
export interface PerformanceTestOptions {
pagespeed?: { apiKey?: string; strategy?: 'mobile' | 'desktop' };
gtmetrix?: { apiKey: string };
webpagetest?: { location?: string; runs?: number; waitForResults?: boolean };
}
export interface AccessibilityTestOptions {
wave?: { apiKey: string };
axe?: { wcagLevel?: string };
}
export interface SecurityTestOptions {
sslLabs: { email: string; waitForComplete?: boolean };
}
export interface AllPerformanceResult {
url: string;
timestamp: string;
pagespeed?: PageSpeedResult;
webpagetest?: WebPageTestResult;
gtmetrix?: GTmetrixResult;
summary: {
tools_run: string[];
avg_performance_score?: number;
};
}
export interface AllAccessibilityResult {
url: string;
timestamp: string;
wave?: WAVEResult;
axe?: AxeResult;
summary: {
tools_run: string[];
total_violations: number;
};
}
export interface AllSEOResult {
url: string;
timestamp: string;
pagespeed_seo?: PageSpeedResult;
summary: {
tools_run: string[];
seo_score?: number;
};
}
export interface AllSecurityResult {
url: string;
timestamp: string;
mozilla_observatory: MozillaObservatoryResult;
ssl_labs: SSLLabsResult;
summary: {
mozilla_grade: string;
ssl_grade?: string;
overall_success: boolean;
};
}
export interface ComprehensiveResult {
url: string;
timestamp: string;
performance?: AllPerformanceResult;
accessibility?: AllAccessibilityResult;
seo?: AllSEOResult;
security?: AllSecurityResult;
summary: {
categories_tested: string[];
overall_health: 'excellent' | 'good' | 'fair' | 'poor';
critical_issues: number;
};
}
/**
* Run all performance tests
*/
export async function runAllPerformance(
url: string,
options: PerformanceTestOptions = {}
): Promise<AllPerformanceResult> {
const results: AllPerformanceResult = {
url,
timestamp: new Date().toISOString(),
summary: {
tools_run: [],
},
};
// Always run PageSpeed (free API)
results.pagespeed = await analyzePageSpeed(url, options.pagespeed || {});
results.summary.tools_run.push('pagespeed');
// Optional: WebPageTest (free, browser automation)
if (options.webpagetest) {
results.webpagetest = await analyzeWebPageTest(url, options.webpagetest);
results.summary.tools_run.push('webpagetest');
}
// Optional: GTmetrix (requires API key)
if (options.gtmetrix?.apiKey) {
results.gtmetrix = await analyzeGTmetrix(url, options.gtmetrix);
results.summary.tools_run.push('gtmetrix');
}
// Calculate average score
const scores = [results.pagespeed?.performance_score].filter(s => s !== undefined) as number[];
if (scores.length > 0) {
results.summary.avg_performance_score = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
}
return results;
}
/**
* Run all accessibility tests
*/
export async function runAllAccessibility(
url: string,
options: AccessibilityTestOptions = {}
): Promise<AllAccessibilityResult> {
const results: AllAccessibilityResult = {
url,
timestamp: new Date().toISOString(),
summary: {
tools_run: [],
total_violations: 0,
},
};
// Always run Axe (free, open source)
results.axe = await analyzeAxe(url, options.axe || {});
results.summary.tools_run.push('axe');
results.summary.total_violations += results.axe.violations;
// Optional: WAVE (requires API key)
if (options.wave?.apiKey) {
results.wave = await analyzeWAVE(url, options.wave);
results.summary.tools_run.push('wave');
results.summary.total_violations += results.wave.errors + results.wave.contrast_errors;
}
return results;
}
/**
* Run all SEO tests
* Uses PageSpeed Insights (Lighthouse SEO)
*/
export async function runAllSEO(url: string): Promise<AllSEOResult> {
const results: AllSEOResult = {
url,
timestamp: new Date().toISOString(),
summary: {
tools_run: [],
},
};
// Use PageSpeed Insights (includes Lighthouse SEO)
const pagespeed = await analyzePageSpeed(url, { categories: ['seo'] });
results.pagespeed_seo = pagespeed;
if (pagespeed.success) {
results.summary.tools_run.push('pagespeed');
results.summary.seo_score = pagespeed.seo_score;
}
return results;
}
/**
* Run all security tests
*/
export async function runAllSecurity(
url: string,
options: SecurityTestOptions
): Promise<AllSecurityResult> {
// Run both security tools
const mozillaResult = await analyzeMozillaObservatory(url);
const sslResult = options.sslLabs.waitForComplete
? await analyzeSSLLabsComplete(url, options.sslLabs)
: await analyzeSSLLabs(url, options.sslLabs);
return {
url,
timestamp: new Date().toISOString(),
mozilla_observatory: mozillaResult,
ssl_labs: sslResult,
summary: {
mozilla_grade: mozillaResult.grade,
ssl_grade: sslResult.grade,
overall_success: mozillaResult.success && (sslResult.success || sslResult.status !== 'ERROR'),
},
};
}
/**
* Run comprehensive validation across all categories
*/
export async function runComprehensive(
url: string,
options: {
performance?: PerformanceTestOptions;
accessibility?: AccessibilityTestOptions;
security: SecurityTestOptions;
categories?: Array<'performance' | 'accessibility' | 'seo' | 'security'>;
}
): Promise<ComprehensiveResult> {
const categories = options.categories || ['performance', 'accessibility', 'seo', 'security'];
const result: ComprehensiveResult = {
url,
timestamp: new Date().toISOString(),
summary: {
categories_tested: categories,
overall_health: 'good',
critical_issues: 0,
},
};
// Run selected categories
if (categories.includes('performance') && options.performance) {
result.performance = await runAllPerformance(url, options.performance);
}
if (categories.includes('accessibility') && options.accessibility) {
result.accessibility = await runAllAccessibility(url, options.accessibility);
result.summary.critical_issues += result.accessibility.axe?.critical || 0;
}
if (categories.includes('seo')) {
result.seo = await runAllSEO(url);
}
if (categories.includes('security')) {
result.security = await runAllSecurity(url, options.security);
}
// Calculate overall health
if (result.summary.critical_issues > 5) {
result.summary.overall_health = 'poor';
} else if (result.summary.critical_issues > 2) {
result.summary.overall_health = 'fair';
}
return result;
}