import { FullConfig } from '@playwright/test'; import { spawn, ChildProcess } from 'child_process'; import path from 'path'; import { fileURLToPath } from 'url'; import { existsSync } from 'fs'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); let backendProcess: ChildProcess | null = null; async function globalSetup(config: FullConfig) { console.log('🚀 开始全局测试环境设置...'); process.env.NODE_ENV = 'test'; process.env.PLAYWRIGHT_HEADLESS = 'false'; const backendDir = path.resolve(__dirname, '../../novalon-manage-api/manage-app'); const jarFile = path.join(backendDir, 'target/manage-app-1.0.0.jar'); let backendCommand: string; let backendArgs: string[]; if (existsSync(jarFile)) { console.log('📦 使用JAR文件启动后端服务...'); console.log(` JAR文件: ${jarFile}`); backendCommand = 'java'; backendArgs = [ '-jar', jarFile, '--spring.profiles.active=test', '-Xms256m', '-Xmx512m' ]; } else { console.log('📦 使用Maven启动后端服务...'); console.log(' 提示: 运行 "mvn clean package -DskipTests" 构建JAR文件以获得更快的启动速度'); backendCommand = 'mvn'; backendArgs = ['spring-boot:run', '-Dspring-boot.run.profiles=test']; } console.log(` 目录: ${backendDir}`); console.log(` 命令: ${backendCommand} ${backendArgs.join(' ')}`); backendProcess = spawn(backendCommand, backendArgs, { cwd: backendDir, stdio: 'pipe', shell: true, detached: false, env: { ...process.env, SPRING_PROFILES_ACTIVE: 'test' } }); if (backendProcess.stdout) { backendProcess.stdout.on('data', (data) => { const output = data.toString(); if (output.includes('Started ManageApplication') || output.includes('Tomcat started on port')) { console.log('✅ 后端服务启动成功'); } }); } if (backendProcess.stderr) { backendProcess.stderr.on('data', (data) => { const output = data.toString(); if (output.includes('ERROR') || output.includes('Exception')) { console.error('❌ 后端服务启动错误:', output); } }); } backendProcess.on('error', (error) => { console.error('❌ 后端服务启动失败:', error); }); backendProcess.on('exit', (code, signal) => { if (code !== 0 && code !== null) { console.error(`❌ 后端服务异常退出,退出码: ${code}, 信号: ${signal}`); } }); console.log('⏳ 等待后端服务就绪...'); await waitForBackendReady(); console.log('✅ 全局测试环境设置完成'); } async function waitForBackendReady(): Promise { const maxRetries = 60; const retryInterval = 1000; for (let i = 0; i < maxRetries; i++) { try { const response = await fetch('http://localhost:8084/actuator/health'); if (response.ok) { const data = await response.json(); if (data.status === 'UP') { console.log(`✅ 后端服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`); return; } } } catch (error) { // 服务还未就绪,继续等待 } if (i < maxRetries - 1) { await new Promise(resolve => setTimeout(resolve, retryInterval)); } } throw new Error('❌ 后端服务启动超时'); } export default globalSetup;