Coder Social home page Coder Social logo

apideck-libraries / postman-to-k6 Goto Github PK

View Code? Open in Web Editor NEW
207.0 6.0 19.0 4.01 MB

Converts Postman collections to k6 script code

Home Page: https://npmjs.com/package/@apideck/postman-to-k6

License: Apache License 2.0

JavaScript 99.82% Dockerfile 0.15% Shell 0.03%
k6 postman performance-testing load-testing postman-collection k6-converter

postman-to-k6's Issues

The converted post api return 415 in k6 running, it can work well in postman, please do me a favor, thanks a lot.

The response code is 415 on the below API when running it by k6.

It works well in postman, the response code is 201.

Could you give me some helps on it? Thanks a lot.

postman[Request]({
name: "saveAgentWithOneTrainingRange",
id: "4836e494-b613-44c1-b650-bacf86f258d4",
method: "POST",
address:
"http://10.148.82.149/demo/APM/Data/api/MachineLearningAgents",
data:
'{"Id":"AA-1","Name":"AA-1","Description":"test","FkSensorGroup":40,"AgentType":"GMM","MaxIterations":20,"AgentCategory":1,"FkGranularity":21,"Attributes":"{\"profile\":{\"ActionType\":\"train\",\"AgentAlgo\":\"GMM\",\"FilterLength\":3,\"MinAlertDuration\":2,\"EventThreshold\":0.5,\"OperatingState\":3,\"DistanceType\":\"euclidean\",\"IterDroprRate\":5,\"Iterations\":200,\"AgentType\":\"anomaly\",\"TrainRange\":[[\"2013-06-18T17:31:58.000Z\",\"2013-12-18T06:12:56.000Z\"]]}}"}',
headers: {
Accept: "application/json, text/plain, /",
Authorization:
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBcHBsaWNhdGlvbiI6IkFzcGVuIE10ZWxsIiwiUGVyc2lzdGVuY2UiOiJQcmltYXJ5IiwidW5pcXVlX25hbWUiOiJBZG1pbiIsInByaW1hcnlzaWQiOiIyIiwicm9sZSI6IkFkbWluaXN0cmF0b3IiLCJuYmYiOjE2NDkzNzk3MTYsImV4cCI6MTY0OTczOTcxNiwiaWF0IjoxNjQ5Mzc5NzE2LCJpc3MiOiJBc3BlbnRlY2hNdGVsbCJ9.lVdWs-wrMpOHA18OSWgqqKP8BT0mT9YVIKHm2Kbu9ks",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36",
"Content-Type": "application/json"
},
post(response) {
console.log("/api/MachineLearningAgents-response code:", pm.response.code);
pm.test("Success to add sensor role mapping on the sensor group on asset.", function () {
pm.expect(pm.response.code).to.be.oneOf([201]);
});
}
});

Question: how can I repeat a request depending on the response body content?

Hi! First of all - thanks for you work!
I have a problem and I hope you can help me. I can't understand how I can repeat a request depending on the response body content. The response contains a status that changes asynchronously and I have to wait for a certain one and after that continue my scenario.
How can I do this?

Post request incorrectly exported from Postman to k6

Hi!
I faced the following problem:
In Postman (Version 9.28.1) I have POST request with Content-Type="application/x-www-form-urlencoded"

image

After export collection I have

"request": {
"method": "POST",
"header": [
	{
		"key": "Content-Type",
		"value": "application/json",
		"type": "text"
	}
],

Because of this, the k6 request returned a 400 error and I could not understand what was wrong for a long time.

K6 teardown()

Feature: Provide a converter option to insert custom K6 "teardown()" logic, that will be injected during conversion.

Reasoning: K6 supports a life cycle: https://k6.io/docs/using-k6/test-life-cycle/
The postman-to-k6 package already supports the “pre-request” functionality from Postman, but it feels that “setup()” and “teardown()” is not a concept that exists in Postman, and it serves more the K6 execution.

Approach: Provide a file reference as a --k6-teardown CLI parameter, that will be take the content of the file and insert it in the generated K6 script.

postman variables that reference broader scoped postman variables are not replaced

I have postman collection variables that reference postman environment variables and postman environment variables that reference postman global variables. Here is the output after running postman-to-k6 script.

postman[Symbol.for("initial")]({
  options,
  global: {
    local_auth_token: "my_local_api_auth_token",
    dev_auth_token: "my_dev_api_auth_token",
    stage_auth_token: "my_stage_api_auth_token",
    prod_auth_token: "my_prod_api_auth_token"
  },
  collection: {
    collection_name: "automated_package_details_by_uuid",
    product: "{{product_zulu}}"
  },
  environment: {
    base_url: "https://stage.api.azul.com/metadata/v1",
    auth_token: "{{stage_auth_token}}",
    product_zulu: "zulu"
  }
});

When exporting environment files from Postman variables are copied verbatim, leaving the variable references in double curly brackets. Unfortunately the postman-to-k6 script doesn't replace variables with the broader scoped variable values, so all variables that reference other variables do not end up with their expected values.

Can not use atob function because of different built-in libraries

I use many atob function in my postman collection; indeed, it not work in k6 script. However I found that I can easily fix it by using the k6/encoding module.

import { b64decode } from "k6/encoding";
const atob = (str) => {
  return b64decode(str, "rawstd", "s");
};

I want to ask is there any plan to support this kind of problem?
e.g. crypto-js -> k6/crypto

The "path" argument must be of type string. Received an instance of Array ( ERROR if src is array for files form-data)

I run

postman-to-k6 tr.json -o k6.js -e tr_env.json

than get this result )

