Standardize live search Playwright setup lane
This commit is contained in:
108
src/Web/StellaOps.Web/scripts/run-live-search-e2e.mjs
Normal file
108
src/Web/StellaOps.Web/scripts/run-live-search-e2e.mjs
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import net from 'node:net';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const webRoot = path.resolve(__dirname, '..');
|
||||
const repoRoot = path.resolve(webRoot, '..', '..', '..');
|
||||
const composeFile = path.join(
|
||||
repoRoot,
|
||||
'devops',
|
||||
'compose',
|
||||
'docker-compose.advisoryai-knowledge-test.yml',
|
||||
);
|
||||
|
||||
async function main() {
|
||||
const forwardedArgs = process.argv.slice(2);
|
||||
const env = {
|
||||
...process.env,
|
||||
LIVE_ADVISORYAI_SEARCH_BASE_URL:
|
||||
process.env.LIVE_ADVISORYAI_SEARCH_BASE_URL?.trim() || 'http://127.0.0.1:10451',
|
||||
PLAYWRIGHT_LIVE_SEARCH_SKIP_REBUILD: '1',
|
||||
};
|
||||
|
||||
if (process.env.PLAYWRIGHT_LIVE_SEARCH_SKIP_DOCKER !== '1') {
|
||||
runCommand('docker', ['compose', '-f', composeFile, 'up', '-d'], repoRoot);
|
||||
await waitForTcpPort('127.0.0.1', 55432, 60_000);
|
||||
}
|
||||
|
||||
const playwrightArgs = ['playwright', 'test', '--config', 'playwright.live-search.config.ts', ...forwardedArgs];
|
||||
const result = process.platform === 'win32'
|
||||
? spawnSync('cmd.exe', ['/d', '/s', '/c', 'npx', ...playwrightArgs], {
|
||||
cwd: webRoot,
|
||||
env,
|
||||
stdio: 'inherit',
|
||||
})
|
||||
: spawnSync('npx', playwrightArgs, {
|
||||
cwd: webRoot,
|
||||
env,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
|
||||
process.exit(result.status ?? 1);
|
||||
}
|
||||
|
||||
function runCommand(command, args, cwd) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd,
|
||||
stdio: 'inherit',
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
|
||||
if ((result.status ?? 1) !== 0) {
|
||||
throw new Error(`${command} ${args.join(' ')} exited with status ${result.status ?? 1}.`);
|
||||
}
|
||||
}
|
||||
|
||||
function waitForTcpPort(host, port, timeoutMs) {
|
||||
const startedAt = Date.now();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const attempt = () => {
|
||||
const socket = new net.Socket();
|
||||
|
||||
socket.setTimeout(2_000);
|
||||
socket.once('connect', () => {
|
||||
socket.destroy();
|
||||
resolve();
|
||||
});
|
||||
socket.once('timeout', () => {
|
||||
socket.destroy();
|
||||
retry(new Error(`Timed out while connecting to ${host}:${port}.`));
|
||||
});
|
||||
socket.once('error', (error) => {
|
||||
socket.destroy();
|
||||
retry(error);
|
||||
});
|
||||
socket.connect(port, host);
|
||||
};
|
||||
|
||||
const retry = (lastError) => {
|
||||
if (Date.now() - startedAt >= timeoutMs) {
|
||||
reject(new Error(`Port ${host}:${port} did not become ready within ${timeoutMs}ms: ${lastError.message}`));
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(attempt, 1_000);
|
||||
};
|
||||
|
||||
attempt();
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(`[live-search-e2e] ${error instanceof Error ? error.message : String(error)}`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user