{"id":14115,"library":"test-listen","title":"test-listen: Ephemeral HTTP Server URLs","description":"test-listen is a JavaScript utility for generating URLs with ephemeral ports, specifically designed for testing HTTP servers. It accepts an instance of Node.js's native `http.Server` and returns a promise that resolves to a unique URL string, typically in the format `http://localhost:{port}`. This mechanism is crucial for ensuring isolated and repeatable test environments, as each test run can utilize a distinct, automatically assigned port, thereby preventing conflicts and ensuring test integrity. The current stable version is 1.1.0, and the package generally maintains a stable release cadence with updates focused on minor improvements and maintenance. Its primary strength lies in its simplicity and direct integration with standard Node.js HTTP servers, providing an `async`/`await`-ready solution that streamlines the setup for robust server test suites. It differentiates itself by offering a straightforward, minimal API for a very specific and common testing requirement without introducing complex abstractions.","status":"active","version":"1.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/zeit/test-listen","tags":["javascript"],"install":[{"cmd":"npm install test-listen","lang":"bash","label":"npm"},{"cmd":"yarn add test-listen","lang":"bash","label":"yarn"},{"cmd":"pnpm add test-listen","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary export is a default export, typically used for ESM.","wrong":"import { listen } from 'test-listen'","symbol":"listen","correct":"import listen from 'test-listen'"},{"note":"CommonJS usage for the default export. Destructuring will result in `undefined`.","wrong":"const { listen } = require('test-listen')","symbol":"listen","correct":"const listen = require('test-listen')"}],"quickstart":{"code":"const http = require('http');\nconst listen = require('test-listen');\nconst assert = require('assert');\n\nasync function setupTestServer() {\n  const server = http.createServer((req, res) => {\n    res.writeHead(200, { 'Content-Type': 'text/plain' });\n    res.end('Hello from ephemeral server!');\n  });\n\n  let url;\n  try {\n    url = await listen(server);\n    console.log(`Test server is listening at: ${url}`);\n    assert.ok(url.startsWith('http://localhost:'), 'URL should start with http://localhost:');\n    assert.ok(/\\d+$/.test(url.split(':')[2]), 'URL should contain a port number');\n\n    // Simulate a request to the server (e.g., in a test runner)\n    // In a real test, you'd make an actual HTTP request here and assert its response\n\n  } catch (error) {\n    console.error('Failed to start test server:', error);\n    process.exit(1);\n  } finally {\n    // Ensure the server is closed after tests complete\n    server.close(() => console.log('Test server closed.'));\n  }\n}\n\n// Run the quickstart example\nsetupTestServer().catch(console.error);\n","lang":"javascript","description":"Demonstrates how to start an HTTP server, get an ephemeral URL using `test-listen`, and verify the URL format, ensuring the server is properly closed."},"warnings":[{"fix":"Always use `await listen(server)` within an `async` function, or chain with `.then()`.","message":"`test-listen` returns a Promise. Forgetting to `await` its call will result in a Promise object being returned instead of the URL string, leading to unexpected behavior or an UnhandledPromiseRejectionWarning.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Assert against the URL's structure (e.g., `startsWith('http://localhost:')`) rather than a specific port number.","message":"The port number returned by `test-listen` is ephemeral and non-deterministic. Do not hardcode port numbers in your tests; instead, parse the returned URL to extract the port if needed, or rely on URL functions.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'1.1.0':87 'abstract':155 'accept':28 'api':143 'assign':73 'async':122 'automat':72 'await':123 'cadenc':96 'common':149 'complex':154 'conflict':77 'crucial':56 'current':83 'design':22 'differenti':136 'direct':113 'distinct':71 'ensur':58,79 'environ':63 'ephemer':4,19 'focus':99 'format':50 'general':91 'generat':16 'http':5,25,118 'http.server':35 'improv':102 'instanc':30 'integr':81,114 'introduc':153 'isol':59 'javascript':13,156 'lie':108 'listen':3,10 'localhost':51 'maintain':92 'mainten':104 'mechan':54 'minim':142 'minor':101 'nativ':34 'node.js':32,117 'offer':139 'packag':90 'port':20,52,74 'prevent':76 'primari':106 'promis':39 'provid':120 'readi':124 'releas':95 'repeat':61 'requir':151 'resolv':41 'return':37 'robust':131 'run':67 'server':6,26,119,132 'setup':129 'simplic':111 'solut':125 'specif':21,147 'stabl':84,94 'standard':116 'straightforward':141 'streamlin':127 'strength':107 'string':46 'suit':134 'test':2,9,24,62,66,80,133,150 'test-listen':1,8 'therebi':75 'typic':47 'uniqu':44 'updat':98 'url':7,17,45 'util':14,69 'version':85 'without':152","created_at":"2026-04-20T01:58:00.778372+00:00","updated_at":"2026-04-20T01:58:00.778372+00:00","problems":[{"fix":"For CommonJS: `const listen = require('test-listen')`. For ESM: `import listen from 'test-listen'`.","cause":"Attempting to destructure the `test-listen` module in CommonJS (`const { listen } = require('test-listen')`) or importing named in ESM (`import { listen } from 'test-listen'`) when it exports a default function.","error":"TypeError: listen is not a function"},{"fix":"Ensure `await listen(server)` is used, or attach `.then()` and `.catch()` handlers to the promise returned by `listen(server)`.","cause":"Calling `listen(server)` without `await` in an `async` context, or without `.then().catch()` handlers in a Promise-based context, leading to an unhandled promise.","error":"UnhandledPromiseRejectionWarning: Unhandled promise rejection."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/zeit/test-listen","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/test-listen","openapi_spec":null,"status_page":null,"smithery":null,"categories":["testing"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}