Skip to content

Instantly share code, notes, and snippets.

@ndemengel
Created July 29, 2024 15:26
Show Gist options
  • Save ndemengel/56b71147d47814c483acac59bd35b00a to your computer and use it in GitHub Desktop.
Save ndemengel/56b71147d47814c483acac59bd35b00a to your computer and use it in GitHub Desktop.
Nuxt UI Tests with Playwright @malt: the reverse proxy
/* eslint-disable no-console */
// Note: a first version of if was using Typescript and was launched using ts-node, but it took 1-2 additional seconds
// to start, which is noticeable when we want tests to start as fast as possible. So it has been reverted to JS.
import {execSync} from 'child_process';
import * as http from 'http';
const COMMON_BACKEND_ROUTES = ['/api', /* ... */];
function startProxy(proxyPort, appPortForTests, backendPortForTests, apiPrefixes) {
const requestPrefixes = apiPrefixes.split(',');
function cleanup() {
console.log(`Checking for old uncleaned instances of proxy still running on port ${proxyPort} ...`);
const appPID = execSync(`lsof -i:${proxyPort} -t || true`).toString().trim();
if (!appPID) {
console.log('No old process found, skipping...');
return;
}
try {
console.log(`Found an old proxy process running: ${appPID}`);
execSync(`kill -- -$(ps -o pgid= ${appPID} | grep -o '[0-9]*')`);
console.log('Proxy process group successfully killed X.X');
} catch (e) {
console.log('No old process found, or failed to kill the remaining process, continue anyway...');
}
}
cleanup();
console.log('Starting proxy...');
function handleClientRequest(clientReq, clientRes) {
const url = new URL(clientReq.url, `http://${clientReq.headers.host}`);
if (url.pathname === '/proxy-health') {
clientRes.writeHead(200);
clientRes.end('Proxy is working well :-)');
return;
}
const destinationPort =
requestPrefixes.some((prefix) => url.pathname.startsWith(prefix)) ||
COMMON_BACKEND_ROUTES.some((prefix) => url.pathname.startsWith(prefix))
? backendPortForTests
: appPortForTests;
if (process.env.DEBUG) {
console.debug(`forwarding ${url.pathname} to ${destinationPort}`);
}
const options = {
hostname: url.hostname,
port: destinationPort,
path: clientReq.url,
method: clientReq.method,
headers: clientReq.headers,
};
const proxyRequest = http.request(options, (proxyRes) => {
clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(clientRes, {
end: true,
});
});
clientReq.pipe(proxyRequest, {
end: true,
});
}
const server = http.createServer();
server.on('request', handleClientRequest);
server.on('error', (error) => {
console.error(error);
});
server.listen(proxyPort);
console.log(`Proxy started and listening to port ${proxyPort}...`);
function stopProxy() {
console.log('Killing proxy...');
server.close();
console.log('Proxy should have been killed.');
}
return Promise.resolve({stop: stopProxy});
}
startProxy(parseInt(process.argv[2]), parseInt(process.argv[3]), parseInt(process.argv[4]), process.argv[5]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment