apideck-libraries/postman-to-k6

Support for auto-insertion of import lines

pfunk1978 opened this issue · 7 comments

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?

Hi @pfunk1978

Normally the postman-to-k6 does some smart detection and insert the necessary libs, including the crypto-js.js.

Could you share your Postman collection (or simplified version of it), with the crypto-js usage included? That way we can review the output of the conversion and improve where necessary.

Hi @thim81
as requested

-$ cat outs.js
// Auto-generated by the postman-to-k6 converter

import "./libs/shim/core.js";
import "./libs/shim/expect.js";
import { group } from "k6";
import * as CryptoJS from "./libs/crypto-js.js"  // imported by me

export let options = { maxRedirects: 4 };


const Pre = Symbol.for("pre");
const Request = Symbol.for("request");
postman[Symbol.for("initial")]({
  options,
  collection: {
    JWT_TOKEN: "",
    APPROVER_TOKEN: "",
    UPLOADER_TOKEN: ""
  },
  environment: {
    host: "10.0.5.49:8081",
    v7: "kmes/v7",
    v6: "kmes/v6",
    jwtIssuer: redacted,
    hmacKey: redacted,
    testUser: "testUser"
  }
});

export default function() {
  postman[Pre].push(() => {

    function make_payload(name) {
      let payload = {
        iss: pm.environment.get("jwtIssuer"),
        iat: Math.floor(Date.now() / 1000),
        exp: Math.floor(Date.now() / 1000 + 100000),
        sub: name
      };
      return payload;
    }

    function base64url(source) {
      let encodedSource = CryptoJS.enc.Base64.stringify(source)
        .replace(/=+$/, "")
        .replace(/\+/g, "-")
        .replace(/\//g, "_");
      return encodedSource;
    }

    function build_token(payload) {
      let hmac_key = pm.environment.get("hmacKey");
      let header = {
        alg: "HS256",
        typ: "JWT"
      };
      let b64_header = base64url(
        CryptoJS.enc.Utf8.parse(JSON.stringify(header))
      );
      let b64_data = base64url(
        CryptoJS.enc.Utf8.parse(JSON.stringify(payload))
      );
      let message = b64_header + "." + b64_data;
      let b64_signature = base64url(CryptoJS.HmacSHA256(message, hmac_key));
      let jwt_token = [b64_header, b64_data, b64_signature].join(".");
      return jwt_token;
    }

    function build_token_from_name(name) {
      let payload = make_payload(name);
      let token = build_token(payload);
      return token;
    }

    let user = pm.environment.get("testUser");
    pm.collectionVariables.set("JWT_TOKEN", build_token_from_name(user));
    pm.collectionVariables.set(
      "APPROVER_TOKEN",
      build_token_from_name("approver")
    );
    pm.collectionVariables.set(
      "UPLOADER_TOKEN",
      build_token_from_name("uploader")
    );
  });

  group("SymmetricKeyGeneration", function() {
    postman[Request]({


      ...

Hi @pfunk1978, I was refering to the Postman collection. But I think I can build a Postman collection based on your output.

hi @pfunk1978

In the past you had to use "require" statements to use libraries like "crypto-js".
https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#using-external-libraries
The postman-to-k6 convertor, scanned for these "require" statements to trigger the automatic loading of the libraries used.

It seems that these Postman supports these libraries without the need of using "require", which means that the postman-to-k6 converter is not aware of these libraries being used.

An example:
https://www.postman.com/postman/workspace/postman-answers/request/18070393-d1fd1172-daef-44d2-a993-5591d1f5d9e7?ctx=code

I'll do some exploration to see if the convertor can detect the usage of libraries in another way.

hi @pfunk1978

We have enhanced support for the commonly supported libs: crypto, cheerio, lodash, xml2json.

The PR will be merged in and this enhancement will be part of the next release.

Closing the issue, since the latest postman-to-k6 version (1.8.5) contains this enhancement.