diff --git a/README.md b/README.md index 127f4b2..2e5f066 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,166 @@ A CLI api tester and request builder, compatible with Postman collection format ## Why Since newer postman requires registration to use most useful features, I decided to build my own tool reusing their format, to be compatible with my coworkers' collections. Also, I'd much rather use a CLI tool than a bundled webpage. + +# Usage +Add `alias pw=postwoman` to your `.bashrc` because I'll be referring to it as `pw` from now on. + +`pw` expects a `postwoman.json` collection in your cwd. A different file or path can be specified with the global `-c` option. + +`pw` supports 2 actions as of now: + +* `show` which will display on your CLI the collection structure +* `test` which will execute all requests concurrently + +Both actions support a `-v` switch to print more stuff (body, headers, descriptions...) and a `-p` switch to prettify json outputs. + +Both actions also work with a filter: just type your regex as argument and only requests with matching urls will be displayed/executed + +# Examples +All coming examples are run with provided example `postwoman.json` in their cwd. + +### Show +``` +$ pw show +─┐ Sample Postman Collection + ├ * GET https://alemi.dev/dump?source=sample-collection + ├─┐ POST requests + │ ├ * POST https://alemi.dev/dump + │ ├ * POST https://alemi.dev/dump + │ ╵ + ╵ +``` + +``` +$ pw show -v +─┐ Sample Postman Collection + │ A sample collection to demonstrate collections as a set of related requests + │ + ├ * GET https://alemi.dev/dump?source=sample-collection + │ + ├─┐ POST requests + │ │ + │ ├ * POST https://alemi.dev/dump + │ │ [ content-type:text/plain ] + │ │ Duis posuere augue vel cursus pharetra. In luctus a ex nec pretium... + │ │ + │ ├ * POST https://alemi.dev/dump + │ │ [ content-type:application/json ] + │ │ {"length":100,"text":"Lorem ipsum"} + │ │ + │ ╵ + ╵ +``` + +``` +$ pw show -v -p +─┐ Sample Postman Collection + │ A sample collection to demonstrate collections as a set of related requests + │ + ├ * GET https://alemi.dev/dump?source=sample-collection + │ + ├─┐ POST requests + │ │ + │ ├ * POST https://alemi.dev/dump + │ │ [ + │ │ content-type:text/plain + │ │ ] + │ │ Duis posuere augue vel cursus pharetra. In luctus a ex nec pretium... + │ │ + │ ├ * POST https://alemi.dev/dump + │ │ [ + │ │ content-type:application/json + │ │ ] + │ │ { + │ │ "length": 100, + │ │ "text": "Lorem ipsum" + │ │ } + │ │ + │ ╵ + ╵ +``` + +### Test + +``` +$ pw test +─┐ Sample Postman Collection + ├ ✓ 200 >> GET https://alemi.dev/dump?source=sample-collection + ├─┐ POST requests + │ ├ ✓ 200 >> POST https://alemi.dev/dump + │ ├ ✓ 200 >> POST https://alemi.dev/dump + │ ╵ + ╵ +``` + +``` +$ pw test -v -p +─┐ Sample Postman Collection + │ A sample collection to demonstrate collections as a set of related requests + │ + ├ ✓ 200 >> GET https://alemi.dev/dump?source=sample-collection + │ { + │ "body": "", + │ "headers": { + │ "accept": [ + │ "*/*" + │ ], + │ "connection": "close", + │ "user-agent": "postwoman/0.2.0", + │ "x-forwarded-proto": "https", + │ "x-real-ip": "xxx.xxx.xxx.xxx", + │ "x-real-port": xxxxx + │ }, + │ "method": "GET", + │ "path": "/dump?source=sample-collection", + │ "time": 0.2629528, + │ "version": "HTTP/1.0" + │ } + │ + ├─┐ POST requests + │ │ + │ ├ ✓ 200 >> POST https://alemi.dev/dump + │ │ { + │ │ "body": "Duis posuere augue vel cursus pharetra. In luctus a ex nec pretium...", + │ │ "headers": { + │ │ "accept": [ + │ │ "*/*" + │ │ ], + │ │ "connection": "close", + │ │ "content-length": "69", + │ │ "content-type": "text/plain", + │ │ "user-agent": "postwoman/0.2.0", + │ │ "x-forwarded-proto": "https", + │ │ "x-real-ip": "xxx.xxx.xxx.xxx", + │ │ "x-real-port": xxxxx + │ │ }, + │ │ "method": "POST", + │ │ "path": "/dump", + │ │ "time": 0.2708838, + │ │ "version": "HTTP/1.0" + │ │ } + │ │ + │ ├ ✓ 200 >> POST https://alemi.dev/dump + │ │ { + │ │ "body": "{\"text\":\"Lorem ipsum\", \"length\":100}", + │ │ "headers": { + │ │ "accept": [ + │ │ "*/*" + │ │ ], + │ │ "connection": "close", + │ │ "content-length": "36", + │ │ "content-type": "application/json", + │ │ "user-agent": "postwoman/0.2.0", + │ │ "x-forwarded-proto": "https", + │ │ "x-real-ip": "xxx.xxx.xxx.xxx", + │ │ "x-real-port": xxxxx + │ │ }, + │ │ "method": "POST", + │ │ "path": "/dump", + │ │ "time": 0.2888672, + │ │ "version": "HTTP/1.0" + │ │ } + │ │ + │ ╵ + ╵ +``` diff --git a/postwoman.json b/postwoman.json new file mode 100644 index 0000000..d582966 --- /dev/null +++ b/postwoman.json @@ -0,0 +1,85 @@ +{ + "variables": [], + "info": { + "name": "Sample Postman Collection", + "_postman_id": "35567af6-6b92-26c2-561a-21fe8aeeb1ea", + "description": "A sample collection to demonstrate collections as a set of related requests", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "GET request", + "request": { + "url": { + "raw": "https://alemi.dev/dump?source=sample-collection", + "protocol": "https", + "host": [ + "alemi", + "dev" + ], + "path": [ + "dump" + ], + "query": [ + { + "key": "source", + "value": "sample-collection", + "equals": true, + "description": "" + } + ], + "variable": [] + }, + "method": "GET", + "header": [], + "body": {}, + "description": "" + }, + "response": [] + }, + { + "name": "POST requests", + "item": [ + { + "name": "Text body", + "request": { + "url": "https://alemi.dev/dump", + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "text/plain", + "type": "default" + } + ], + "body": { + "mode": "raw", + "raw": "Duis posuere augue vel cursus pharetra. In luctus a ex nec pretium..." + }, + "description": "" + }, + "response": [] + }, + { + "name": "Json body", + "request": { + "url": "https://alemi.dev/dump", + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\"text\":\"Lorem ipsum\", \"length\":100}" + }, + "description": "" + }, + "response": [] + } + ] + } + ] +} diff --git a/sample_collection.json b/sample_collection.json deleted file mode 100644 index f10be8a..0000000 --- a/sample_collection.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "variables": [], - "info": { - "name": "Sample Postman Collection", - "_postman_id": "35567af6-6b92-26c2-561a-21fe8aeeb1ea", - "description": "A sample collection to demonstrate collections as a set of related requests", - "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json" - }, - "item": [ - { - "name": "Newman: GET request", - "event": [ - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "pm.test('expect response be 200', function () {", - " pm.response.to.be.ok", - "})", - "pm.test('expect response json contain args', function () {", - " pm.expect(pm.response.json().args).to.have.property('source')", - " .and.equal('newman-sample-github-collection')", - "})" - ] - } - } - ], - "request": { - "url": { - "raw": "https://postman-echo.com/get?source=newman-sample-github-collection", - "protocol": "https", - "host": [ - "postman-echo", - "com" - ], - "path": [ - "get" - ], - "query": [ - { - "key": "source", - "value": "newman-sample-github-collection", - "equals": true, - "description": "" - } - ], - "variable": [] - }, - "method": "GET", - "header": [], - "body": {}, - "description": "" - }, - "response": [] - }, - { - "name": "Newman: POST request", - "request": { - "url": "https://postman-echo.com/post", - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "text/plain" - } - ], - "body": { - "mode": "raw", - "raw": "Duis posuere augue vel cursus pharetra. In luctus a ex nec pretium..." - }, - "description": "" - }, - "response": [] - }, - { - "name": "Newman: POST request with JSON body", - "request": { - "url": "https://postman-echo.com/post", - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\"text\":\"Duis posuere augue vel cursus pharetra. In luctus a ex nec pretium...\"}" - }, - "description": "" - }, - "response": [] - } - ] -}