{"id":22897270,"url":"https://github.com/center-key/server-listening","last_synced_at":"2025-05-07T22:06:25.548Z","repository":{"id":65775001,"uuid":"182213666","full_name":"center-key/server-listening","owner":"center-key","description":"🧪 Simple promise to wait for server ready inside a mocha specification","archived":false,"fork":false,"pushed_at":"2025-04-21T22:01:27.000Z","size":167,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T22:06:15.866Z","etag":null,"topics":["javascript","mocha","promise","ready","server","specification","wait"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/center-key.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-19T06:27:15.000Z","updated_at":"2025-04-21T22:01:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"f558ef67-b70f-4dfc-a47f-36f0ec9a6292","html_url":"https://github.com/center-key/server-listening","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fserver-listening","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fserver-listening/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fserver-listening/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fserver-listening/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/center-key","download_url":"https://codeload.github.com/center-key/server-listening/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252961837,"owners_count":21832196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","mocha","promise","ready","server","specification","wait"],"created_at":"2024-12-14T00:16:23.883Z","updated_at":"2025-05-07T22:06:25.503Z","avatar_url":"https://github.com/center-key.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# server-listening\n\u003cimg src=https://centerkey.com/graphics/center-key-logo.svg align=right width=180 alt=logo\u003e\n\n_Simple promise to wait for server ready or DOM ready inside a mocha specification_\n\n[![License:MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/center-key/server-listening/blob/main/LICENSE.txt)\n[![npm](https://img.shields.io/npm/v/server-listening.svg)](https://www.npmjs.com/package/server-listening)\n[![Build](https://github.com/center-key/server-listening/actions/workflows/run-spec-on-push.yaml/badge.svg)](https://github.com/center-key/server-listening/actions/workflows/run-spec-on-push.yaml)\n\n**server-listening** is a lightweight helper utility to reduce the amount of boilerplate code\nneeded to startup servers when running mocha specifications.\n\n## A) Setup\nInstall package:\n```shell\n$ npm install --save-dev server-listening\n```\nImport package:\n```javascript\nimport { serverListening } from 'server-listening';\n```\n\n## B) Usage\nThree primary tools:\n* `serverListening.ready(server)` Waits for your node server application to start up\n* `serverListening.startWebServer(options)` Starts and waits for static web server (express), see: [start-web-server.spec.js](spec/start-web-server.spec.js)\n* `serverListening.loadWebPage(url, options)` Uses JSDOM to load and wait for a web page, see: [load-web-page.spec.js](spec/load-web-page.spec.js)\n\n(for similar functionality using Puppeteer instead, see the\n[puppeteer-browser-ready](https://github.com/center-key/puppeteer-browser-ready) project).\n\n### 1. Mocha specification file\n```javascript\nimport { server } from '../server.js';\nbefore(() =\u003e serverListening.ready(server));\nafter(() =\u003e  serverListening.close(server));\n```\nExample usage:\u003cbr\u003e\n[hello-world/mocha.spec.js](hello-world/mocha.spec.js)\n\n**NOTE:**\u003cbr\u003e\nMocha's default timeout is 2,000 milliseconds which often is not enough time for a node server to shutdown.\u0026nbsp;\nUse the `--timeout` flag to help avoid this problem:\n```json\n\"scripts\": {\n   \"test\": \"mocha *.spec.js --timeout 7000\"\n}\n```\n\n### 2. `setPort()` options\nThe `setPort(options)` function is just a handy way to set the environment variable for the\nHTTP port.\u0026nbsp; This function is for convenience and is not required.\n```javascript\nserverListening.setPort({ port: 9000 });\n```\n| Option    | Meaning                                                   | Default  |\n| --------- | --------------------------------------------------------- | -------- |\n| **port**  | Port number for server (`0` means choose an unused port). | `0`      |\n| **name**  | Environment variable name to store port number.           | `'port'` |\n\n### 3. Leveraging promises\nThe `ready(server)` and `close(server)` functions return a\n[promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises), enabling\nchaining of operations.\n\nFor example, a `port` variable could be set **after** the server is ready using:\n```javascript\nlet port;\nbefore(() =\u003e serverListening.ready(server).then(() =\u003e port = server.address().port));\n```\n\n### 4. Example for serverListening.loadWebPage(url)\n```javascript\n// Mocha Specification Suite\n\n// Imports\nimport { assertDeepStrictEqual } from 'assert-deep-strict-equal';\nimport { serverListening } from 'server-listening';\n\n// Setup\nconst url = 'https://pretty-print-json.js.org/';\nlet web;  //fields: url, dom, window, document, title, html, verbose\nconst loadWebPage =  () =\u003e serverListening.loadWebPage(url).then(webInst =\u003e web = webInst);\nconst closeWebPage = () =\u003e serverListening.closeWebPage(web);\n\n////////////////////////////////////////////////////////////////////////////////\ndescribe('The web page', () =\u003e {\n   const getTags = (elems) =\u003e [...elems].map(elem =\u003e elem.nodeName.toLowerCase());\n   before(loadWebPage);\n   after(closeWebPage);\n\n   it('has the correct URL', () =\u003e {\n      const actual =   { url: web.window.location.href };\n      const expected = { url: url };\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   it('body has exactly one header, main, and footer', () =\u003e {\n      const actual =   getTags(web.document.querySelectorAll('body \u003e*'));\n      const expected = ['header', 'main', 'footer'];\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   });\n\n////////////////////////////////////////////////////////////////////////////////\ndescribe('The document content', () =\u003e {\n   before(loadWebPage);\n   after(closeWebPage);\n\n   it('has a 🚀 traveling to 🪐!', () =\u003e {\n      const html =     web.document.body.outerHTML;\n      const actual =   { '🚀': !!html.match(/🚀/g), '🪐': !!html.match(/🪐/g) };\n      const expected = { '🚀': true,                '🪐': true };\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   });\n```\nAbove mocha test will output:\n```\n  The web page\n    ✓ has the correct URL -\u003e https://pretty-print-json.js.org/\n    ✓ body has exactly one header, main, and footer\n\n  The document content\n    ✓ has a 🚀 traveling to 🪐!\n```\nExample of loading a web page into jsdom from a local node server:\u003cbr\u003e\nhttps://github.com/dna-engine/data-dashboard/blob/main/spec/spec.js\n\n### 5. TypeScript declarations\nSee the TypeScript declarations at the top of the [server-listening.ts](server-listening.ts) file.\n\nThe declarations provide type information about the API, such as the options for calling\n`serverListening.setPort()`:\n```typescript\ntype ServerListeningOptions = {\n   port?:  number,  //0 = find unused port\n   name?:  string,  //environment variable to pass port number\n   };\n```\n\n## C) Hello World Example\nTo try out **server-listening** locally, enter the following terminal commands:\n```shell\n$ git clone https://github.com/center-key/server-listening.git\n$ cd server-listening/hello-world\n$ npm install\n$ npm test\n```\n\u003cimg src=https://raw.githubusercontent.com/center-key/server-listening/main/hello-world/screenshot.png\nwidth=800 alt=screenshot\u003e\n\nYou can also run the server locally:\n```shell\n$ npm start\n```\nand then use a browser to view the `'Hello, World!'` message at: http://localhost:3300\n\n---\n**server-listening** is open source under the [MIT License](LICENSE.txt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcenter-key%2Fserver-listening","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcenter-key%2Fserver-listening","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcenter-key%2Fserver-listening/lists"}