The "path" argument must be of type string. Received an instance of Array

I don't now, why?))

My collection is example

									],
							"request": {
								"method": "POST",
								"header": [
									{
											"key": "Content-Type",
												"value": "multipart/mixed",
												"type": "text",
												"disabled": true
									}
								],
								"body": {
										"mode": "formdata",
											"formdata": [
												{
													"key": "files[]",
													"description": "Массив файлов",
													"type": "file",
													"src": [
														"1.txt",
														"2.txt"
													]
												},
												{
													"key": "data",
													"value": "{\n\t\"name\": \"{{name}}\",\n\t\"num\": \"{{num}}\",\n\t\"reg_date\": \"{{reg_date}}\",\n\t\"source_id\": \"{{source_id}}\",\n\t\t\t\t\t\t\t\t\t \n\t\"attr\": [{\n\t\t\t\t  \n\t\t\t\"attr_id\": {{attr1_id}},\n\t\t\t\"attr_value\": {{rand_num}}\n\t\t},\n\t\t{\n\t\t\t\t  \n\t\t\t\"attr_id\": {{attr2_id}},\n\t\t\t\"attr_value\": \"{{rand_str}}\"\n\t\t},\n\t\t{\n\t\t\t\t  \n\t\t\t\"attr_id\": {{attr3_id}},\n\t\t\t\"attr_value\": \"{{rand_date}}\"\n\t\t},\n\t\t{\n\t\t\t\t  \n\t\t\t\"attr_id\": {{attr4_id}},\n\t\t\t\"attr_value\": {{rand_bool}}\n\t\t},\n\t\t{\n\t\t\t\t \n\t\t\t\"attr_id\": {{attr5_id}}\n\t\t}\n\t],\n\t\"files\": [{\n\t\t\"file\": \"1.txt\",\n\t\t\"fr_id\": {{fr_id1}},\n\t\t\"parent_file\": null\n\t}, {\n\t\t\"file\": \"2.txt\",\n\t\t\"fr_id\": {{fr_id2}},\n\t\t\"parent_file\": \"1.txt\"\n\t}]\n}",
													"contentType": "application/json",
													"description": "JSON",
													"type": "text"
												}
											]
						
								},
								"url": {
									"raw": "https://trarchive.it-thematic.ru/api/ead/eds/",

But i use to POST form-date like multi-form (multipart/mixed) and body like 'raw', maybe this problem?)

yes, he is doesn't path to file

	"1.txt",
	"2.txt"
]

How to pass oauth credentials

Hi,

I am using command to convert postman collection with global variable file as

postman-to-k6 collection.json --global workspace.postman_globals.json -o k6-postman.js

but getting this "To convert this collection provide OAuth credentials. Either include them in the collection or use the --oauth1-* CLI options. Minimum required configuration is signature method, consumer key, consumer secret, access token, and token secret"

The login request generates login token using ID and password then this token is used in all the subsequent requests and passed as XML header.

In postman script I am storing the generated token as global variable and then passing this variable in each requests.

Please suggest what to do .

Thanks,

API Key Auth not correctly being assigned to header

We have the following logic in lib\auth\apikey.js

const aid = require('../aid');

class ApiKeyAuth {
  constructor(settings) {
    const params = settings.parameters();
    const key = params.get('key');
    const value = aid.evalString(params.get('value'));

    if (params.get('in') === 'header') {
      this.logic = '' + `config.headers['${key}'] = ${value};`;
    } else {
      this.logic = '' + `config.options['${key}'] = ${value};`;
    }
  }
}

