#!/usr/bin/env node const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); const E2E_DIR = path.join(__dirname, 'e2e'); const RESULTS_FILE = path.join(__dirname, 'e2e-performance-results.json'); function measureE2ETestPerformance() { console.log('šŸš€ 开始E2Eę€§čƒ½ęµ‹čÆ•...\n'); const startTime = Date.now(); try { const output = execSync('npm run test:e2e', { cwd: __dirname, encoding: 'utf8', stdio: 'pipe' }); const endTime = Date.now(); const duration = (endTime - startTime) / 1000; const results = { timestamp: new Date().toISOString(), duration: duration, durationFormatted: formatDuration(duration), success: true, message: 'E2Eęµ‹čÆ•ę‰§č”ŒęˆåŠŸ' }; saveResults(results); console.log('\nāœ… E2Eęµ‹čÆ•ę‰§č”ŒęˆåŠŸļ¼'); console.log(`ā±ļø ꀻ耗ꗶ: ${results.durationFormatted}`); console.log(`šŸ“Š ę€§čƒ½čÆ„ä¼°: ${evaluatePerformance(duration)}`); return results; } catch (error) { const endTime = Date.now(); const duration = (endTime - startTime) / 1000; const results = { timestamp: new Date().toISOString(), duration: duration, durationFormatted: formatDuration(duration), success: false, message: error.message || 'E2Eęµ‹čÆ•ę‰§č”Œå¤±č“„' }; saveResults(results); console.log('\nāŒ E2Eęµ‹čÆ•ę‰§č”Œå¤±č“„ļ¼'); console.log(`ā±ļø ꀻ耗ꗶ: ${results.durationFormatted}`); console.log(`šŸ“Š ę€§čƒ½čÆ„ä¼°: ${evaluatePerformance(duration)}`); console.log(`šŸ’„ 错误俔息: ${error.message}`); return results; } } function formatDuration(seconds) { const minutes = Math.floor(seconds / 60); const remainingSeconds = Math.floor(seconds % 60); return `${minutes}分${remainingSeconds}ē§’`; } function evaluatePerformance(duration) { if (duration < 60) { return '🟢 ä¼˜ē§€ - ę‰§č”Œę—¶é—“åœØ1分钟仄内'; } else if (duration < 90) { return '🟔 良儽 - ę‰§č”Œę—¶é—“åœØ1.5分钟仄内'; } else if (duration < 120) { return '🟠 äø€čˆ¬ - ę‰§č”Œę—¶é—“åœØ2分钟仄内'; } else { return 'šŸ”“ éœ€č¦ä¼˜åŒ– - ę‰§č”Œę—¶é—“č¶…čæ‡2分钟'; } } function saveResults(results) { const history = []; if (fs.existsSync(RESULTS_FILE)) { const data = fs.readFileSync(RESULTS_FILE, 'utf8'); try { history.push(...JSON.parse(data)); } catch (e) { console.warn('āš ļø ę— ę³•č§£ęžåŽ†å²ē»“ęžœę–‡ä»¶'); } } history.push(results); if (history.length > 10) { history.shift(); } fs.writeFileSync(RESULTS_FILE, JSON.stringify(history, null, 2)); console.log('\nšŸ“ˆ ę€§čƒ½č¶‹åŠæåˆ†ęž:'); analyzePerformanceTrend(history); } function analyzePerformanceTrend(history) { if (history.length < 2) { console.log(' éœ€č¦ę›“å¤šęµ‹čÆ•ę•°ę®ę„åˆ†ęžč¶‹åŠæ'); return; } const successfulTests = history.filter(r => r.success); if (successfulTests.length < 2) { console.log(' éœ€č¦ę›“å¤šęˆåŠŸēš„ęµ‹čÆ•ę•°ę®ę„åˆ†ęžč¶‹åŠæ'); return; } const durations = successfulTests.map(r => r.duration); const avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length; const minDuration = Math.min(...durations); const maxDuration = Math.max(...durations); console.log(` å¹³å‡ę‰§č”Œę—¶é—“: ${formatDuration(avgDuration)}`); console.log(` ęœ€åæ«ę‰§č”Œę—¶é—“: ${formatDuration(minDuration)}`); console.log(` ęœ€ę…¢ę‰§č”Œę—¶é—“: ${formatDuration(maxDuration)}`); const recentTests = successfulTests.slice(-3); if (recentTests.length >= 2) { const recentAvg = recentTests.reduce((a, b) => a + b.duration, 0) / recentTests.length; const olderTests = successfulTests.slice(0, -3); if (olderTests.length > 0) { const olderAvg = olderTests.reduce((a, b) => a + b.duration, 0) / olderTests.length; const improvement = ((olderAvg - recentAvg) / olderAvg * 100).toFixed(1); if (improvement > 0) { console.log(` šŸ“‰ ę€§čƒ½ęå‡: ${improvement}%`); } else { console.log(` šŸ“ˆ ę€§čƒ½äø‹é™: ${Math.abs(improvement)}%`); } } } } if (require.main === module) { measureE2ETestPerformance(); } module.exports = { measureE2ETestPerformance };