111 lines
2.8 KiB
JavaScript
111 lines
2.8 KiB
JavaScript
import { spawn } from 'node:child_process';
|
|
import { dirname, resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const projectRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
const serverSpecs = [
|
|
{ name: 'viewer-2d', args: ['run', 'dev:2d'] },
|
|
{ name: 'viewer-3d', args: ['run', 'dev:3d'] },
|
|
{
|
|
name: 'viewer-3d-subpath',
|
|
args: ['--workspace', '@hmwebviewer/viewer-3d', 'run', 'serve:subpath:e2e'],
|
|
},
|
|
];
|
|
const servers = [];
|
|
let stopping = false;
|
|
|
|
function stopServers() {
|
|
if (stopping) return;
|
|
stopping = true;
|
|
for (const server of servers) {
|
|
if (!server.pid) continue;
|
|
try {
|
|
// npm과 그 아래 Vite process를 같은 process group 단위로 종료합니다.
|
|
process.kill(-server.pid, 'SIGTERM');
|
|
} catch {
|
|
// 이미 종료된 server는 별도 처리하지 않습니다.
|
|
}
|
|
}
|
|
}
|
|
|
|
function startServer({ name, args }) {
|
|
return new Promise((resolveReady, rejectReady) => {
|
|
const child = spawn('npm', args, {
|
|
cwd: projectRoot,
|
|
detached: true,
|
|
env: {
|
|
...process.env,
|
|
NO_PROXY: '127.0.0.1,localhost',
|
|
no_proxy: '127.0.0.1,localhost',
|
|
},
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
servers.push(child);
|
|
|
|
let ready = false;
|
|
const timeout = setTimeout(() => {
|
|
rejectReady(new Error(`${name} server가 90초 안에 준비되지 않았습니다.`));
|
|
}, 90_000);
|
|
|
|
const inspect = (chunk) => {
|
|
const output = chunk.toString();
|
|
process.stderr.write(`[${name}] ${output}`);
|
|
if (!ready && output.includes('Local:')) {
|
|
ready = true;
|
|
clearTimeout(timeout);
|
|
resolveReady();
|
|
}
|
|
};
|
|
child.stdout.on('data', inspect);
|
|
child.stderr.on('data', inspect);
|
|
child.once('exit', (code, signal) => {
|
|
clearTimeout(timeout);
|
|
if (!ready) {
|
|
rejectReady(
|
|
new Error(`${name} server가 준비 전에 종료됐습니다. code=${code} signal=${signal}`),
|
|
);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
process.once('SIGINT', () => {
|
|
stopServers();
|
|
process.exit(130);
|
|
});
|
|
process.once('SIGTERM', () => {
|
|
stopServers();
|
|
process.exit(143);
|
|
});
|
|
|
|
try {
|
|
await Promise.all(serverSpecs.map(startServer));
|
|
|
|
const playwright = spawn(
|
|
resolve(projectRoot, 'node_modules/.bin/playwright'),
|
|
['test', ...process.argv.slice(2)],
|
|
{
|
|
cwd: projectRoot,
|
|
env: {
|
|
...process.env,
|
|
E2E_SERVERS_READY: '1',
|
|
NO_PROXY: '127.0.0.1,localhost',
|
|
no_proxy: '127.0.0.1,localhost',
|
|
},
|
|
stdio: 'inherit',
|
|
},
|
|
);
|
|
const exitCode = await new Promise((resolveExit) => {
|
|
playwright.once('exit', (code, signal) => {
|
|
if (signal) resolveExit(1);
|
|
else resolveExit(code ?? 1);
|
|
});
|
|
});
|
|
process.exitCode = exitCode;
|
|
} catch (error) {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
} finally {
|
|
stopServers();
|
|
}
|