fix(e2e): 添加前端服务启动逻辑
问题: - 测试访问 http://localhost:3002 但前端服务未启动 - 导致所有登录测试失败 修复: - 在 global-setup 中添加前端服务启动(pnpm run dev) - 添加 waitForFrontendReady 函数等待前端服务就绪 - 在 global-teardown 中添加前端服务停止逻辑 - 前端服务健康检查:http://localhost:3002
This commit is contained in:
@@ -8,6 +8,7 @@ const __filename = fileURLToPath(import.meta.url);
|
|||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
let backendProcess: ChildProcess | null = null;
|
let backendProcess: ChildProcess | null = null;
|
||||||
|
let frontendProcess: ChildProcess | null = null;
|
||||||
let healthCheckInterval: NodeJS.Timeout | null = null;
|
let healthCheckInterval: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
async function checkBackendHealth(): Promise<boolean> {
|
async function checkBackendHealth(): Promise<boolean> {
|
||||||
@@ -117,6 +118,49 @@ async function globalSetup(config: FullConfig) {
|
|||||||
console.log('⏳ 等待后端服务就绪...');
|
console.log('⏳ 等待后端服务就绪...');
|
||||||
await waitForBackendReady();
|
await waitForBackendReady();
|
||||||
|
|
||||||
|
const frontendDir = path.resolve(__dirname, '..');
|
||||||
|
console.log('🌐 启动前端服务...');
|
||||||
|
console.log(` 目录: ${frontendDir}`);
|
||||||
|
|
||||||
|
frontendProcess = spawn('pnpm', ['run', 'dev'], {
|
||||||
|
cwd: frontendDir,
|
||||||
|
stdio: 'pipe',
|
||||||
|
shell: true,
|
||||||
|
detached: false,
|
||||||
|
env: { ...process.env, NODE_ENV: 'test' }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (frontendProcess.stdout) {
|
||||||
|
frontendProcess.stdout.on('data', (data) => {
|
||||||
|
const output = data.toString();
|
||||||
|
if (output.includes('Local:') || output.includes('localhost:3002')) {
|
||||||
|
console.log('✅ 前端服务启动成功');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frontendProcess.stderr) {
|
||||||
|
frontendProcess.stderr.on('data', (data) => {
|
||||||
|
const output = data.toString();
|
||||||
|
if (output.includes('ERROR') || output.includes('error')) {
|
||||||
|
console.error('❌ 前端服务启动错误:', output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
frontendProcess.on('error', (error) => {
|
||||||
|
console.error('❌ 前端服务启动失败:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
frontendProcess.on('exit', (code, signal) => {
|
||||||
|
if (code !== 0 && code !== null) {
|
||||||
|
console.error(`❌ 前端服务异常退出,退出码: ${code}, 信号: ${signal}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('⏳ 等待前端服务就绪...');
|
||||||
|
await waitForFrontendReady();
|
||||||
|
|
||||||
console.log('🧹 清理测试数据...');
|
console.log('🧹 清理测试数据...');
|
||||||
await cleanupTestData();
|
await cleanupTestData();
|
||||||
|
|
||||||
@@ -151,6 +195,31 @@ async function waitForBackendReady(): Promise<void> {
|
|||||||
throw new Error('❌ 后端服务启动超时');
|
throw new Error('❌ 后端服务启动超时');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function waitForFrontendReady(): Promise<void> {
|
||||||
|
const maxRetries = 60;
|
||||||
|
const retryInterval = 1000;
|
||||||
|
|
||||||
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('http://localhost:3002', {
|
||||||
|
signal: AbortSignal.timeout(5000) as any
|
||||||
|
});
|
||||||
|
if (response.ok) {
|
||||||
|
console.log(`✅ 前端服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 服务还未就绪,继续等待
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < maxRetries - 1) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, retryInterval));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('❌ 前端服务启动超时');
|
||||||
|
}
|
||||||
|
|
||||||
async function cleanupTestData(): Promise<void> {
|
async function cleanupTestData(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// 登录获取token
|
// 登录获取token
|
||||||
@@ -265,6 +334,30 @@ async function globalTeardown() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frontendProcess) {
|
||||||
|
console.log('🛑 停止前端服务...');
|
||||||
|
frontendProcess.kill('SIGTERM');
|
||||||
|
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
if (frontendProcess) {
|
||||||
|
frontendProcess.on('exit', () => {
|
||||||
|
console.log('✅ 前端服务已停止');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (frontendProcess) {
|
||||||
|
frontendProcess.kill('SIGKILL');
|
||||||
|
console.log('⚠️ 强制停止前端服务');
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
console.log('✅ 全局测试环境清理完成');
|
console.log('✅ 全局测试环境清理完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user