upskill-event-manager/tests/framework/setup/global-teardown.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

388 lines
No EOL
14 KiB
JavaScript
Raw Permalink 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.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Global Test Teardown for HVAC Testing Framework
*
* Runs once after all tests to:
* - Clean up test data and artifacts
* - Generate final reports
* - Archive screenshots and videos
* - Display test summary
*
* @package HVAC_Community_Events
* @version 2.0.0
* @created 2025-08-27
*/
const ConfigManager = require('../core/ConfigManager');
const AuthManager = require('../core/AuthManager');
const WordPressUtils = require('../utils/WordPressUtils');
const ScreenshotManager = require('../utils/ScreenshotManager');
const fs = require('fs').promises;
const path = require('path');
async function globalTeardown(config) {
console.log('\n🏁 HVAC Testing Framework - Global Teardown');
console.log('='.repeat(50));
const startTime = Date.now();
const configManager = ConfigManager;
const authManager = AuthManager;
const wpUtils = new WordPressUtils();
const screenshotManager = new ScreenshotManager();
try {
// 1. Clean Up Test Data
console.log('\n🧹 1. Cleaning Up Test Data');
const environment = configManager.getEnvironment();
if (configManager.get('testData.cleanupAfterTests') && environment !== 'staging') {
try {
// Clean up WordPress test data
const testIds = await getTestIds();
for (const testId of testIds) {
await wpUtils.cleanupTestData(testId);
}
console.log(` ✅ Cleaned up ${testIds.length} test datasets`);
} catch (error) {
console.warn(' ⚠️ Test data cleanup failed:', error.message);
}
} else {
console.log(' Skipping test data cleanup (staging environment)');
}
// 2. Authentication State Management
console.log('\n🔐 2. Authentication State Management');
// Get auth status before cleanup
const authStatus = await authManager.getAuthStatus();
console.log(` 📊 Storage states: ${Object.keys(authStatus).length} roles`);
// Clear validation cache
authManager.clearValidationCache();
console.log(' ✅ Validation cache cleared');
// Clean up old storage states if configured
if (environment === 'local') {
// Only clean on local environment
const oldStatesCount = await cleanOldStorageStates();
if (oldStatesCount > 0) {
console.log(` 🗑️ Removed ${oldStatesCount} old storage states`);
}
}
// 3. Generate Screenshot Reports
console.log('\n📸 3. Processing Screenshots and Media');
try {
// Generate screenshot report
const screenshotReport = await screenshotManager.generateReport();
if (screenshotReport) {
console.log(` 📊 Screenshot report: ${screenshotReport.totalScreenshots} files`);
}
// Create screenshot gallery
const galleryPath = await screenshotManager.createGallery('HVAC Test Results');
if (galleryPath) {
console.log(` 🖼️ Screenshot gallery: ${galleryPath}`);
}
// Clean up old screenshots if configured
const daysToKeep = 7;
await screenshotManager.cleanup(daysToKeep);
} catch (error) {
console.warn(' ⚠️ Screenshot processing failed:', error.message);
}
// 4. Generate Final Test Report
console.log('\n📊 4. Generating Final Reports');
try {
const finalReport = await generateFinalReport(startTime);
const reportPath = path.resolve('./test-results/final-report.json');
await fs.writeFile(reportPath, JSON.stringify(finalReport, null, 2));
console.log(` ✅ Final report: ${reportPath}`);
// Generate HTML summary
const htmlReport = await generateHTMLReport(finalReport);
const htmlPath = path.resolve('./test-results/summary.html');
await fs.writeFile(htmlPath, htmlReport);
console.log(` 📄 HTML report: ${htmlPath}`);
} catch (error) {
console.warn(' ⚠️ Report generation failed:', error.message);
}
// 5. Archive Test Artifacts
console.log('\n📦 5. Archiving Test Artifacts');
try {
await archiveTestArtifacts();
console.log(' ✅ Test artifacts archived');
} catch (error) {
console.warn(' ⚠️ Archiving failed:', error.message);
}
// 6. WordPress Cleanup (if safe)
console.log('\n⚙ 6. WordPress Environment Cleanup');
if (environment === 'local' || environment === 'docker') {
try {
// Clear cache one final time
await wpUtils.clearCache();
console.log(' ✅ Final cache clear');
} catch (error) {
console.warn(' ⚠️ WordPress cleanup failed:', error.message);
}
} else {
console.log(' Skipping WordPress cleanup (staging environment)');
}
// 7. Display Final Summary
console.log('\n📋 7. Test Session Summary');
await displayTestSummary();
// 8. Final Teardown Report
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log('\n' + '='.repeat(50));
console.log('✅ Global Teardown Complete');
console.log(`⏱️ Teardown Duration: ${duration}s`);
console.log(`🌍 Environment: ${environment}`);
console.log('='.repeat(50) + '\n');
} catch (error) {
console.error('\n❌ Global Teardown Failed');
console.error('Error:', error.message);
console.error('='.repeat(50) + '\n');
// Don't throw - teardown failures shouldn't fail the test suite
}
}
/**
* Get list of test IDs for cleanup
*/
async function getTestIds() {
try {
const testResults = await fs.readFile('./test-results/test-metrics.jsonl', 'utf8');
const lines = testResults.trim().split('\n');
const testIds = lines
.map(line => JSON.parse(line))
.map(test => test.testId)
.filter(id => id.startsWith('hvac-test-'));
return [...new Set(testIds)]; // Remove duplicates
} catch (error) {
return [];
}
}
/**
* Clean old storage states
*/
async function cleanOldStorageStates() {
try {
const storageStatesDir = path.resolve(__dirname, '../fixtures/storage-states');
const files = await fs.readdir(storageStatesDir);
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - 7);
let deletedCount = 0;
for (const file of files) {
if (file.endsWith('.json')) {
const filePath = path.join(storageStatesDir, file);
const stats = await fs.stat(filePath);
if (stats.mtime < cutoffDate) {
await fs.unlink(filePath);
deletedCount++;
}
}
}
return deletedCount;
} catch (error) {
return 0;
}
}
/**
* Generate comprehensive final report
*/
async function generateFinalReport(startTime) {
const report = {
timestamp: new Date().toISOString(),
environment: ConfigManager.getEnvironment(),
teardownDuration: Date.now() - startTime,
framework: {
version: '2.0.0',
features: ConfigManager.get('features')
}
};
// Add test metrics if available
try {
const metricsFile = './test-results/test-metrics.jsonl';
const metricsData = await fs.readFile(metricsFile, 'utf8');
const metrics = metricsData.trim().split('\n').map(line => JSON.parse(line));
report.testMetrics = {
totalTests: metrics.length,
passed: metrics.filter(t => t.passed).length,
failed: metrics.filter(t => !t.passed).length,
categories: groupBy(metrics, 'category'),
avgDuration: metrics.reduce((sum, t) => sum + t.duration, 0) / metrics.length
};
} catch (error) {
report.testMetrics = { error: 'Metrics not available' };
}
return report;
}
/**
* Generate HTML report
*/
async function generateHTMLReport(report) {
const testMetrics = report.testMetrics || {};
const passRate = testMetrics.totalTests ?
((testMetrics.passed / testMetrics.totalTests) * 100).toFixed(1) : 'N/A';
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HVAC Test Results Summary</title>
<style>
body { font-family: system-ui, sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }
.header { text-align: center; background: white; padding: 30px; border-radius: 8px; margin-bottom: 20px; }
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; }
.metric { background: white; padding: 20px; border-radius: 8px; text-align: center; }
.metric h3 { margin: 0; color: #333; }
.metric .value { font-size: 2em; font-weight: bold; margin: 10px 0; }
.passed { color: #28a745; }
.failed { color: #dc3545; }
.info { background: white; padding: 20px; border-radius: 8px; margin-top: 20px; }
pre { background: #f8f9fa; padding: 15px; border-radius: 4px; overflow-x: auto; }
</style>
</head>
<body>
<div class="header">
<h1>🧪 HVAC Testing Framework Results</h1>
<p><strong>Environment:</strong> ${report.environment}</p>
<p><strong>Generated:</strong> ${new Date(report.timestamp).toLocaleString()}</p>
</div>
<div class="metrics">
<div class="metric">
<h3>Total Tests</h3>
<div class="value">${testMetrics.totalTests || 0}</div>
</div>
<div class="metric">
<h3>Passed</h3>
<div class="value passed">${testMetrics.passed || 0}</div>
</div>
<div class="metric">
<h3>Failed</h3>
<div class="value failed">${testMetrics.failed || 0}</div>
</div>
<div class="metric">
<h3>Pass Rate</h3>
<div class="value">${passRate}%</div>
</div>
</div>
<div class="info">
<h2>📊 Detailed Report</h2>
<pre>${JSON.stringify(report, null, 2)}</pre>
</div>
</body>
</html>
`;
}
/**
* Archive test artifacts
*/
async function archiveTestArtifacts() {
const archiveDir = path.resolve('./test-results/archives');
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const archiveName = `test-session-${timestamp}`;
const sessionArchive = path.join(archiveDir, archiveName);
await fs.mkdir(sessionArchive, { recursive: true });
// Copy important files to archive
const filesToArchive = [
'./test-results/final-report.json',
'./test-results/summary.html',
'./test-results/setup-report.json'
];
for (const file of filesToArchive) {
try {
const filename = path.basename(file);
const sourcePath = path.resolve(file);
const destPath = path.join(sessionArchive, filename);
await fs.copyFile(sourcePath, destPath);
} catch (error) {
// File might not exist, continue
}
}
}
/**
* Display test session summary
*/
async function displayTestSummary() {
try {
const metricsFile = './test-results/test-metrics.jsonl';
const metricsData = await fs.readFile(metricsFile, 'utf8');
const metrics = metricsData.trim().split('\n').map(line => JSON.parse(line));
const totalTests = metrics.length;
const passed = metrics.filter(t => t.passed).length;
const failed = metrics.filter(t => !t.passed).length;
const passRate = ((passed / totalTests) * 100).toFixed(1);
console.log(` 📊 Total Tests: ${totalTests}`);
console.log(` ✅ Passed: ${passed}`);
console.log(` ❌ Failed: ${failed}`);
console.log(` 📈 Pass Rate: ${passRate}%`);
if (failed > 0) {
console.log('\n ❌ Failed Tests:');
metrics
.filter(t => !t.passed)
.slice(0, 5) // Show first 5 failures
.forEach(t => console.log(` - ${t.title}`));
if (failed > 5) {
console.log(` ... and ${failed - 5} more`);
}
}
} catch (error) {
console.log(' No test metrics available');
}
}
/**
* Helper function to group by property
*/
function groupBy(array, property) {
return array.reduce((groups, item) => {
const key = item[property] || 'unknown';
groups[key] = (groups[key] || 0) + 1;
return groups;
}, {});
}
module.exports = globalTeardown;