veza/veza-desktop/scripts/production-tests.js

258 lines
7.3 KiB
JavaScript

#!/usr/bin/env node
/**
* Script de tests de production pour Veza V5 Ultra
* Objectif: 100% tests passés, 0 bugs critiques
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('🧪 VEZA V5 ULTRA - Production Tests');
console.log('===================================\n');
// Configuration des tests
const testConfig = {
unit: {
command: 'npm run test:unit',
coverage: 80,
timeout: 30000,
},
e2e: {
command: 'npm run test:e2e',
timeout: 60000,
},
lighthouse: {
command: 'npm run lighthouse:ci',
score: 100,
},
performance: {
command: 'npm run test:perf',
fcp: 0.8, // First Contentful Paint < 0.8s
tti: 1.5, // Time to Interactive < 1.5s
cls: 0.1, // Cumulative Layout Shift < 0.1
},
accessibility: {
command: 'npm run test:a11y',
score: 100,
},
};
// Fonction pour exécuter un test
function runTest(name, config) {
console.log(`\n🔍 Running ${name}...`);
try {
const startTime = Date.now();
const result = execSync(config.command, {
encoding: 'utf8',
timeout: config.timeout || 30000,
stdio: 'pipe'
});
const duration = (Date.now() - startTime) / 1000;
console.log(`${name} passed in ${duration.toFixed(2)}s`);
// Analyser les résultats spécifiques
if (name === 'Unit Tests' && config.coverage) {
const coverageMatch = result.match(/(\d+)%/);
if (coverageMatch) {
const coverage = parseInt(coverageMatch[1]);
if (coverage >= config.coverage) {
console.log(`✅ Coverage: ${coverage}% (target: ${config.coverage}%)`);
} else {
console.log(`⚠️ Coverage: ${coverage}% (target: ${config.coverage}%)`);
}
}
}
if (name === 'Lighthouse' && config.score) {
const scoreMatch = result.match(/Performance: (\d+)/);
if (scoreMatch) {
const score = parseInt(scoreMatch[1]);
if (score >= config.score) {
console.log(`✅ Lighthouse Score: ${score}/100`);
} else {
console.log(`⚠️ Lighthouse Score: ${score}/100 (target: ${config.score})`);
}
}
}
return { success: true, duration, result };
} catch (error) {
console.log(`${name} failed:`, error.message);
return { success: false, error: error.message };
}
}
// Fonction pour vérifier les métriques de performance
function checkPerformanceMetrics() {
console.log('\n📊 Checking Performance Metrics...');
const metrics = {
bundleSize: checkBundleSize(),
buildTime: checkBuildTime(),
memoryUsage: checkMemoryUsage(),
};
return metrics;
}
function checkBundleSize() {
const distPath = path.join(__dirname, '..', 'dist');
if (!fs.existsSync(distPath)) {
return { error: 'No dist folder found' };
}
let totalSize = 0;
let jsFiles = [];
function scanDir(dir) {
const files = fs.readdirSync(dir);
files.forEach(file => {
const filePath = path.join(dir, file);
if (fs.statSync(filePath).isDirectory()) {
scanDir(filePath);
} else if (file.endsWith('.js')) {
const size = fs.statSync(filePath).size;
totalSize += size;
jsFiles.push({ name: file, size });
}
});
}
scanDir(distPath);
const initialBundle = jsFiles.find(f => f.name.includes('index'))?.size || 0;
const maxChunk = Math.max(...jsFiles.map(f => f.size));
return {
total: totalSize,
initial: initialBundle,
maxChunk,
files: jsFiles.length,
target: 150 * 1024, // 150KB
};
}
function checkBuildTime() {
const startTime = Date.now();
try {
execSync('npm run build', { stdio: 'pipe' });
return Date.now() - startTime;
} catch (error) {
return { error: error.message };
}
}
function checkMemoryUsage() {
const usage = process.memoryUsage();
return {
rss: Math.round(usage.rss / 1024 / 1024), // MB
heapUsed: Math.round(usage.heapUsed / 1024 / 1024), // MB
heapTotal: Math.round(usage.heapTotal / 1024 / 1024), // MB
};
}
// Fonction pour générer le rapport de tests
function generateTestReport(results) {
const report = {
timestamp: new Date().toISOString(),
summary: {
total: Object.keys(testConfig).length,
passed: Object.values(results).filter(r => r.success).length,
failed: Object.values(results).filter(r => !r.success).length,
},
results,
performance: checkPerformanceMetrics(),
};
const reportPath = path.join(__dirname, '..', 'test-report-production.json');
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
console.log(`\n📄 Test report saved to: ${reportPath}`);
return report;
}
// Exécuter tous les tests
async function runAllTests() {
console.log('🚀 Starting Production Test Suite...\n');
const results = {};
// Tests unitaires
results.unit = runTest('Unit Tests', testConfig.unit);
// Tests E2E
results.e2e = runTest('E2E Tests', testConfig.e2e);
// Tests Lighthouse
results.lighthouse = runTest('Lighthouse', testConfig.lighthouse);
// Tests de performance
results.performance = runTest('Performance Tests', testConfig.performance);
// Tests d'accessibilité
results.accessibility = runTest('Accessibility Tests', testConfig.accessibility);
// Générer le rapport
const report = generateTestReport(results);
// Afficher le résumé
console.log('\n📋 TEST SUMMARY');
console.log('================');
console.log(`Total Tests: ${report.summary.total}`);
console.log(`Passed: ${report.summary.passed}`);
console.log(`Failed: ${report.summary.failed}`);
console.log(`Success Rate: ${((report.summary.passed / report.summary.total) * 100).toFixed(1)}%`);
// Métriques de performance
console.log('\n📊 PERFORMANCE METRICS');
console.log('======================');
if (report.performance.bundleSize) {
const bundle = report.performance.bundleSize;
console.log(`Bundle Size: ${(bundle.initial / 1024).toFixed(2)} KB (target: < 150 KB)`);
console.log(`Max Chunk: ${(bundle.maxChunk / 1024).toFixed(2)} KB (target: < 50 KB)`);
console.log(`Total Files: ${bundle.files}`);
}
if (report.performance.buildTime) {
console.log(`Build Time: ${(report.performance.buildTime / 1000).toFixed(2)}s`);
}
if (report.performance.memoryUsage) {
const mem = report.performance.memoryUsage;
console.log(`Memory Usage: ${mem.heapUsed}MB / ${mem.heapTotal}MB`);
}
// Recommandations
console.log('\n💡 RECOMMENDATIONS');
console.log('==================');
if (report.summary.failed > 0) {
console.log('❌ Fix failing tests before production deployment');
}
if (report.performance.bundleSize?.initial > report.performance.bundleSize?.target) {
console.log('⚠️ Bundle size too large - consider code splitting');
}
if (report.performance.buildTime > 30000) {
console.log('⚠️ Build time too slow - consider optimization');
}
if (report.summary.passed === report.summary.total) {
console.log('🎉 All tests passed! Ready for production deployment');
}
return report.summary.passed === report.summary.total;
}
// Exécuter les tests
runAllTests().then(success => {
process.exit(success ? 0 : 1);
}).catch(error => {
console.error('❌ Test suite failed:', error);
process.exit(1);
});