module.exports = ApiKeyAuth;

I have my Postman collection auth defined like this:

image

A snippet from the json output from my exported collection:

	"auth": {
		"type": "apikey",
		"apikey": [
			{
				"key": "value",
				"value": "{{Authorization}}",
				"type": "string"
			},
			{
				"key": "key",
				"value": "Authorization",
				"type": "string"
			}
		]
	},

It appears to be incorrectly using config.options instead of config.headers so my auth to fail when using the generated k6s output. If I manually change that part the auth works.

Perhaps something has changed in the output from Postman that's causing the line if (params.get('in') === 'header') { to not work as expected?

Here is my Postman version:

image

CI - docker build (and publish) failing

Hello! 👋

I noticed that you were using GitHub Container Registry from this PR from @thim81 - #91

But I noticed that there are zero packages published - https://github.com/orgs/apideck-libraries/packages?repo_name=postman-to-k6

So I went and looked at the Actions (CI) and saw https://github.com/apideck-libraries/postman-to-k6/actions/runs/4133989496

buildx failed with: ERROR: failed to solve: executor failed running [/bin/sh -c npm install --production]: exit code: 127

Thanks for considering! Have a wonderful day!

Support for auto-insertion of import lines

As a postman-to-k6 user I would like to auto-insert custom import statements from ./libs/

Issue:

I'm rather new to k6, which in-turn means that I'm also new to postman-to-k6. What I describe below may be my error, but I'm really not sure.

The setup I have uses JWT's for auth. In postman I use CryptoJS to create a new JWT on the fly for every request. When I first tried to convert a sample collection to develop a proof of concept, the generated k6 script did not work as is.

Through no fault of the team of postman-to-k6, I understood, after reading k6 documentation, what that k6 couldn't resolve the crypto-js dependency and that I would need to compile the libs. This started me on a long, dark, rabbit-hole decent into the world of webpack, then rollup, which I never really got to work.

Finally, after a bit of poking around, I discovered that postman-to-k6, magically put crypto-js.js into ./libs folder and all that I needed was to add the import line via sed and I was in business.

I'm not sure if postman-to-k6 pulled in crypto-js for me or if it's just part of the deal. But if it was smart enough to understand that CryptoJS requires crypto-js, then can it also be smart enough to add that inclusion as well?

API Key Auth not correctly being assigned to header

We have the following logic in lib\auth\apikey.js

const aid = require('../aid');

class ApiKeyAuth {
  constructor(settings) {
    const params = settings.parameters();
    const key = params.get('key');
    const value = aid.evalString(params.get('value'));

    if (params.get('in') === 'header') {
      this.logic = '' + `config.headers['${key}'] = ${value};`;
    } else {
      this.logic = '' + `config.options['${key}'] = ${value};`;
    }
  }
}

module.exports = ApiKeyAuth;

I have my Postman collection auth defined like this:

image

A snippet from the json output from my exported collection:

	"auth": {
		"type": "apikey",
		"apikey": [
			{
				"key": "value",
				"value": "{{Authorization}}",
				"type": "string"
			},
			{
				"key": "key",
				"value": "Authorization",
				"type": "string"
			}
		]
	},

It appears to be incorrectly using config.options instead of config.headers so my auth to fail when using the generated k6s output. If I manually change that part the auth works.

Perhaps something has changed in the output from Postman that's causing the line if (params.get('in') === 'header') { to not work as expected?

Here is my Postman version:

image

Not working for requests Content-Type is application/xml

ERRO[0007] TypeError: Cannot read property 'RequestTransactionPOSRegistration' of undefined

var jsonObject = xml2Json(pm.response.text());
pm.environment.set(
"pdc",
jsonObject.RequestTransactionPOSRegistration.POSs.POS.Identifier
);

Does not recognize as object.

K6 setup()

Feature: Provide a converter option to insert custom K6 "setup()" logic, that will be injected during conversion.

Reasoning: K6 supports a life cycle: https://k6.io/docs/using-k6/test-life-cycle/
The package already supports the “pre-request” functionality from Postman, but it feels that “setup()” and “teardown()” is not a concept that exists in Postman, and it serves more the K6 execution.

Approach: Provide a file reference as a --k6-setup CLI parameter, that will be take the content of the file and insert it in the generated K6 script.

GraphQL Support

Hi There,

I just came across this watching the office hours episode regarding this and loved the workflow shown by Tim.

