From 598540f1ca53609d0690577897fb83fac773fbe4 Mon Sep 17 00:00:00 2001 From: Thim Date: Mon, 1 Apr 2024 19:06:41 +0200 Subject: [PATCH] Added pm.response.headers.all() & pm.response.headers.get() --- CHANGELOG.md | 4 ++++ README.md | 5 +++-- lib/shim/core.js | 36 ++++++++++++++++++++++++++++++++---- test/com/shim/response.js | 29 ++++++++++++++++++++++++++--- yarn.lock | 6 +++--- 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef055dd..9cd0d3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/apideck-libraries/postman-to-k6/compare/v1.8.7...HEAD) +## [1.9.0] - 2024-04-01 + +- Support for pm.response.headers.all() & pm.response.headers.get() (thanks to the contribution of @aegrey) + ## [1.8.10] - 2024-01-05 ### Security diff --git a/README.md b/README.md index c435036..64db6a9 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ variables, ... to K6 scripts that can be executed by K6 to run performance tests This project is a friendly fork of the original [grafana/postman-to-k6](https://github.com/grafana/postman-to-k6) converter, actively maintained and open for new contributions. +Feel free to contribute or pass any suggestion + ## Content - [Features](#features) @@ -324,8 +326,7 @@ $ postman-to-k6 example/v2/echo.json -o k6-script.js - `pm.response.to.have.status(reason)` - `pm.response.to.not.have.status(reason)` - Properties returning Postman classes: - - `pm.request.url` `pm.request.headers` - - `pm.response.headers` + - `pm.request.url` - The Hawk authentication method. - Deprecated `xmlToJson` method. - Request IDs are changed. Postman doesn't provide them in the export, so we have to generate new ones. diff --git a/lib/shim/core.js b/lib/shim/core.js index 92d7438..9b610b5 100644 --- a/lib/shim/core.js +++ b/lib/shim/core.js @@ -33,7 +33,7 @@ String.prototype.has = function(v) { }; /* - * Functional manipulation of frozen dicts + * Functional manipulation of frozen dictionaries * * These objects are frozen for consistency with Postman readonly semantics. * The constructor property is forced clear to keep it as clean as possible. @@ -147,11 +147,13 @@ function requireEnvironment() { throw new Error('Missing Postman environment'); } } + function requireRequest() { if (!state.request) { throw new Error('May only be used in a request scope'); } } + function requirePost() { if (!state.post) { throw new Error('May only be used in a postrequest script'); @@ -461,12 +463,19 @@ const pm = Object.freeze({ /* Response information */ response: Object.freeze({ + headers: Object.freeze({ + get(name) { + const header = store.response.headers.cased[name]; + return header ? header : null; + }, + all() { + const headers = store.response.headers.cased; + return headers ? headers : null; + }, + }), get code() { return store.response.code; }, - get headers() { - throw new Error('pm.response.headers not supported'); - }, json() { parseBodyJson(); const body = store.response.body; @@ -601,6 +610,7 @@ const pm = Object.freeze({ } }, }); + function exposePm() { const exposed = { environment: pm.environment, @@ -917,6 +927,7 @@ const responseCode = Object.freeze({ function xml2Json(xml) { throw new Error('To use xml2Json import ./libs/shim/xml2Json.js'); } + function xmlToJson(xml) { throw new Error('Deprecated function xmlToJson not supported'); } @@ -934,6 +945,7 @@ function parseBodyJson() { body.json = false; } } + function deepEqual(x, y) { // From https://stackoverflow.com/a/32922084/10086414 const ok = Object.keys; @@ -944,6 +956,7 @@ function deepEqual(x, y) { ok(x).every(key => deepEqual(x[key], y[key])) : x === y; } + function jsonPath(value, path) { try { return eval(`value.${path}`); /* eslint-disable-line no-eval */ @@ -976,6 +989,7 @@ function evaluate(text) { } /* Request execution */ + /** * @typedef {object} RequestParams * @param {string} name - Request name. @@ -1039,6 +1053,7 @@ function executeRequest({ exitRequest(); } } + function namedRequest(name, index = 1) { const requests = definition.request[name]; if (!requests) { @@ -1050,6 +1065,7 @@ function namedRequest(name, index = 1) { const config = requests[index - 1]; return executeRequest(config); } + function makeRequestConfig(method, address, data, headers, options, tags) { const config = {}; config.method = method || null; @@ -1086,6 +1102,7 @@ function evaluateAddress(address) { return evaluate(address); } } + function defaultProtocol(addressText) { if (!postman[Extend].module.urijs) { throw new Error( @@ -1099,6 +1116,7 @@ function defaultProtocol(addressText) { } return address.toString(); } + function evaluateDataObject(data) { for (const key of Object.keys(data)) { if (typeof data[key] === 'string') { @@ -1106,6 +1124,7 @@ function evaluateDataObject(data) { } } } + function makeRequestArgs({ method, address, data, headers, options }) { // Set K6 request params from setting if (setting.options) { @@ -1119,6 +1138,7 @@ function makeRequestArgs({ method, address, data, headers, options }) { options.headers = requestHeaders; return [method, address, data, options]; } + function enterRequest(name, id, method, address, data, headers) { state.request = true; store.request.id = id; @@ -1141,6 +1161,7 @@ function enterRequest(name, id, method, address, data, headers) { require, }); } + function enterPost(response = {}) { state.post = true; Object.assign(store.response, { @@ -1162,15 +1183,18 @@ function enterPost(response = {}) { } exposePm(); } + function enterTest() { state.test = true; exposePm(); } + function exitTest() { state.test = false; store.test = []; exposePm(); } + function exitRequest() { state.request = false; state.post = false; @@ -1207,6 +1231,7 @@ function exitRequest() { require: standard.require, }); } + function translateCookies(cookies) { for (const key of Object.keys(cookies)) { // Postman semantics have no duplicate cookie names. Duplicates discarded. @@ -1216,6 +1241,7 @@ function translateCookies(cookies) { store.response.cookies.simple[cookie.name] = cookie.value; } } + function translateCookie(cookie) { return { domain: cookie.domain, @@ -1235,6 +1261,7 @@ function translateCookie(cookie) { value: cookie.value, }; } + function executePrerequest(outer, inner) { const scripts = [...outer]; if (inner) { @@ -1244,6 +1271,7 @@ function executePrerequest(outer, inner) { script(); } } + function executePostrequest(outer, inner, response) { const scripts = [...outer]; if (inner) { diff --git a/test/com/shim/response.js b/test/com/shim/response.js index d976266..3943746 100644 --- a/test/com/shim/response.js +++ b/test/com/shim/response.js @@ -104,11 +104,34 @@ test.serial('pm.response.code', t => { }); }); -test.serial('pm.response.headers', t => { +test.serial('pm.response.headers.get', t => { + http.request.returns({ + headers: { + 'Content-Type': 'application/json', + 'Server': 'GitHub Copilot' + } + }); postman[Request]({ post() { - t.throws(() => { - pm.response.headers; /* eslint-disable-line no-unused-expressions */ + t.deepEqual(pm.response.headers.get('Server'), + 'GitHub Copilot' + ); + } + }); +}); + +test.serial('pm.response.headers.all', t => { + http.request.returns({ + headers: { + 'Content-Type': 'application/json', + 'Server': 'GitHub Copilot' + } + }); + postman[Request]({ + post() { + t.deepEqual(pm.response.headers.all(), { + 'Content-Type': 'application/json', + 'Server': 'GitHub Copilot' }); } }); diff --git a/yarn.lock b/yarn.lock index 7dbceae..c24b356 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2014,9 +2014,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001248: - version "1.0.30001374" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz" - integrity sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw== + version "1.0.30001603" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001603.tgz" + integrity sha512-iL2iSS0eDILMb9n5yKQoTBim9jMZ0Yrk8g0N9K7UzYyWnfIKzXBZD5ngpM37ZcL/cv0Mli8XtVMRYMQAfFpi5Q== chai@^4.3.4: version "4.3.6"