/** * 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 `
Environment: ${report.environment}
Generated: ${new Date(report.timestamp).toLocaleString()}
${JSON.stringify(report, null, 2)}