server-listening

Simple promise to wait for server ready inside a mocha specification (written in TypeScript)

Usage no npm install needed!

<script type="module">
  import serverListening from 'https://cdn.skypack.dev/server-listening';
</script>

README

server-listening

logo

Simple promise to wait for server ready inside a mocha specification

License:MIT npm Vulnerabilities Build

server-listening is just a little helper utility to reduce the amount of boilerplate code needed to startup servers when running mocha specifications.

A) Setup

Install package:

$ npm install --save-dev server-listening

Import package:

import { serverListening } from 'server-listening';

Or if using the older CommonJS format:

const { serverListening } = require('server-listening');  //deprecated

B) Usage

The original low-level API is described below.  For the newer high-level API to start a web server (localhost) and load a web page (jsdom), see start-web-server.spec.js and load-web-page.spec.js (for similar functionality using Puppeteer instead, see the puppeteer-browser-ready project).

1. Mocha specification file

import { server } from '../server.js';
before(() => serverListening.ready(server));
after(() =>  serverListening.close(server));

Example usage:
hello-world/mocha-spec.js

2. setPort() options

The setPort(options) function is just a handy way to set the environment variable for the HTTP port.  This function is for convenience and is not required.

serverListening.setPort({ port: 9000 });
Option Meaning Default
port Port number for server (0 means choose an unused port). 0
name Environment variable name to store port number. 'port'

3. Leveraging promises

The ready(server) and close(server) functions return a promise, enabling chaining of operations.

For example, a port variable could be set after the server is ready using:

let port;
before(() => serverListening.ready(server).then(() => port = server.address().port));

4. jsdom support

The two helper functions jsdomOnLoad() and jsdomCloseWindow() can be used with the JSDOM.fromURL() function to load a web page before the mocha tests run and then close the window when the tests are finished.

// Imports
import { assertDeepStrictEqual } from 'assert-deep-strict-equal';
import { serverListening } from 'server-listening';
import { JSDOM } from 'jsdom';

// Setup
const url = 'https://pretty-print-json.js.org/';
const jsdomOptions = { resources: 'usable', runScripts: 'dangerously' };
let dom;
const loadWebPage = () => JSDOM.fromURL(url, jsdomOptions)
   .then(serverListening.jsdomOnLoad)
   .then((jsdom) => dom = jsdom);
const closeWebPage = () => serverListening.jsdomCloseWindow(dom);

////////////////////////////////////////////////////////////////////////////////////////////////////
describe('The web page', () => {
   before(loadWebPage);
   after(closeWebPage);

   it('has the correct URL -> ' + url, () => {
      const actual =   { url: dom.window.location.href };
      const expected = { url: url };
      assertDeepStrictEqual(actual, expected);
      });

   it('has exactly one header, main, and footer', () => {
      const $ = dom.window.$;
      const actual =   {
         header: $('body >header').length,
         main:   $('body >main').length,
         footer: $('body >footer').length,
         };
      const expected = { header: 1, main: 1, footer: 1 };
      assertDeepStrictEqual(actual, expected);
      });

   });

////////////////////////////////////////////////////////////////////////////////////////////////////
describe('The document content', () => {
   before(loadWebPage);
   after(closeWebPage);

   it('has a 🚀 traveling to 🪐!', () => {
      const html = dom.window.document.documentElement.outerHTML;
      const actual =   { '🚀': !!html.match(/🚀/g), '🪐': !!html.match(/🪐/g) };
      const expected = { '🚀': true,                '🪐': true };
      assertDeepStrictEqual(actual, expected);
      });

   });

Above mocha test will output:

  The web page
    ✓ has the correct URL -> https://pretty-print-json.js.org/
    ✓ has exactly one header, main, and footer

  The document content
    ✓ has a 🚀 traveling to 🪐!

Example of loading a web page into jsdom from a local node server:
https://github.com/dnajs/data-dashboard/blob/main/spec/spec.js

5. TypeScript declarations

The TypeScript Declaration File file is server-listening.d.ts in the dist folder.

The declarations provide type information about the API, such as the options for calling serverListening.setPort()::

type ServerListeningOptions = {
   port?:  number,  //0 = find unused port
   name?:  string,  //environment variable to pass port number
   };

C) Hello World Example

To try out server-listening locally, enter the following terminal commands:

$ git clone https://github.com/center-key/server-listening.git
$ cd server-listening/hello-world
$ npm install
$ npm test

screenshot

You can also run the server locally:

$ npm start

and then use a browser to view the 'Hello, World!' message at: http://localhost:3300


server-listening is open source under the MIT License.