How to read dynamic request parameter value in postman? - postman

I pass some a random integer in the value of a parameter in the request body -
"trans_id":"7q498992029699{{$randomInt}}"
What is the best way to get the final value of trans_id param in the Tests tab?
As per my observation, using {{$randomInt}} again in the request body gives a different random integer.

A way around is to store it to environment variable while sending the request, using Pre-request-script. And later get same environment variable in your test.
Body:
{
"trans_id": "{{transId}}"
}
Pre-request-script:
var randomNumber = '7q498992029699' + _.random(0, 1000);
pm.environment.set("transId", randomNumner);
Test:
var tarnsId = pm.environment.get("transId");
Note: {{$randomInt}} and _.random(0, 1000) both are doing the same thing, it provides random number from 0-1000.

You could create your random int as a variable in the Pre-Request script of your request like this:
pm.globals.set('myRandomInt', Math.floor(Math.random() * 1000))
Or
// Using the built-in Lodash module
pm.globals.set("myRandomInt", _.random(0, 1000))
(I am using a global variable in this example but you can of course use an environment variable if you want to.)
Now you can re-use the variable {{myRandomInt}} in your request body and in your Tests tab.

Related

How to use substring of a variable in a param or another variable?

I can use
{{guid}}
to get an id for body params that I can use for a new records ID.
How do I use a substring of guid in postman either in that param variable (which is collection level, by the way) or through another variable?
I tried various such as
{{$guid.substring(10)}}
{{$guid}.substring(10)}
but they did not work
I tried to use a pre-request script like this:
pm.collectionVariables.set("short_guid", pm.collectionVariables.get("myGUID").substr(12) )
using my collection variable myGUID which is defined as {{guid}}
along with
"email": "{{$pm.collectionVariables.get('myGUID')}}#example.com",
but it does not work as the variable is not interpreted and I get a string literal
you have to refer variable in body as {{<variablename}} don't need to call pm.varaible.get
for prerequest :
var uuid = require("uuid")
var myUUID = uuid.v4();
pm.environment.set("myuuid",myUUID.substring(20))
console.log(pm.environment.get("myuuid"))
And in body
{
"email": {{myuuid}}
}
you can also use variables in script section as:
console.log(pm.variables.replaceIn("{{$guid}}").substring(20))
This will first replace {{$guid}} with the postman variable value and then find the substring
you can use it like
console.log(pm.variables.replaceIn("this will print {{variable}} value"))
The second issue of variable not detecting is because of the variable scope
In postman variable scope is from right to left , but precedence is from left to right as follows:
Local>data>environment>collection>global
So if you have a environment variable and collection varible with same name , the value of that variable will be from environment not collection

Store Data from Postman request in variables to use in tests

