Server Orchestration for E2E Tests
The `with-server` package is a command-line utility and programmatic API designed to orchestrate local server startup, command execution (typically end-to-end tests), and server shutdown. It automatically handles port allocation via the `$PORT` environment variable, waits for the server to become ready, and exposes `$SERVER_URL` to the executed command. It offers options to specify the server's start script and control output redirection. The current stable version is 2.1.0, with releases appearing infrequently, driven by feature additions or critical maintenance, such as the major Node.js version bump in v2.0.0. It's a focused tool for e2e testing workflows, abstracting away the complexities of server lifecycle management during test runs, differentiating itself by its simplicity and direct integration with npm scripts.
Common errors
-
Error: connect ECONNREFUSED 127.0.0.1:XXXX
cause The server process failed to start or did not listen on the expected port before the timeout, preventing `with-server` from establishing a connection.fixVerify your server's start script, ensure it's listening on `process.env.PORT`, and check for any startup errors in the server's output (redirect to stdout for debugging). Increase timeout if server takes long to start. -
command not found: <your-test-command>
cause The test command specified (e.g., 'cypress') is not installed globally, not available in the local `node_modules/.bin` directory, or not properly configured in your `package.json` scripts.fixEnsure the test command is installed as a `devDependency` (e.g., `npm install cypress --save-dev`) and either run `with-server` via `npm scripts` or directly reference the local binary (e.g., `node_modules/.bin/cypress`). -
Error: Cannot find module 'with-server'
cause The `with-server` package is not installed in your project's `node_modules` directory, or there's an issue with how it's being imported (e.g., trying to use `import` syntax in a CommonJS-only context without a bundler).fixRun `npm install with-server --save-dev` to install the package. If using ESM, ensure your setup correctly handles CJS module imports or consider bundling your code.
Warnings
- breaking Version 2.0.0 dropped support for Node.js 12 and 14. The package now requires Node.js version 16 or newer.
- gotcha The server process started by `with-server` *must* listen on the TCP port specified by the `$PORT` environment variable. If `$PORT` is not explicitly set, `with-server` will pick a free random port and expose it.
- gotcha By default, the standard output (stdout) of the server process is redirected to stderr to prevent it from mixing with test output. This can make debugging server logs challenging if you're not aware of it.
Install
-
npm install with-server -
yarn add with-server -
pnpm add with-server
Imports
- withServer
import withServer from 'with-server';
const withServer = require("with-server");
Quickstart
const withServer = require("with-server");
async function runTests() {
console.log('Starting server and running tests...');
try {
const exitCode = await withServer("cypress run", {
run: "start", // Assuming 'npm start' is the command to launch your server
redirect: "stderr", // Redirect server logs to stderr to keep test output clean
// Additional options like 'port' can be specified if you need a fixed port
});
console.log(`Test command exited with code: ${exitCode}`);
process.exit(exitCode);
} catch (error) {
console.error('An error occurred:', error.message);
process.exit(1);
}
}
// Example package.json script for demonstration:
// "scripts": {
// "start": "node server.js",
// "test:e2e": "node run-tests.js"
// }
// Where server.js might look like:
// const http = require('http');
// const port = process.env.PORT || 3000;
// http.createServer((req, res) => res.end('Hello from server')).listen(port, () => console.log(`Server listening on port ${port}`));
runTests();