Use Random Collection Variable in Request Body

My question:
To automate Name generation in Test requests, I want to use a random collection variable in the collection pre-request script.

Problem is that I don’t see the actual value in the variable, request body → some kind of Typo?

Details (like screenshots):

I use the following pre-request script function to set the Collection variable

function randomString(length=1) {
    let randomString = "Test_";
    for (let i = 0; i < length; i++){
        randomString += pm.variables.replaceIn("{{$randomAlphaNumeric}}");
    }
    return randomString;
}

STRING_LEN = 15
pm.collectionVariables.set('CollRandomString', randomString(STRING_LEN));

The variable is correctly set:

But when I want to use this variable in a request body, the current value is not shown during mouse-over.

{
    "$type": "bla",
    "Message": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
    <functionname>
        <functionparameter>
            <Name>{{CollRandomString}}</Name>

Hi @dacreator

You appear to be working with XML but have the body type set to JSON.

Hi @w4dd325 ,
that should be correct- header content-type is applicaton/json.
The software manufacturer uses an API interface in JSON format, which encases XML…
Regards

OK, I’ve never seen that before.

But the issue with that is using this format appears to recognise the first { of the variable as part of the XML. You can see in your screenshot that the first one is red and the rest are orange. That’s why your variable isn’t working.

Unfortunately, I don’t know enough about this format to suggest a fix (or even if Postman is built to handle it). I’ll have a play around and see if I can figure it out.

Hi @w4dd325 ,
answer from sw manufacturer - they “expect to have the XML message as a string under the message property on the JSON”.
Perhaps you find something, thanks in advance.

JSON and XML mixed together!!

Whoever the Solution Architect is for that API needs a stern talking to :slight_smile:

However, this still might be possible.

Step 1. Create a variable to store the initial XML string.
Step 2. Parse the variable into a Javascript object.
Step 3. Produce your random string and update the name element in the JavaScript object.
Step 4. Save the JavaScript object back into a string variable and hope it hasn’t messed up the formatting.
Step 5. Use that variable for the message field in the body.

If you can provide an example “message” XML string. I’ll have a go at this next week. (I like a challenge).

Hi @mdjones ,
sorry for delayed answer -

looking into the Code snipplet, I saw that it actually is working - in te CURL message, the correct current value of the collection variable is shown.


Nevertheless, one may not be confused by the red line in the body and that the value is not being shown on mouse over.

Unfortunately, I cannot test it as I have to wait for some API corrections on software side to be implemented. Then I can test again, if the correct object with correct name will be created.

“If you can provide an example “message” XML string. I’ll have a go at this next week. (I like a challenge).”


POST ... {
  ...
    },
    "tls": {
   ...
    },
  "Request Headers": {
    "content-type": "application/json",
    "authorization": "Bearer ...",
    "user-agent": "PostmanRuntime/7.29.2",
    "accept": "*/*",
    "cache-control": "no-cache",
    "postman-token": "...",
    "host": "...",
    "accept-encoding": "gzip, deflate, br",
    "connection": "keep-alive",
    "content-length": "...",
    "cookie": "...."
  },
  "Request Body": "{\n    \"$type\": \"..., ...\",\n    \"Message\": \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\n    <Name>Test_kbnfpst0hln9myy</Name>\n  \"MessageType\": \"...\"\n}",
  "Response Headers": {
    "...-service-history-id": "True",
    "content-encoding": "br",
    "content-type": "application/json; charset=utf-8",
    "date": "Wed, 02 Nov 2022 12:35:30 GMT",
    "vary": "Accept-Encoding",
    "transfer-encoding": "chunked"
  },
  "Response Body": "{...}```

I can parse the XML string into a JavaScript object (and that element does seem to be wrapped in a string).

I can update said object.

What I can’t do is convert it back to XML as it doesn’t seem that Postman supports the libraries needed to do this.

I’ll see if there is a way to update the string as it is, but that is probably a lot more code than using an existing library like json2xml or the DOMParser method.

Hopefully this won’t be needed, and although it not showing the details when you hover it, it’s still working as you generally need it to. Fingers crossed.

I had a look at the libraries that Postman does support, and it supports xml2js (not to be confused with xml2Json).

The following will allow you to parse an XML string into a JavaScript object, update whatever element you want, and then using the xml2js build function, create a new XML string. (Not sure about all of the new line and escape characters you have though).

// intitial XML string
var initialXmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<functionname>\n<functionparameter>\n<Name>Test_kbnfpst0hln9myy</Name>\n<Type>Test_Type</Type>\n</functionparameter>\n</functionname>";
console.log("----initial XML string----")
console.log(initialXmlString);

// random string using Lodash _.
var randomString = "Test_" + _.times(15, () => _.random(35).toString(36)).join('');

// convert the initial string into a JavaScript object so that you can target the elements
var javascriptObject = xml2Json(initialXmlString); 
console.log(javascriptObject);

// update the name element with the randomString
javascriptObject.functionname.functionparameter.Name = randomString;
console.log(javascriptObject);

// the xml2js library can generate XML, not to be confused with xml2json
var xml2js = require('xml2js');
var builder = new xml2js.Builder();
var updatedXmlString = builder.buildObject(javascriptObject);
console.log("----new XML string----")
console.log(updatedXmlString);

image

Hi @mdjones
Thanks, was able to replicate your code.
I understand this would have to be integrate into the pre-request Script on request-level.
Question is how can I integrate this solution on Collection level, to change a collection variable which every request then can use?
Let me know if I understand wrongly.

Thanks

This needs to be in the tests tab of the request which returns the initial XML.

It needs to run after than request.