Store Data from Postman request in variables to use in tests - postman

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
});

Related

can we pass multiple args in Get Json Value key?

I'm for now fetching one arg value through Get Json Value key
Create Session Get_Inventory_Details ${Base_URL}
${Headers}= Create Dictionary Content-Type=application/json Authorization=bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6InByaXRpc3dhaW4iLCJpYXQiOjE1Njc1MTQ2NDd9.o3qTPbj2KH6AgHpIf1BLV5nOlGL-fR83wSGAYyuWsBQ
${Response}= Get Request Get_Inventory_Details inventorybyOutlet/7 headers=${Headers}
Log To Console ${Response.status_code}
Log Many ${Response.content}
${actual_response}= Convert To String ${Response.status_code}
Should Be Equal ${actual_response} 200
${quantity}= Get Json Value ${Response.content} /0/currentInventory
Run Keyword If ${quantity}>10 Log Threshold Condition Pass ELSE Log Threshold Condition Fail
What can be the possible way out if I want to pass more than one arg in Get Json Value
I have tried
${quantity}= Get Json Value ${Response.content} /0/currentInventory/0/itemid
Reference to Json Data
[
{
"isInventoryOperationEnable":1,
"itemId":1,
"name":"Afghani Chicken Tikka Biryani (Heavy Eater)",
"posName":"Afghani Chicken Tikka Biryani (Heavy Eater)",
"image":"https://d30mle0t4iy75h.cloudfront.net/websiteV2/images/menuItems/AfghaniTikkaBiryani.jpg",
"typeid":2,
"isCombo":0,
"currentInventory":100,
"categoryId":1,
"categoryname":"Biryani",
"subCategoryId":1,
"sequenceInCategory":1
},
{
"isInventoryOperationEnable":1,
"itemId":3,
"name":"Chicken Tikka Biryani (Heavy Eater)",
"posName":"Chicken Tikka Biryani (Heavy Eater)",
"image":"https://d30mle0t4iy75h.cloudfront.net/websiteV2/images/menuItems/ChickenTikkaBiryani.jpg",
"typeid":2,
"isCombo":0,
"currentInventory":100,
"categoryId":1,
"categoryname":"Biryani",
"subCategoryId":1,
"sequenceInCategory":14
}
]
But RobotFramework throws error as :-
JsonPointerException: Document '' does not support indexing, must be mapping/sequence or support __getitem__
Error Message on RobotFramework
Please can anyone help in finding out a way how to pass more than 1 arg in this case
Thank You
Create Session Get_Inventory_Details ${Base_URL}
${Headers}= Create Dictionary Content-Type=application/json Authorization=bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6InByaXRpc3dhaW4iLCJpYXQiOjE1Njc1MTQ2NDd9.o3qTPbj2KH6AgHpIf1BLV5nOlGL-fR83wSGAYyuWsBQ
${Response}= Get Request Get_Inventory_Details inventorybyOutlet/7 headers=${Headers}
Log To Console ${Response.status_code}
Log Many ${Response.content}
${actual_response}= Convert To String ${Response.status_code}
Should Be Equal ${actual_response} 200
${response_content_json}= To Json ${Response.content} #To Json is from RequestsLibrary
${quantity}= Set Variable ${response_content_json}[0][currentInventory]
Run Keyword If ${quantity}>10 Log Threshold Condition Pass ELSE Log Threshold Condition Fail
In this case, ${quantity} was 100.
Note two things:
after converting to JSON, variable values can be accessed alike dictionary type variables
To JSON keyword is from RequestsLibrary

Using Postman, unable to reference CSV file for JavaScript test

I am using a REST API with a POST request. I have created a CSV file to load in various inputs and using the Collection Runner to submit my requests and run the associated JavaScript Tests iteratively. I am trying to figure out how I can also have an entry in each row of the CSV to reference for my JavaScript Test in order to make the JavaScript dynamic. I've searched the Postman documentation and forums, as well as Google and Stack Overflow, but I haven't found anything that works. Here is a basic example of what I'm trying to accomplish.
Let's say I have a basic adding API. Here is my Request:
{
"Numbers": {
"Value_1": {{val1}},
"Value_2": {{val2}},
}
}
The CSV file is as follows:
val1,val2,sum
1,1,2
2,2,4
3,3,6
For this example, lets assume that the API returns a response that includes the sum of val1 and val2; something like this:
{
"Numbers": {{sum}},
}
I am able to load val1 and val2 into my request and iterate through the request for each row, but I am having trouble incorporating the sum values (from the same CSV) into the JavaScript Test.
I am trying to do something like the test below where I can reference the sum value from my spreadsheet, but Postman doesn't like my syntax.
pm.test("Adding machine", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.Numbers === {{sum}});
});
Does anyone have any suggestions? Is this even possible to do?
You could use the pm.iterationData().get('var_name') function and create a check like this?
pm.test("Sums are correctly calculated", () => {
pm.expect(pm.response.json().Numbers).to.equal(pm.iterationData.get('sum'))
})

How to read entire test data file in postman as part of pre-request script?

I am trying to read the entire test data file as a part of pre-request script in postman.
I tried the variable pm.iterationData, however ,it prints only the current iteration data set in the colletion runner.
I need the entire test data and load it as an environment variable in postman.
Is there a way?
The solution that i could find for this is, to set the test data in a variable as a part of pre-request script as follows:
let testdataset =
[
{
"name": "xyz",
"address": "abcd",
"value": "Hello"
},
{
"name" : "mno",
"address" : "defg",
"value" : "Mnop"
}
];
The best way I have come up with dealing with this (collecting all data from a file to us in one request) is to:
Have 2 nodes
The first node has
A dummy call to something like https://postman-echo.com/
Code that:
i. stores the table headers in an environment variable;
ii. concatenates the rows into environment variables;
iii. does 'postman.setNextRequest(null)' for all but the last row
The second node
Only runs in the last iteration
Sends collected data in the environment variable to the API
There is (currently) no way to not make any call on the first node at the moment.
See Github ticket for a request to do this: Request a way for nodes in collection to be logic-only, no request issued #5707

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.