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
- 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>
418 lines
No EOL
15 KiB
JavaScript
418 lines
No EOL
15 KiB
JavaScript
/**
|
|
* Global Teardown for Advanced HVAC Testing
|
|
*
|
|
* Performs post-test cleanup and reporting:
|
|
* - Generate final test report
|
|
* - Clean up test data
|
|
* - Archive test artifacts
|
|
* - Performance analysis
|
|
* - Accessibility report summary
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
async function globalTeardown(config) {
|
|
console.log('🏁 Starting Advanced HVAC E2E Test Suite Teardown...');
|
|
|
|
const REPORTS_DIR = path.join(__dirname, '../../reports');
|
|
const TIMESTAMP = new Date().toISOString().replace(/[:.]/g, '-');
|
|
|
|
try {
|
|
// Read the main test report
|
|
const testReportPath = path.join(REPORTS_DIR, 'advanced-test-report.json');
|
|
let testReport = {};
|
|
|
|
if (fs.existsSync(testReportPath)) {
|
|
testReport = JSON.parse(fs.readFileSync(testReportPath, 'utf8'));
|
|
}
|
|
|
|
// Generate comprehensive final report
|
|
const finalReport = {
|
|
metadata: {
|
|
generatedAt: new Date().toISOString(),
|
|
testSuiteVersion: '1.0.0',
|
|
environment: 'staging',
|
|
testDuration: 'calculated-during-tests'
|
|
},
|
|
summary: {
|
|
totalTests: testReport.totalTests || 0,
|
|
passedTests: testReport.passedTests || 0,
|
|
failedTests: testReport.failedTests || 0,
|
|
successRate: testReport.successRate || '0%',
|
|
categories: {
|
|
functionality: 0,
|
|
performance: 0,
|
|
accessibility: 0,
|
|
crossBrowser: 0,
|
|
mobile: 0,
|
|
errorHandling: 0
|
|
}
|
|
},
|
|
detailedResults: testReport.testMatrix || {},
|
|
performanceAnalysis: analyzePerformance(testReport.performanceMetrics || {}),
|
|
accessibilityAnalysis: analyzeAccessibility(testReport.accessibilityIssues || []),
|
|
recommendations: testReport.recommendations || [],
|
|
riskAssessment: generateRiskAssessment(testReport),
|
|
artifacts: {
|
|
screenshots: listFiles(path.join(REPORTS_DIR, 'screenshots')),
|
|
videos: listFiles(path.join(REPORTS_DIR, 'videos')),
|
|
traces: listFiles(path.join(REPORTS_DIR, 'traces')),
|
|
reports: listFiles(REPORTS_DIR, '.json')
|
|
}
|
|
};
|
|
|
|
// Calculate category scores
|
|
if (testReport.testMatrix) {
|
|
Object.keys(testReport.testMatrix).forEach(testName => {
|
|
const result = testReport.testMatrix[testName];
|
|
if (result.passed) {
|
|
if (testName.toLowerCase().includes('performance') || testName.toLowerCase().includes('network')) {
|
|
finalReport.summary.categories.performance++;
|
|
} else if (testName.toLowerCase().includes('accessibility')) {
|
|
finalReport.summary.categories.accessibility++;
|
|
} else if (testName.toLowerCase().includes('browser') || testName.toLowerCase().includes('chromium') || testName.toLowerCase().includes('firefox') || testName.toLowerCase().includes('webkit')) {
|
|
finalReport.summary.categories.crossBrowser++;
|
|
} else if (testName.toLowerCase().includes('mobile') || testName.toLowerCase().includes('responsive')) {
|
|
finalReport.summary.categories.mobile++;
|
|
} else if (testName.toLowerCase().includes('error') || testName.toLowerCase().includes('recovery') || testName.toLowerCase().includes('failure')) {
|
|
finalReport.summary.categories.errorHandling++;
|
|
} else {
|
|
finalReport.summary.categories.functionality++;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Save final report
|
|
const finalReportPath = path.join(REPORTS_DIR, `final-test-report-${TIMESTAMP}.json`);
|
|
fs.writeFileSync(finalReportPath, JSON.stringify(finalReport, null, 2));
|
|
|
|
// Generate HTML summary report
|
|
generateHtmlSummary(finalReport, path.join(REPORTS_DIR, `test-summary-${TIMESTAMP}.html`));
|
|
|
|
// Generate executive summary
|
|
generateExecutiveSummary(finalReport, path.join(REPORTS_DIR, `executive-summary-${TIMESTAMP}.md`));
|
|
|
|
console.log('📊 Test Results Summary:');
|
|
console.log(` Total Tests: ${finalReport.summary.totalTests}`);
|
|
console.log(` Passed: ${finalReport.summary.passedTests}`);
|
|
console.log(` Failed: ${finalReport.summary.failedTests}`);
|
|
console.log(` Success Rate: ${finalReport.summary.successRate}`);
|
|
console.log('');
|
|
console.log('📁 Generated Reports:');
|
|
console.log(` Final Report: ${finalReportPath}`);
|
|
console.log(` HTML Summary: test-summary-${TIMESTAMP}.html`);
|
|
console.log(` Executive Summary: executive-summary-${TIMESTAMP}.md`);
|
|
|
|
// Clean up temporary files if requested
|
|
if (process.env.CLEANUP_TEMP === 'true') {
|
|
console.log('🧹 Cleaning up temporary test files...');
|
|
// Add cleanup logic here
|
|
}
|
|
|
|
console.log('✅ Advanced HVAC E2E Test Suite Teardown Complete!');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Teardown encountered errors:', error.message);
|
|
|
|
// Create error report
|
|
const errorReport = {
|
|
timestamp: new Date().toISOString(),
|
|
phase: 'teardown',
|
|
error: error.message,
|
|
stack: error.stack
|
|
};
|
|
|
|
fs.writeFileSync(
|
|
path.join(REPORTS_DIR, `teardown-error-${TIMESTAMP}.json`),
|
|
JSON.stringify(errorReport, null, 2)
|
|
);
|
|
}
|
|
}
|
|
|
|
function analyzePerformance(performanceMetrics) {
|
|
const analysis = {
|
|
averageLoadTime: 0,
|
|
slowestPage: '',
|
|
fastestPage: '',
|
|
performanceScore: 'Good',
|
|
recommendations: []
|
|
};
|
|
|
|
const loadTimes = [];
|
|
let slowestTime = 0;
|
|
let fastestTime = Infinity;
|
|
|
|
Object.keys(performanceMetrics).forEach(testName => {
|
|
const metrics = performanceMetrics[testName];
|
|
if (metrics.navigation && metrics.navigation.loadEventEnd) {
|
|
const loadTime = metrics.navigation.loadEventEnd - metrics.navigation.fetchStart;
|
|
loadTimes.push(loadTime);
|
|
|
|
if (loadTime > slowestTime) {
|
|
slowestTime = loadTime;
|
|
analysis.slowestPage = testName;
|
|
}
|
|
|
|
if (loadTime < fastestTime) {
|
|
fastestTime = loadTime;
|
|
analysis.fastestPage = testName;
|
|
}
|
|
}
|
|
|
|
if (metrics.loadTime) {
|
|
loadTimes.push(metrics.loadTime);
|
|
}
|
|
});
|
|
|
|
if (loadTimes.length > 0) {
|
|
analysis.averageLoadTime = Math.round(loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length);
|
|
|
|
if (analysis.averageLoadTime > 5000) {
|
|
analysis.performanceScore = 'Poor';
|
|
analysis.recommendations.push('Consider optimizing page load times - average exceeds 5 seconds');
|
|
} else if (analysis.averageLoadTime > 3000) {
|
|
analysis.performanceScore = 'Fair';
|
|
analysis.recommendations.push('Page load times could be improved - average exceeds 3 seconds');
|
|
}
|
|
}
|
|
|
|
return analysis;
|
|
}
|
|
|
|
function analyzeAccessibility(accessibilityIssues) {
|
|
const analysis = {
|
|
totalViolations: 0,
|
|
criticalIssues: 0,
|
|
moderateIssues: 0,
|
|
minorIssues: 0,
|
|
complianceLevel: 'Unknown',
|
|
topIssues: []
|
|
};
|
|
|
|
const issueCount = {};
|
|
|
|
accessibilityIssues.forEach(issue => {
|
|
issue.violations.forEach(violation => {
|
|
analysis.totalViolations++;
|
|
|
|
if (violation.impact === 'critical') {
|
|
analysis.criticalIssues++;
|
|
} else if (violation.impact === 'serious') {
|
|
analysis.moderateIssues++;
|
|
} else {
|
|
analysis.minorIssues++;
|
|
}
|
|
|
|
issueCount[violation.id] = (issueCount[violation.id] || 0) + 1;
|
|
});
|
|
});
|
|
|
|
// Determine compliance level
|
|
if (analysis.criticalIssues === 0 && analysis.moderateIssues === 0) {
|
|
analysis.complianceLevel = 'WCAG 2.1 AA Compliant';
|
|
} else if (analysis.criticalIssues === 0) {
|
|
analysis.complianceLevel = 'Partially Compliant';
|
|
} else {
|
|
analysis.complianceLevel = 'Non-Compliant';
|
|
}
|
|
|
|
// Top issues
|
|
analysis.topIssues = Object.entries(issueCount)
|
|
.sort(([,a], [,b]) => b - a)
|
|
.slice(0, 5)
|
|
.map(([issue, count]) => ({ issue, count }));
|
|
|
|
return analysis;
|
|
}
|
|
|
|
function generateRiskAssessment(testReport) {
|
|
const risks = [];
|
|
|
|
const successRate = parseFloat(testReport.successRate) || 0;
|
|
|
|
if (successRate < 70) {
|
|
risks.push({
|
|
level: 'HIGH',
|
|
category: 'Functionality',
|
|
description: 'Low test success rate indicates significant functionality issues',
|
|
impact: 'User experience severely compromised'
|
|
});
|
|
} else if (successRate < 85) {
|
|
risks.push({
|
|
level: 'MEDIUM',
|
|
category: 'Functionality',
|
|
description: 'Moderate test failures may impact user experience',
|
|
impact: 'Some features may not work as expected'
|
|
});
|
|
}
|
|
|
|
if (testReport.accessibilityIssues && testReport.accessibilityIssues.length > 0) {
|
|
const criticalAccessibilityIssues = testReport.accessibilityIssues
|
|
.flatMap(issue => issue.violations)
|
|
.filter(violation => violation.impact === 'critical').length;
|
|
|
|
if (criticalAccessibilityIssues > 0) {
|
|
risks.push({
|
|
level: 'HIGH',
|
|
category: 'Accessibility',
|
|
description: 'Critical accessibility violations detected',
|
|
impact: 'Application may be unusable for users with disabilities'
|
|
});
|
|
}
|
|
}
|
|
|
|
return {
|
|
overallRisk: risks.length > 0 ? risks[0].level : 'LOW',
|
|
risks
|
|
};
|
|
}
|
|
|
|
function generateHtmlSummary(report, filePath) {
|
|
const html = `
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HVAC Trainer Events - Advanced Test Report</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 40px; }
|
|
.header { border-bottom: 2px solid #007cba; padding-bottom: 20px; }
|
|
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; }
|
|
.metric { background: #f9f9f9; padding: 15px; border-radius: 5px; text-align: center; }
|
|
.metric h3 { margin: 0 0 10px 0; color: #007cba; }
|
|
.metric .value { font-size: 24px; font-weight: bold; }
|
|
.passed { color: #4CAF50; }
|
|
.failed { color: #F44336; }
|
|
.table { width: 100%; border-collapse: collapse; margin: 20px 0; }
|
|
.table th, .table td { padding: 10px; border: 1px solid #ddd; text-align: left; }
|
|
.table th { background: #007cba; color: white; }
|
|
.risk-high { color: #F44336; font-weight: bold; }
|
|
.risk-medium { color: #FF9800; font-weight: bold; }
|
|
.risk-low { color: #4CAF50; font-weight: bold; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<h1>HVAC Trainer Events System - Advanced Test Report</h1>
|
|
<p>Generated: ${report.metadata.generatedAt}</p>
|
|
<p>Environment: ${report.metadata.environment}</p>
|
|
</div>
|
|
|
|
<div class="summary">
|
|
<div class="metric">
|
|
<h3>Total Tests</h3>
|
|
<div class="value">${report.summary.totalTests}</div>
|
|
</div>
|
|
<div class="metric">
|
|
<h3>Success Rate</h3>
|
|
<div class="value ${parseFloat(report.summary.successRate) >= 85 ? 'passed' : 'failed'}">${report.summary.successRate}</div>
|
|
</div>
|
|
<div class="metric">
|
|
<h3>Passed</h3>
|
|
<div class="value passed">${report.summary.passedTests}</div>
|
|
</div>
|
|
<div class="metric">
|
|
<h3>Failed</h3>
|
|
<div class="value failed">${report.summary.failedTests}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h2>Risk Assessment</h2>
|
|
<p class="risk-${report.riskAssessment.overallRisk.toLowerCase()}">Overall Risk: ${report.riskAssessment.overallRisk}</p>
|
|
|
|
<h2>Performance Analysis</h2>
|
|
<p>Average Load Time: ${report.performanceAnalysis.averageLoadTime}ms</p>
|
|
<p>Performance Score: ${report.performanceAnalysis.performanceScore}</p>
|
|
|
|
<h2>Test Categories</h2>
|
|
<table class="table">
|
|
<tr>
|
|
<th>Category</th>
|
|
<th>Tests Passed</th>
|
|
</tr>
|
|
${Object.entries(report.summary.categories).map(([category, count]) =>
|
|
`<tr><td>${category}</td><td>${count}</td></tr>`
|
|
).join('')}
|
|
</table>
|
|
|
|
<h2>Recommendations</h2>
|
|
<ul>
|
|
${report.recommendations.map(rec => `<li>${rec}</li>`).join('')}
|
|
</ul>
|
|
|
|
</body>
|
|
</html>`;
|
|
|
|
fs.writeFileSync(filePath, html);
|
|
}
|
|
|
|
function generateExecutiveSummary(report, filePath) {
|
|
const markdown = `# HVAC Trainer Events System - Executive Test Summary
|
|
|
|
## Test Overview
|
|
- **Test Date**: ${new Date(report.metadata.generatedAt).toLocaleDateString()}
|
|
- **Environment**: ${report.metadata.environment}
|
|
- **Total Tests Executed**: ${report.summary.totalTests}
|
|
- **Success Rate**: ${report.summary.successRate}
|
|
|
|
## Key Findings
|
|
|
|
### Test Results Summary
|
|
- ✅ **Passed Tests**: ${report.summary.passedTests}
|
|
- ❌ **Failed Tests**: ${report.summary.failedTests}
|
|
- 📊 **Overall Success Rate**: ${report.summary.successRate}
|
|
|
|
### Risk Assessment
|
|
**Overall Risk Level**: ${report.riskAssessment.overallRisk}
|
|
|
|
${report.riskAssessment.risks.map(risk =>
|
|
`- **${risk.level} Risk** (${risk.category}): ${risk.description}`
|
|
).join('\n')}
|
|
|
|
### Performance Metrics
|
|
- **Average Page Load Time**: ${report.performanceAnalysis.averageLoadTime}ms
|
|
- **Performance Score**: ${report.performanceAnalysis.performanceScore}
|
|
|
|
### Accessibility Compliance
|
|
- **Total Violations**: ${report.accessibilityAnalysis.totalViolations}
|
|
- **Compliance Level**: ${report.accessibilityAnalysis.complianceLevel}
|
|
|
|
## Recommendations for Production
|
|
|
|
${report.recommendations.map(rec => `- ${rec}`).join('\n')}
|
|
|
|
## Production Readiness Assessment
|
|
|
|
Based on the test results, the HVAC Trainer Events System is:
|
|
|
|
${parseFloat(report.summary.successRate) >= 90 ? '🟢 **READY FOR PRODUCTION**' :
|
|
parseFloat(report.summary.successRate) >= 75 ? '🟡 **READY WITH MINOR FIXES**' :
|
|
'🔴 **REQUIRES SIGNIFICANT IMPROVEMENTS**'}
|
|
|
|
## Test Coverage by Category
|
|
|
|
${Object.entries(report.summary.categories).map(([category, count]) =>
|
|
`- **${category}**: ${count} tests passed`
|
|
).join('\n')}
|
|
|
|
---
|
|
*Generated by Advanced HVAC E2E Test Suite v${report.metadata.testSuiteVersion}*
|
|
`;
|
|
|
|
fs.writeFileSync(filePath, markdown);
|
|
}
|
|
|
|
function listFiles(dirPath, extension = '') {
|
|
if (!fs.existsSync(dirPath)) {
|
|
return [];
|
|
}
|
|
|
|
return fs.readdirSync(dirPath)
|
|
.filter(file => !extension || file.endsWith(extension))
|
|
.map(file => path.join(dirPath, file));
|
|
}
|
|
|
|
module.exports = globalTeardown; |