I'd like to implement this type of workflow for my team so whipped up a small API to test out the workflow and starting planning for our system design, however I seem to be getting some issues once I try and run the k6. This scipt runs fine, but fails to actually hit the endpoints and tests fails.

We/I am using a graphQL API for this proof of concept and wondered if that's the issue, that the postman-to-k6 tool doesn't support graphQL API's/tests coming from postman? I can see that k6 does support graphQL.

Any help would be great.

Thanks.

Error: Cannot find module 'prettier'

get the following issue when running postman-to-k6 PostmanScript.json -e PostmanGlobals.json -o k6-script.js

node:internal/modules/cjs/loader:1042
throw err;
^

Error: Cannot find module 'prettier'
Require stack:

  • /opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/render/index.js
  • /opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/convert/object.js
  • /opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/convert/json.js
  • /opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/convert/file.js
  • /opt/homebrew/lib/node_modules/@apideck/postman-to-k6/bin/postman-to-k6.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
    at Module._load (node:internal/modules/cjs/loader:885:27)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object. (/opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/render/index.js:3:18)
    at Module._compile (node:internal/modules/cjs/loader:1218:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at Module._load (node:internal/modules/cjs/loader:922:12)
    at Module.require (node:internal/modules/cjs/loader:1105:19) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
    '/opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/render/index.js',
    '/opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/convert/object.js',
    '/opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/convert/json.js',
    '/opt/homebrew/lib/node_modules/@apideck/postman-to-k6/lib/convert/file.js',
    '/opt/homebrew/lib/node_modules/@apideck/postman-to-k6/bin/postman-to-k6.js'
    ]
    }

Node.js v19.3.0

The "path" argument must be of type string. Received type object

{
									"name": "xxx",
									"request": {
										"method": "POST",
										"header": [],
										"body": {
											"mode": "formdata",
											"formdata": [
												{
													"key": "file",
													"description": "required",
													"type": "file",
													"src": []
												}
											]
										},
										"url": {
											"raw": "xxx",
											"host": [
												"xxx"
											],
											"path": [
												"xxx"
											]
										}
									},
									"response": []
								}

The default value is of src is []. If I replace it with a string, then the postman-to-k6 will work fine.

Help wanted - Convert Ava test to Jest test

When the postman-to-k6 library was incubated, Ava was a handy and easy to use testing framework.
The version used in the postman-to-k6 library is out-dated (and contains security issues) and migrating to the latest version is not easy, because of a lack of knowledge of Ava and the mocking used.

The approach is to switch to Jest. Jest is a testing framework with a lot of traction and fairly easy to use, including great tooling.

So this story is about migrating the current tests from Ava to Jest.
I'm more familiar with Jest (although not an expert) than with Ava, so I could use a hand from the community.

If there are members willing to contribute to this Ava to Jest migration, lets us know.

Question: Is there a plan to provide mentioned `unsupported-features` ?

As per https://github.com/apideck-libraries/postman-to-k6#unsupported-features, some features are not supported (although this pm.response.to.have.status(200); worked for us!) which creates some blockers in converting our already written postman scripts to k6 scripts.

Is there a plan to provide for those features? Until these are provided, any other workarounds for these missing features?

Thanks for maintaining this friendly fork!

Many converted tests have "::" in the request url

This produces: GoError: group and check names may not contain '::'

