#!/usr/bin/env node const { spawn } = require('child_process'); const fs = require('fs'); const { glob } = require('glob'); const testTypes = [ { name: '冒烟测试', script: 'test:smoke', pattern: 'src/tests/smoke/**/*.spec.ts' }, { name: '回归测试', script: 'test:regression', pattern: 'src/tests/regression/**/*.spec.ts' }, { name: '性能测试', script: 'test:performance', pattern: 'src/tests/performance/**/*.spec.ts' }, { name: '响应式测试', script: 'test:responsive', pattern: 'src/tests/responsive/**/*.spec.ts' } ]; const TIMEOUT_SECONDS = 600; async function runTests() { console.log('🧪 开始运行E2E测试...\n'); const results = { total: 0, passed: 0, failed: 0, byType: {} }; for (const testType of testTypes) { console.log(`\n${'='.repeat(60)}`); console.log(`📋 ${testType.name}`); console.log(`${'='.repeat(60)}`); await new Promise((resolve) => { const startTime = Date.now(); let lastUpdateTime = startTime; let currentTest = 0; let passedCount = 0; let failedCount = 0; let isComplete = false; let lastTestName = ''; const testProcess = spawn('npm', ['run', testType.script], { cwd: __dirname, shell: true, stdio: ['pipe', 'pipe', 'pipe'] }); testProcess.stdout.on('data', (data) => { const output = data.toString(); if (output.includes('›')) { currentTest++; const progress = Math.min(100, Math.round((currentTest / 100) * 100)); const elapsed = Math.round((Date.now() - startTime) / 1000); const barLength = Math.floor(progress / 2); const bar = '█'.repeat(barLength) + '░'.repeat(50 - barLength); const testNameMatch = output.match(/›\s+(.+)/); if (testNameMatch) { lastTestName = testNameMatch[1].trim(); } process.stdout.write(`\r⏳ 进度: [${bar}] ${progress}% - ${elapsed}s - ${lastTestName}`); lastUpdateTime = Date.now(); } if (output.includes('passed')) { const match = output.match(/(\d+)\s+passed/); if (match) { passedCount = parseInt(match[1]); } } if (output.includes('failed')) { const match = output.match(/(\d+)\s+failed/); if (match) { failedCount = parseInt(match[1]); } } }); testProcess.stderr.on('data', (data) => { const output = data.toString(); if (output.includes('Error') || output.includes('error')) { process.stdout.write('\n❌ 错误: ' + output); } }); testProcess.on('close', (code) => { isComplete = true; const elapsed = Math.round((Date.now() - startTime) / 1000); process.stdout.write(`\r✅ 完成: [${'█'.repeat(50)}] 100% - ${elapsed}s\n`); results.total += passedCount + failedCount; results.passed += passedCount; results.failed += failedCount; results.byType[testType.name] = { total: passedCount + failedCount, passed: passedCount, failed: failedCount, elapsed: elapsed }; resolve(); }); const progressInterval = setInterval(() => { if (!isComplete) { const elapsed = Math.round((Date.now() - startTime) / 1000); const timeSinceLastUpdate = Date.now() - lastUpdateTime; if (timeSinceLastUpdate > 10000 && timeSinceLastUpdate < 30000) { process.stdout.write(`\r⏳ 等待测试... (${elapsed}s) - ${lastTestName}`); } else if (timeSinceLastUpdate >= 30000) { process.stdout.write(`\r⚠️ 测试可能卡住 (${elapsed}s) - ${lastTestName}`); } if (elapsed > TIMEOUT_SECONDS) { console.log(`\n❌ 测试超时 (${TIMEOUT_SECONDS}s),正在停止...`); testProcess.kill(); clearInterval(progressInterval); isComplete = true; resolve(); } } }, 5000); testProcess.on('close', () => { clearInterval(progressInterval); }); }); } console.log(`\n${'='.repeat(60)}`); console.log('📊 测试结果汇总'); console.log(`${'='.repeat(60)}`); console.log(`总测试数: ${results.total}`); console.log(`通过: ${results.passed} (${((results.passed / results.total) * 100).toFixed(1)}%)`); console.log(`失败: ${results.failed} (${((results.failed / results.total) * 100).toFixed(1)}%)`); console.log('\n分类结果:'); for (const [name, result] of Object.entries(results.byType)) { const passRate = ((result.passed / result.total) * 100).toFixed(1); const status = passRate >= 80 ? '✅' : passRate >= 50 ? '⚠️' : '❌'; console.log(` ${status} ${name}: ${result.passed}/${result.total} (${passRate}%) - ${result.elapsed}s`); } } runTests().catch(console.error);