{"id":15474787,"url":"https://github.com/center-key/puppeteer-browser-ready","last_synced_at":"2025-04-22T14:08:59.379Z","repository":{"id":57332050,"uuid":"323278041","full_name":"center-key/puppeteer-browser-ready","owner":"center-key","description":"🐕‍🦺 Simple utility to go to a URL and wait for the HTTP response","archived":false,"fork":false,"pushed_at":"2025-04-09T09:16:17.000Z","size":182,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-22T14:08:48.892Z","etag":null,"topics":["browser","http","javascript","mocha","puppeteer","ready","response","url"],"latest_commit_sha":null,"homepage":"https://github.com/center-key/puppeteer-browser-ready","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":"2020-12-21T08:41:35.000Z","updated_at":"2025-04-09T09:16:21.000Z","dependencies_parsed_at":"2023-11-10T12:40:43.066Z","dependency_job_id":"a666041b-e957-4dac-af8e-7dd919edf22f","html_url":"https://github.com/center-key/puppeteer-browser-ready","commit_stats":{"total_commits":171,"total_committers":2,"mean_commits":85.5,"dds":0.005847953216374324,"last_synced_commit":"2649c1c49cc299e6aa0df732712d12617ffde6fa"},"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fpuppeteer-browser-ready","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fpuppeteer-browser-ready/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fpuppeteer-browser-ready/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/center-key%2Fpuppeteer-browser-ready/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/center-key","download_url":"https://codeload.github.com/center-key/puppeteer-browser-ready/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250255697,"owners_count":21400410,"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":["browser","http","javascript","mocha","puppeteer","ready","response","url"],"created_at":"2024-10-02T03:04:22.226Z","updated_at":"2025-04-22T14:08:59.372Z","avatar_url":"https://github.com/center-key.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# puppeteer-browser-ready\n\u003cimg src=https://centerkey.com/graphics/center-key-logo.svg align=right width=180 alt=logo\u003e\n\n_Simple utility to go to a URL and wait for the HTTP response_\n\n[![License:MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/center-key/puppeteer-browser-ready/blob/main/LICENSE.txt)\n[![npm](https://img.shields.io/npm/v/puppeteer-browser-ready.svg)](https://www.npmjs.com/package/puppeteer-browser-ready)\n[![Build](https://github.com/center-key/puppeteer-browser-ready/actions/workflows/run-spec-on-push.yaml/badge.svg)](https://github.com/center-key/puppeteer-browser-ready/actions/workflows/run-spec-on-push.yaml)\n\n**puppeteer-browser-ready** is a helper utility to reduce the amount of boilerplate code needed\nto tell Puppeteer to visit a web page and and retrieve the HTML.\u0026nbsp;\nIt's primarily intended for use within [Mocha](https://mochajs.org) test cases.\u0026nbsp;\nIn addition to the raw HTML, you get a [node-html-parsed](https://github.com/taoqf/node-html-parser)\nroot so you can immediately run queries on the DOM.\n\n## A) Setup\n**Install packages:**\n```shell\n$ npm install --save-dev puppeteer puppeteer-browser-ready\n```\n**Import packages:**\n```javascript\nimport puppeteer from 'puppeteer';\nimport { browserReady } from 'puppeteer-browser-ready';\n```\n\n## B) Usage\nUse the `browserReady.goto(url, options)` function to tell Puppeteer which page to open.\nThe **Promise** will resolve with a **Web** object containing a `title` field and a `html` field.\nPass the **Web** object to the `browserReady.close(web)` function to disconnect the page.\n```javascript\nconst url = 'https://pretty-print-json.js.org/';\nlet web;  //fields: browser, page, response, status, location, title, html, root\nbefore(async () =\u003e web = await puppeteer.launch().then(browserReady.goto(url));\nafter(async () =\u003e  await browserReady.close(web));\n```\n### `goto()` Options\n| Name (key)   | Type        | Default | Description                                               |\n| :----------- | :---------- | :------ | :-------------------------------------------------------- |\n| `parseHtml`  | **boolean** | `true`  | Return the DOM root as an HTMLElement (node-html-parsed). |\n| `verbose`    | **boolean** | `false` | Output HTTP connection debug messages.                    |\n\n### `startWebServer()` Options\n| Name (key)    | Type        | Default| Description                                      |\n| :------------ | :---------- | :----- | :----------------------------------------------- |\n| `autoCleanup` | **boolean** | `true` | Terminate connection on interruption (`SIGINT`). |\n| `folder`      | **string**  | `'.'`  | Document root for the static web server.         |\n| `port`        | **number**  | `0`    | Port number for server (`0` find open port).     |\n| `verbose`     | **boolean** | `true` | Output informational messages.                   |\n\n## C) TypeScript Declarations\nSee the TypeScript declarations at the top of the\n[puppeteer-browser-ready.ts](src/puppeteer-browser-ready.ts) file.\n\nThe `browserReady.goto(url, options)` function returns a function that takes a Puppeteer **Browser**\nobject and returns a **Promise** that resolves with a **Web** object:\n```typescript\ntype Web = {\n   browser:  Puppeteer.Browser,\n   page:     Puppeteer.Page,\n   response: HTTPResponse | null,\n   location: Location,\n   title:    string,\n   html:     string,\n   root:     HTMLElement | null,  //see node-html-parsed library\n   };\n```\n\nThe optional `browserReady.startWebServer(options)` function starts a static web server and returns\na **Promise** for when the [server](spec/start-web-server.spec.js) is ready:\n```typescript\nexport type Http = {\n   server:     Server,\n   terminator: httpTerminator.HttpTerminator,\n   folder:     string,\n   url:        string,\n   port:       number,\n   verbose:    boolean,\n   };\n```\n\n## D) Examples\n\n### Example 1: Node.js program\n**Code:**\n```javascript\nimport puppeteer from 'puppeteer';\nimport { browserReady } from 'puppeteer-browser-ready';\n\nconst handleResponse = (web) =\u003e {\n   console.log('Hello, World!');\n   console.log('web fields:', Object.keys(web).join(', '));\n   console.log(`The HTML from ${web.location.href} is ${web.html.length} characters`,\n      `long and contains ${web.root.querySelectorAll('p').length} \u003cp\u003e tags.`);\n   return web;\n   };\npuppeteer.launch()\n   .then(browserReady.goto('https://pretty-print-json.js.org/'))\n   .then(handleResponse)\n   .then(browserReady.close);\n```\n**Output:**\n```\nHello, World!\nweb fields: browser, page, response, status, location, title, html, root\nThe HTML from https://pretty-print-json.js.org/ is 8200 characters\nlong and contains 7 \u003cp\u003e tags.\n```\n\n### Example 2: Mocha specification suite\n**Code:**\n```javascript\n// Mocha Specification Suite\n\n// Imports\nimport puppeteer from 'puppeteer';\nimport { assertDeepStrictEqual } from 'assert-deep-strict-equal';\nimport { browserReady } from 'puppeteer-browser-ready';\n\n// Setup\nconst url = 'https://pretty-print-json.js.org/';\nlet web;  //fields: browser, page, response, status, location, title, html, root\nconst loadWebPage = async () =\u003e\n   web = await puppeteer.launch().then(browserReady.goto(url));\nconst closeWebPage = async () =\u003e\n   await browserReady.close(web);\n\n/////////////////////////////////////////////////////////////////////////////////////\ndescribe('The web page', () =\u003e {\n   before(loadWebPage);\n   after(closeWebPage);\n\n   it('has the correct URL', () =\u003e {\n      const actual =   { status: web.status, url: web.location.href };\n      const expected = { status: 200,        url: url };\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   it('title starts with \"Pretty-Print JSON\"', () =\u003e {\n      const actual =   { title: web.title.substring(0, 17) };\n      const expected = { title: 'Pretty-Print JSON' };\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   it('body has exactly one header, main, and footer -- node-html-parsed', () =\u003e {\n      const getTags =  (elems) =\u003e [...elems].map(elem =\u003e elem.tagName.toLowerCase());\n      const actual =   getTags(web.root.querySelectorAll('body \u003e*'));\n      const expected = ['header', 'main', 'footer'];\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   it('body has exactly one header, main, and footer -- page.$$eval()', async () =\u003e {\n      const getTags =  (elems) =\u003e elems.map(elem =\u003e elem.nodeName.toLowerCase());\n      const actual =   await web.page.$$eval('body \u003e*', getTags);\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 actual =   { '🚀': !!web.html.match(/🚀/g), '🪐': !!web.html.match(/🪐/g) };\n      const expected = { '🚀': true,                    '🪐': true };\n      assertDeepStrictEqual(actual, expected);\n      });\n\n   });\n```\n**Output:**\n```\n  The web page\n    ✓ has the correct URL\n    ✓ title starts with \"Pretty-Print JSON\"\n    ✓ body has exactly one header, main, and footer -- node-html-parsed\n    ✓ body has exactly one header, main, and footer -- page.$$eval()\n\n  The document content\n    ✓ has a 🚀 traveling to 🪐!\n```\n\n### Example 3: Start and shutdown a static web server\nThe [startWebServer(options) and shutdownWebServer(http)](spec/start-web-server.spec.js) functions\ncan be used in global fixtures to start and shutdown a static web server.\n\nFor example, the **spec/fixtures/setup-teardown.js** file below starts a web server on port `7123`\nwith the web root pointed to the project's **docs** folder.\n\n**Code:**\n```javascript\n// Specification Fixtures\nimport { browserReady } from 'puppeteer-browser-ready';\nlet http;  //fields: server, terminator, folder, url, port, verbose\n\n// Setup\nconst mochaGlobalSetup = async () =\u003e {\n   http = await browserReady.startWebServer({ folder: 'docs', port: 7123 });\n   };\n\n// Teardown\nconst mochaGlobalTeardown = async () =\u003e {\n   await browserReady.shutdownWebServer(http);\n   };\n\nexport { mochaGlobalSetup, mochaGlobalTeardown };\n```\nRun specification suites with global fixtures:\u003cbr\u003e\n`$ npx mocha spec/*.spec.js --require spec/fixtures/setup-teardown.js`\n\n**Output:**\n```\n  [2021-07-14T11:38:22.892Z] Web Server - listening: true 7123 http://localhost:7123/\n  ...Output of Mocha specification suites here...\n  [2021-07-14T11:38:26.704Z] Web Server - shutdown: true\n```\n\n## E) Test Timeout Errors\nBy default Mocha allows a test 2,000 ms to complete before timing out with a failure.\u0026nbsp;\nWeb page load times can vary significantly, so it's sometimes a good idea to use the `timeout`\noption to bump up the allowed test execution time.\n\nExample configuration in **package.json** to allow 5,000 ms:\n```json\n   \"scripts\": {\n      \"pretest\": \"run-scripts clean build\",\n      \"test\": \"mocha spec/*.spec.js --timeout 7000\"\n   },\n```\n\n\u003cbr\u003e\n\n---\n**CLI Build Tools for package.json**\n   - 🎋 [add-dist-header](https://github.com/center-key/add-dist-header):\u0026nbsp; _Prepend a one-line banner comment (with license notice) to distribution files_\n   - 📄 [copy-file-util](https://github.com/center-key/copy-file-util):\u0026nbsp; _Copy or rename a file with optional package version number_\n   - 📂 [copy-folder-util](https://github.com/center-key/copy-folder-util):\u0026nbsp; _Recursively copy files from one folder to another folder_\n   - 🪺 [recursive-exec](https://github.com/center-key/recursive-exec):\u0026nbsp; _Run a command on each file in a folder and its subfolders_\n   - 🔍 [replacer-util](https://github.com/center-key/replacer-util):\u0026nbsp; _Find and replace strings or template outputs in text files_\n   - 🔢 [rev-web-assets](https://github.com/center-key/rev-web-assets):\u0026nbsp; _Revision web asset filenames with cache busting content hash fingerprints_\n   - 🚆 [run-scripts-util](https://github.com/center-key/run-scripts-util):\u0026nbsp; _Organize npm package.json scripts into groups of easy to manage commands_\n   - 🚦 [w3c-html-validator](https://github.com/center-key/w3c-html-validator):\u0026nbsp; _Check the markup validity of HTML files using the W3C validator_\n\n[MIT License](LICENSE.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcenter-key%2Fpuppeteer-browser-ready","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcenter-key%2Fpuppeteer-browser-ready","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcenter-key%2Fpuppeteer-browser-ready/lists"}