/** * E2E测试环境验证脚本 * 在运行完整测试前验证配置 */ const fs = require('fs'); const path = require('path'); console.log('🔍 验证E2E测试环境...\n'); // 检查目录结构 const requiredDirs = [ 'e2e', 'e2e/fixtures', 'e2e/tests', 'e2e/utils', ]; console.log('📂 检查目录结构:'); let allDirsExist = true; for (const dir of requiredDirs) { const dirPath = path.join(__dirname, '..', dir); if (fs.existsSync(dirPath)) { console.log(` ✅ ${dir}`); } else { console.log(` ❌ ${dir} (缺失)`); allDirsExist = false; } } if (!allDirsExist) { console.log('\n❌ 目录结构不完整'); process.exit(1); } // 检查关键文件 const requiredFiles = [ 'playwright.config.ts', 'e2e/global-setup.ts', 'e2e/global-teardown.ts', 'e2e/fixtures/test-data.ts', 'e2e/tests/user-journey.spec.ts', 'e2e/utils/auth-helper.ts', 'e2e/utils/wait-helper.ts', ]; console.log('\n📄 检查关键文件:'); let allFilesExist = true; for (const file of requiredFiles) { const filePath = path.join(__dirname, '..', file); if (fs.existsSync(filePath)) { const stats = fs.statSync(filePath); console.log(` ✅ ${file} (${(stats.size / 1024).toFixed(1)} KB)`); } else { console.log(` ❌ ${file} (缺失)`); allFilesExist = false; } } if (!allFilesExist) { console.log('\n❌ 关键文件缺失'); process.exit(1); } // 检查package.json中的脚本 console.log('\n📦 检查npm脚本:'); const packageJsonPath = path.join(__dirname, '..', 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); const requiredScripts = [ 'test:e2e', 'test:e2e:ui', 'test:e2e:debug', 'test:e2e:report', ]; for (const script of requiredScripts) { if (packageJson.scripts && packageJson.scripts[script]) { console.log(` ✅ ${script}`); } else { console.log(` ⚠️ ${script} (可选)`); } } // 检查Playwright配置 console.log('\n⚙️ 检查Playwright配置:'); const playwrightConfigPath = path.join(__dirname, '..', 'playwright.config.ts'); if (fs.existsSync(playwrightConfigPath)) { const configContent = fs.readFileSync(playwrightConfigPath, 'utf-8'); const checks = [ { name: '测试目录', pattern: /testDir/ }, { name: '多浏览器支持', pattern: /chromium.*firefox.*webkit/s }, { name: '移动端设备', pattern: /Pixel 5.*iPhone 12/s }, { name: '截图配置', pattern: /screenshot/ }, { name: '录屏配置', pattern: /video/ }, { name: 'Web服务器配置', pattern: /webServer/ }, ]; for (const check of checks) { if (check.pattern.test(configContent)) { console.log(` ✅ ${check.name}`); } else { console.log(` ⚠️ ${check.name}`); } } } // 检查后端E2E配置 console.log('\n🔧 检查后端E2E配置:'); const backendE2EConfigPath = path.join(__dirname, '..', '..', 'src', 'main', 'resources', 'application-e2e.properties'); if (fs.existsSync(backendE2EConfigPath)) { console.log(' ✅ application-e2e.properties'); const configContent = fs.readFileSync(backendE2EConfigPath, 'utf-8'); const checks = [ { name: 'H2数据库配置', pattern: /spring\.datasource\.url.*h2/i }, { name: 'Flyway禁用', pattern: /spring\.flyway\.enabled=false/i }, ]; for (const check of checks) { if (check.pattern.test(configContent)) { console.log(` ✅ ${check.name}`); } else { console.log(` ⚠️ ${check.name}`); } } } else { console.log(' ❌ application-e2e.properties (缺失)'); } // 检查启动脚本 console.log('\n🚀 检查启动脚本:'); const scriptPath = path.join(__dirname, 'run-e2e-tests.sh'); if (fs.existsSync(scriptPath)) { const stats = fs.statSync(scriptPath); const isExecutable = (stats.mode & parseInt('111', 8)) !== 0; if (isExecutable) { console.log(' ✅ run-e2e-tests.sh (可执行)'); } else { console.log(' ⚠️ run-e2e-tests.sh (需要执行权限)'); console.log(' 运行: chmod +x scripts/run-e2e-tests.sh'); } } else { console.log(' ❌ run-e2e-tests.sh (缺失)'); } // 统计测试用例 console.log('\n🧪 统计测试用例:'); const testFilePath = path.join(__dirname, '..', 'e2e', 'tests', 'user-journey.spec.ts'); if (fs.existsSync(testFilePath)) { const testContent = fs.readFileSync(testFilePath, 'utf-8'); // 统计test.describe和test('') const describeMatches = testContent.match(/test\.describe\(/g); const testMatches = testContent.match(/test\(['`]/g); console.log(` 测试套件: ${describeMatches ? describeMatches.length : 0} 个`); console.log(` 测试用例: ${testMatches ? testMatches.length : 0} 个`); // 提取测试描述 const testDescriptions = testContent.match(/test\(['`]([^'`]+)['`]/g); if (testDescriptions) { console.log('\n 测试场景:'); testDescriptions.forEach((desc, i) => { const cleanDesc = desc.replace(/test\(['`]/, '').replace(/['`]$/, ''); console.log(` ${i + 1}. ${cleanDesc}`); }); } } console.log('\n✅ 验证完成!'); console.log(''); console.log('📖 使用指南:'); console.log(' 快速运行: cd frontend && ./scripts/run-e2e-tests.sh'); console.log(' 分步运行:'); console.log(' 1. mvn spring-boot:run -Dspring-boot.run.profiles=e2e'); console.log(' 2. cd frontend && npm run dev -- --port 5173'); console.log(' 3. cd frontend && npm run test:e2e'); console.log('');