snippet of a generated test that is causing the issue:

  name: "Returns a list of Entity Types.",
  id: "3e5bf7c1-c6c2-4b7a-b08f-7027a55dd05a",
  method: "GET",
  address: "{{baseUrl}}/entities/types?q=lic",
  headers: {
    Accept: "application/json"
  },
  post(response) {
    // Validate status 2xx
    pm.test("[GET]::/entities/types - Status code is 2xx", function() {
      pm.response.to.be.success;
    });```

Support Alternate Environments Format

As a CICD user I wish to pull my environments file from the following url and use it as the environments variables for conversion
https://api.getpostman.com/environment/{UUID}

Issue:

Environments file retrieved from the postman api differs from the environments file from a postman export process. The file retrieved from the API call has the following structure

{"environment":{"id":"redacted","name":"10.0.5.49-6.3.2.x","owner":"18142191","createdAt":"2022-08-03T16:16:01.000Z","updatedAt":"2022-08-03T16:43:57.000Z","values":[{"key":"host","value":"10.0.5.49","enabled":true},{"key":"port","value":"8081","enabled":true},{"key":"v7","value":"v7","enabled":true},{"key":"v6","value":"v6","enabled":true},{"key":"jwtIssuer","value":"redacted","enabled":true},{"key":"hmacKey","value":"redacted","enabled":true},{"key":"testUser","value":"testUser","enabled":true}],"isPublic":false}}

While the file from a regular export process has the following structure

{"id":"redacted","name":"10.0.5.49-6.3.2.x","values":[{"key":"host","value":"10.0.5.49","enabled":true},{"key":"port","value":"8081","enabled":true},{"key":"v7","value":"v7","enabled":true},{"key":"v6","value":"v6","enabled":true},{"key":"jwtIssuer","value":"redacted","enabled":true},{"key":"hmacKey","value":"redacted","enabled":true},{"key":"testUser","value":"testUser","enabled":true}]}

Currently I'm getting a environment.values is not iterable error

Requests wrongly reusing headers from previous requests?

I converted a postman collection to K6 but I cannot properly run it. After analysing the HTTP requests with Fiddler I noticed that some requests are wrongly reusing headers from previous requests.
For instance:

  1. Request to /login (user/pass)-> OK (no Content-Type is specified so the default and correct application/x-www-form-urlencoded value is sent).
  2. Request to /endpoint1 using an Authorization bearer header obtained from the previous request. -> OK
  3. Another request to /login (which is a verbatim copy of the first request) -> FAIL, due to wrong headers (Content-Type: application/json & Authorization: Bearer xxxxxxxx) that seems to be coming from the previous request to /endpoint1

Is there something I can do to avoid this behaviour?
I have tried to manually add the Content-Type: application/x-www-form-urlencoded header to the /login requests but the second request to the /login still fails due to the incorrect Authorization: bearer xxxxxxxx header, even though a 'basic' auth is defined for these requests.

Thanks

oauth2 pkce auth code flow support?

Does this library support auth code flow with pkce? I'm getting generated tests that look like this:

postman[Symbol.for("define")]({
  name: "admin user",
  id: "6a08afa4-c3ee-4f6b-a2cf-549a12ef119e",
  method: "GET",
  address: "{{mde-base-url}}/admin/user",
  post(response) {
    pm.test("Status code is 200", function() {
      pm.response.to.have.status(200);
    });
  },
  auth(config, Var) {
    config.headers.Authorization = "Bearer undefined";
  }
});

my collection configuration looks like this:

"name": "admin user",
	"event": [
			{
				"listen": "test",
				"script": {
					"exec": [
						"pm.test(\"Status code is 200\", function () {\r",
						"    pm.response.to.have.status(200);\r",
						"});\r",
							""
					],
					"type": "text/javascript"
				}
			}
		],
		"request": {
			"auth": {
				"type": "oauth2",
				"oauth2": [
					{
						"key": "refreshRequestParams",
						"value": [
							{
								"key": "origin",
								"value": "http://localhost:8080",
								"enabled": true,
								"send_as": "request_header"
							}
						],
						"type": "any"
					},
					{
						"key": "tokenRequestParams",
						"value": [
							{
								"key": "client_id",
								"value": "{{clienId}}",
								"enabled": true,
								"send_as": "request_body"
							},
							{
								"key": "origin",
								"value": "http://localhost:8080",
								"enabled": true,
								"send_as": "request_header"
							}
						],
						"type": "any"
					},
					{
						"key": "scope",
						"value": "api://mde-api-nonprod.mayo.edu/api.use",
						"type": "string"
					},
					{
						"key": "clientId",
						"value": "{{clientId}}",
						"type": "string"
					},
					{
						"key": "redirect_uri",
						"value": "http://localhost:8080",
						"type": "string"
					},
					{
						"key": "tokenName",
						"value": "AAD MDE-nonprod",
						"type": "string"
					},
					{
						"key": "useBrowser",
						"value": false,
						"type": "boolean"
					},
					{
						"key": "authUrl",
						"value": "https://login.microsoftonline.com/{{aad-tenant}}/oauth2/v2.0/authorize",
						"type": "string"
					},
					{
						"key": "accessTokenUrl",
						"value": "https://login.microsoftonline.com/{{aad-tenant}}/oauth2/v2.0/token",
						"type": "string"
					},
					{
						"key": "grant_type",
						"value": "authorization_code_with_pkce",
						"type": "string"
					},
					{
						"key": "addTokenTo",
						"value": "header",
						"type": "string"
					}
				]
			},

I can use this auth configuration in postman and it pops open a window for me to authenticate in but I assume that's not possible in k6... is that why this isn't working?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.