Im currently trying to get used to POSTMAN and i was wondering if there is a way to store variables from my request JSON Body via Pre Request in some environment variable so ican resuse it in the tests for response value cheks
This is how my json File might look like
{
"text" : "myText",
"attachments": {
"text": "myText2",
"anotherText" : "myText3"
}
So i want to get all Values, store them in a variable before sending my request, and then test if they match the expected value in my response
(example: myText2 gets mapped to green, myText3 gets mapped to red and so on)
That would make it possible to write one test for several request
Thanks a lot!
You can write the following in your script:
let body = JSON.parse(pm.request.body);
_.forEach(body, (value, key) => pm.environment.set(key, JSON.stringify(value)));
This will set each key and it's associated value as an environment variables.
Note you'll need to JSON.parse the value in the test script before using it for testing.
For eg in your test script you'll need to do something like this:
let attachments = JSON.parse(pm.environment.get('attachments'));
pm.test('All attachments are of correct value', function () {
// ...write your test here using the `attachments` variable
});

How to build a Postman url query with Pre-request Scripts

I'm trying to use a pre-request script to build out a request object based on data pulled from a CSV file. The problem is that the request seems to be set in stone prior to the pre-request script being run. That would seem to make this a mid-request script almost rather than a pre-request.
My code is as follows:
if(ipList === undefined) ipList = "1.2.3.4,2.3.4.5,123.234.345.465";
let ips = ipList.split(',');
let queryArray = [];
for( i=0; i<ips.length; i++){
queryArray.push({ "key": "ip", "value": ips[i] });
}
console.log(queryArray);
pm.request.url.query = queryArray;
console.log(pm.request);
When I hardcode a url query variable in the request to equal 4.3.2.1, the pm.response.url object like this:
pm.request.url.query[0] = {key:"ip", value:"4.3.2.1"}
Note that the url.query[0] part of the object matches the parameter in the actual get request.
When I change the value of pm.request.url.query to equal the new query array, however as you can see here, the query array is set correctly, but the parameters are not appended to the request URL.
So unless I'm doing something wrong, it appears that the request is immutable even to the pre-request scripts.
So my question is this:
Is there a way to modify the url params of a request prior to making the request?
BTW: I know that is might seem odd to have multiple params with the same key in a query, but that's the way this API works and hard coding multiple ip addresses in the query works just fine.
You could just assign a new value to pm.request.url.
Here I had some query params already in the URL, which I had to edit:
const urlSplit = request.url.split('?');
const paramsString = urlSplit[1]; // the second part actually represents the query string we need to modify
const eachParamArray = paramsString.split('&');
let params = {};
eachParamArray.forEach((param) => {
const key = param.split('=')[0];
const value = param.split('=')[1];
Object.assign(params, {[key]: value});
});
params.bla = params.bla + 'foobar';
newQueryString = Object.keys(params).map(key => key + '=' + params[key]).join('&');
pm.request.url = urlSplit[0] + '?' + newQueryString;
In the end, I just constructed a new URL, using the first part of the previous one & the query string with the edited bla parameter.
This seemed to work for me--it didn't change what the UI shows the query string is, but it changed what the actual request was (looking at the console log)
pm.request.url.addQueryParams(["a=1", "b=2"])
pm.request.url.query.remove("b")
I have some parameters called "script_loginAs" etc... named such that people on my team know the parameter is evaluated and not sent.

Postman - How to store multiple values from a response header in a var or just be able to see them

Using a GET in postman with the URL posted below, I am able to store the entire response header in question with all of its data in a var, the issue for me is how do I verify the pieces of data inside that var
here is my URL
http://localhost/v1/accounts?pageNumber=1&pageSize=2
[
using postman I am able to get the above in a var
var XPaginationData = postman.getResponseHeader(pm.globals.get("PaginationHeader"));
pm.globals.set("XPaginationData", XPaginationData);
is there a way to get the individual values inside the response header X-Pagination stored in a different var to assert later
using this in postman
pm.globals.set("XPaginationData", JSON.stringify(pm.response.headers));
console.log(JSON.parse(pm.globals.get('XPaginationData')));
console.log(JSON.parse(pm.globals.get('XPaginationData'))[4].value);
I get
how would i go about getting "TotalCount" for example
BIG EDIT:
thanks to a coworker, the solution is this
//Filtering Response Headers to get PaginationHeader
var filteredHeaders = pm.response.headers.all()
.filter(headerObj => {
return headerObj.key == pm.globals.get("PaginationHeader");
});
// JSON parse the string of the requested response header
// from var filteredHeaders
var paginationObj = filteredHeaders[0].value;
paginationObj = JSON.parse(paginationObj);
//Stores global variable for nextpageURL
var nextPageURL = paginationObj.NextPageLink;
postman.setGlobalVariable("nextPageURL", nextPageURL);
You could use JSON.stringfy() when saving the environment variable and then use JSON.parse() to access the different properties or property that you need.
If you set a global variable for the response headers like this:
pm.globals.set('PaginationHeader', JSON.stringify(pm.response.headers))
Then you can get any of the data from the variable like this:
console.log(JSON.parse(pm.globals.get('PaginationHeader'))[1].value)
The image shows how this works in Postman. The ordering of the headers returned in the console is inconsistent so you will need to find the correct one to extract data from the X-Pagination header
Looks like an issue with Postman itself.
The only solution that worked for me was to stringify & parse the JSON again, like this:
var response = JSON.parse(JSON.stringify(res))
After doing this, the headers and all other properties are accessible as expected.

CouchDB filter timestamps in a reduce function - some sort of Date.now?

Can a Date.now type function be used in either map or reduce functions? Can it be used anywhere at all?
More specifically, the view must not cache the Date.now value.
Here is what I tested that only worked for the first run after a change to any view function:
function (doc){
var n = new Date();
if(doc.TimeStamp > n.getTime() - 30000){
emit(doc._id, doc);
}
}
The view rows will be refreshed only when the particular doc gets updated. But you can request the view for that result: emit the doc.TimeStamp as key and request the view with ?startkey=timestamp where timestamp is the value of now.getTime() - 30000.
Yes. var now = new Date() should work.
The condition must result in false. You can test it with the view:
function (doc) {
var now = new Date()
var timestamp = now.getTime()
emit(timestamp,null)
}
It will respond something like
{
"total_rows":1,
"offset":0,
"rows" :[{
"id":"ecd99521eeda9a79320dd8a6954ecc2c",
"key":1429904419591, // timestamp as key
"value":null
}]
}
Make sure that doc.TimeStamp is a number (maybe you have to execute parseInt(doc.TimeStamp)) and greater then timestamp - 30000
Two words about your line of code emit(doc._id, doc);:
To emit doc._id as key means maybe you doesn't need the view. Simply request the doc by GET /databasename/:id. Also to include doc._id in multipart keys or the value of the view row is mostly not necessary because its included in every row automatically as additional property. One valid reason would be when you want to sort the view over the doc ids.
To emit the doc as value is not recommended for performance reasons of the view. Simply add ?include_docs=true when you request the view and every row will have an additional property doc with whole doc in it.