{"id":17132687,"url":"https://github.com/nicolassiver/http-probe","last_synced_at":"2025-07-05T09:40:01.949Z","repository":{"id":16394593,"uuid":"79875427","full_name":"NicolasSiver/http-probe","owner":"NicolasSiver","description":"Utility for HTTP validation. Implementation is based on the Chrome debugging protocol.","archived":false,"fork":false,"pushed_at":"2023-03-04T04:02:07.000Z","size":775,"stargazers_count":8,"open_issues_count":4,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-18T05:52:27.762Z","etag":null,"topics":["chrome-debugging-protocol","http-probe","test-automation","webdriver"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/NicolasSiver.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2017-01-24T03:36:54.000Z","updated_at":"2025-04-18T15:43:57.000Z","dependencies_parsed_at":"2025-06-12T16:47:42.219Z","dependency_job_id":null,"html_url":"https://github.com/NicolasSiver/http-probe","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/NicolasSiver/http-probe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicolasSiver%2Fhttp-probe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicolasSiver%2Fhttp-probe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicolasSiver%2Fhttp-probe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicolasSiver%2Fhttp-probe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NicolasSiver","download_url":"https://codeload.github.com/NicolasSiver/http-probe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicolasSiver%2Fhttp-probe/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261315620,"owners_count":23140308,"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":["chrome-debugging-protocol","http-probe","test-automation","webdriver"],"created_at":"2024-10-14T19:27:51.239Z","updated_at":"2025-06-22T15:35:45.348Z","avatar_url":"https://github.com/NicolasSiver.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HTTP Probe\n\nUtility for HTTP validation. Implementation is based on the Chrome debugging protocol.\n\n![Version](https://img.shields.io/npm/v/http-probe.svg)\n![Dependencies](https://david-dm.org/NicolasSiver/http-probe.svg)\n![Code Climate](https://codeclimate.com/github/NicolasSiver/http-probe/badges/gpa.svg)\n[![Coverage Status](https://coveralls.io/repos/github/NicolasSiver/http-probe/badge.svg?branch=master)](https://coveralls.io/github/NicolasSiver/http-probe?branch=master)\n\n## Table of Contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n \n\n- [Motivation](#motivation)\n- [API](#api)\n  - [`HttpProbe`](#httpprobe)\n    - [`constructor(provider)`](#constructorprovider)\n    - [`getRequest(search)`](#getrequestsearch)\n      - [`RequestResult`](#requestresult)\n    - [`getResponse(search)`](#getresponsesearch)\n      - [`ResponseResult`](#responseresult)\n  - [`NetworkInspector`](#networkinspector)\n    - [`constructor(eventTarget)`](#constructoreventtarget)\n    - [`dispose()`](#dispose)\n    - [`getLogs(deplete)`](#getlogsdeplete)\n- [Snapshots](#snapshots)\n- [Links](#links)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Motivation\n\nWhile Selenium and other end-to-end solutions provide a good set of tools to check UI feedback and states, they lack tools for HTTP validation. \nHTTP Probe tries to solve an issue with HTTP testing by providing API to work and analyze Performance (in particular Network) logs in the modern browsers like Chromium.\n\n## API\n\nCreate an instance of the HTTP Probe. Don't forget to teardown an instance, otherwise `http-probe` will accumulate HTTP requests from every consecutive `getRequest` or `getResponse` invocation.\n\n### `HttpProbe`\n\n#### `constructor(provider)`\n\n- `provider \u003cFunction\u003e` should return an array of performance logs\n\nExample: \n\n```js\nconst {HttpProbe} = require('http-probe');\n\nlet httpProbe = new HttpProbe(() =\u003e myMethodToExtractPerformanceLogs());\n```\n\nExtended example for `WebdriverIO`.\n\nFirst of all you should activate performance logs for Google Chrome.\n\n```json\n{\n    \"loggingPrefs\": {\n        \"browser\": \"ALL\",\n        \"performance\": \"ALL\"\n    }\n}\n```\n\nNow in `before` hook you can create an instance of HTTP Probe:\n\n```js\nbefore(() =\u003e {\n    httpProbe = new HttpProbe(() =\u003e {\n        return browser.log('performance').value;\n    });\n});\n```\n\nYou should use single test case per spec if you don't want fight with cache.\n\n#### `getRequest(search)`\n\n- `search \u003cString|RegExp\u003e` a pattern which will be executed against an URL\n\nReturns a `Request` entity with several properties:\n\n- `length \u003cNumber\u003e`, - total number of matched requests\n- `executed \u003cBoolean\u003e`, - if request was executed at least once\n- `executedOnce \u003cBoolean\u003e`, - if request was executed exactly _once_\n- `executedTwice \u003cBoolean\u003e`, - if request was executed exactly _twice_\n- `executeThrice \u003cBoolean\u003e`, - if request was executed exactly _thrice_\n- `first \u003cRequestResult\u003e`, - a result object for the _first_ request\n- `second \u003cRequestResult\u003e`, - a result object for the _second_ request\n- `third \u003cRequestResult\u003e`, - a result object for the _third_ request\n- `last \u003cRequestResult\u003e`, - a result object for the _last_ request\n\n##### `RequestResult`\n\n- `headers \u003cObject\u003e`, - request's headers\n- `method \u003cString\u003e`, - HTTP method, 'GET', 'POST', etc.\n- `postData \u003cObject\u003e`, - request's POST parameters\n- `url \u003cString\u003e`, - request's fully qualified URL \n\nExample:\n\n```js\nexpect(httpProbe.getRequest('accounts/8').executed).to.be.true;\n```\n\n#### `getResponse(search)`\n\n- `search \u003cString|RegExp\u003e` a pattern which will be executed against an URL\n\nReturns a `Response` entity with several properties:\n\n- `length \u003cNumber\u003e`, - total number of matched responses\n- `received \u003cBoolean\u003e`, - if response was delivered at least once\n- `receivedOnce \u003cBoolean\u003e`, - if response was delivered exactly _once_\n- `receivedTwice \u003cBoolean\u003e`, - if response was delivered exactly _twice_\n- `receivedThrice \u003cBoolean\u003e`, - if response was delivered exactly _thrice_\n- `first \u003cResponseResult\u003e`, - a result object for the _first_ response\n- `second \u003cResponseResult\u003e`, - a result object for the _second_ response\n- `third \u003cResponseResult\u003e`, - a result object for the _third_ response\n- `last \u003cResponseResult\u003e`, - a result object for the _last_ response\n\n##### `ResponseResult`\n\n- `encodedDataLength \u003cNumber\u003e`, - Total number of bytes received for this request so far.\n- `fromDiskCache \u003cBoolean\u003e`, - Specifies that the request was served from the disk cache.\n- `fromServiceWorker \u003cBoolean\u003e`, - Specifies that the request was served from the ServiceWorker.\n- `headers \u003cObject\u003e`, - HTTP response headers.\n- `requestHeaders \u003cObject\u003e`, - (Optional) Refined HTTP request headers that were actually transmitted over the network.\n- `status \u003cNumber\u003e`, - HTTP response status code.\n- `statusText \u003cString\u003e`, - HTTP response status text.\n- `url \u003cString\u003e`, - Response URL. This URL can be different from CachedResource.url in case of redirect.\n\nExample:\n\n```js\nexpect(httpProbe.getResponse('total/cart').last.status).to.be.equal(200);\n```\n\n### `NetworkInspector`\n\nCaptures network events through the Chrome debugging protocol for the later use in HttpProbe for analysis.\nSpecifically designed for the solutions that can not provide performance logs or it's more convenient to use listener abstraction for network logs.\n\n#### `constructor(eventTarget)`\n\n- `eventTarget \u003cEventEmitter\u003e` entity that satisfies EventEmitter interface at least for ability to subscribe (`on`) and unsubscribe (`removeListener`) for the events\n\nExample: \n\n```js\nconst {NetworkInspector} = require('http-probe');\n\nlet inspector = new NetworkInspector(myEmitter);\nconsole.log(inspector.getLogs());\ninspector.dispose();\n```\n\nExtended example for `WebdriverIO` with the use of `before` and `after` hooks.\n\n```js\nconst {HttpProbe, NetworkInspector} = require('http-probe');\n\nlet inspector;\n\nbefore(() =\u003e {\n    browser.cdp('Network', 'enable');\n    inspector = new NetworkInspector(browser);\n    httpProbe = new HttpProbe(() =\u003e inspector.getLogs());\n});\n\nafter(() =\u003e {\n    inspector.dispose(); \n});\n```\n\n#### `dispose()`\n\nResets internal resources and listeners. \nAfter this point, the instance of Network Inspector is not usable.\n\nExample:\n\n```js\nnetworkInspector.dispose();\n```\n\n#### `getLogs(deplete)`\n\n- `deplete \u003cBoolean\u003e` an optional parameter, by default it's always `true`. If the parameter is `false` logs will be preserved before the next `getLogs` invocation.\n\nReturns a list of messages formatted to comply with Chrome debugging protocol.\n\nExample:\n\n```js\nlet myLogs = networkInspector.getLogs();\nconsole.log(myLogs);\n```\n\n## Snapshots\n\nTests are working with snapshots. Snapshots are picked randomly and recorded for 30 seconds.\nTo create a snapshot, instance of the Chrome should be active, if yor are using Mac, it could be done via:\n\n```shell\n/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=9222\n```\n\nor run Chrome Browser in the container:\n\n```shell\n$ docker pull justinribeiro/chrome-headless\n$ docker run -it --rm -p 9222:9222 justinribeiro/chrome-headless \n```\n\nNow it's possible to make a snapshot:\n\n```shell\nURL=http://some-domain.com node create-snapshot.js\n\n// or visit multiple websites \n\nURL=\"http://domain1.com http://domain2.com\" node create-snapshot.js\n```\n\n## Links\n\n- [Protocol Viewer](https://github.com/ChromeDevTools/debugger-protocol-viewer)\n- [Performance Log](https://sites.google.com/a/chromium.org/chromedriver/logging/performance-log)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnicolassiver%2Fhttp-probe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnicolassiver%2Fhttp-probe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnicolassiver%2Fhttp-probe/lists"}