In order to save the response from postman API calls, I am executing Postman collection using newman run.
The collection runs when running using
newman run C:\TasteBud\NewMan\JSON-Order_collection.json --env-var unique_order_id=OD-06-07-I2Q5-JYRY5ARPN --environment C:\TasteBud\NewMan\EnvironmentJSON.json
However when I run the same collection as part of javascript or nodejs script.
node writeToFile.js
it throws error as node "1⠄ JSONError in test-script " refer attached image. I need to pass the auth token generated by login request to subsequent request. So I have variable assignment in the "test".
let response = pm.response.json();
pm.environment.set("auth_token", response.data.auth_token);
console.log(pm.response.json().data.auth_token);
Why cant I have "test" ? if no then how can I pass/set these environment variable for subsequent API call ?
Code inside writeToFile.js is here. writeToFile.js
Always use status code validation in your token generation. because every request is based on the token, if we receive negative status code, terminate the build.
postman.setNextRequest(null);
var jsonData = JSON.parse(responseBody);
if(responseCode.code === 200){
tests["Status code is 200"] = responseCode.code === 200;
postman.setEnvironmentVariable("AT", jsonData.oauth2.accessToken);
console.log("AccessToken : " +jsonData.oauth2.accessToken);
}
else{
postman.setNextRequest(null);
console.log("Error generating user token");
console.log("Status code : "+responseCode.code);
console.log("Status description : "+jsonData.statusDescr);
}
Related
I need to make requests to an API that accepts authentication tokens and I want to be able to use a dynamically generated token by running cmd.exe /c GenerateToken.bat instead of having to run my program and then manually paste the value in Postman every time.
I imagine something that looks like this:
How can I set the value of a HTTP header to contain the stdout output of a program or a batch file?
Short answer is, you can't. This is deliberate, both pre-request and test scripts (the only way, other than a collection runner, to make your environment dynamic) run in the postman sandbox, which has limited functionality.
More information of what is available is in the postman-sandbox Github repository page and in postman docs (scroll to the bottom to see what libraries you can import)
You do have a few options, as described in comments - postman allows sending requests and parsing the response in scripts, so you can automate this way. You do need a server to handle the requests and execute your script (simplest option is probably a small server suporting CGI - I won't detail it here as I feel it's too big of a scope for this answer. Other options are also available, such as a small PHP or Node server)
Once you do have a server, the pre-request script is very simple:
const requestOptions = {
url: `your_server_endpoint`,
method: 'GET'
}
pm.sendRequest(requestOptions, function (err, res) {
if (err) {
throw new Error(err);
} else if (res.code != 200) {
throw new Error(`Non-200 response when fetching token: ${res.code} ${res.status}`);
} else {
var token = res.text();
pm.environment.set("my_token", token);
}
});
You can then set the header as {{my_token}} in the "Headers" tab, and it will be updated once the script runs.
You can do something similar to this from Pre-request Scripts at the collection level.
This is available in postman for 9 different authorization and authentication methods.
this is a sample code taken from this article, that show how to do this in Pre-request Scripts for OAuth2
// Refresh the OAuth token if necessary
var tokenDate = new Date(2010,1,1);
var tokenTimestamp = pm.environment.get("OAuth_Timestamp");
if(tokenTimestamp){
tokenDate = Date.parse(tokenTimestamp);
}
var expiresInTime = pm.environment.get("ExpiresInTime");
if(!expiresInTime){
expiresInTime = 300000; // Set default expiration time to 5 minutes
}
if((new Date() - tokenDate) >= expiresInTime)
{
pm.sendRequest({
url: pm.variables.get("Auth_Url"),
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': pm.variables.get("Basic_Auth")
}
}, function (err, res) {
pm.environment.set("OAuth_Token", res.json().access_token);
pm.environment.set("OAuth_Timestamp", new Date());
// Set the ExpiresInTime variable to the time given in the response if it exists
if(res.json().expires_in){
expiresInTime = res.json().expires_in * 1000;
}
pm.environment.set("ExpiresInTime", expiresInTime);
});
}
We have a lot of API level automated tests written as collections of requests in Postman.
We have a script to run all collections in automated manner.
Is there a way to label/run only subset of requests e.g. with some label e.g. as smoke suite, without copying requests to new collection(s) and run then explicitly (as this yields the need to maintain same tests in 2 places...)?
There might be labels, groups or some script that skips the request is env variable is set...
you can create folders and organize test like
smoke_and_regression
smoke_only etc
you can specify which folder to run using --folder arguent when using newman as command line tool
you can also control the execution flow using postman.setNextRequest .
and also you can run newman as an npm module.
you just need to write a logic to read the collection file and get all folder names containing "smoke" for eg and pass it as an array
const newman = require('newman'); // require newman in your project
// call newman.run to pass `options` object and wait for callback
newman.run({
collection: require('./sample-collection.json'),
reporters: 'cli',
folder: folders
}, function (err) {
if (err) { throw err; }
console.log('collection run complete!');
});
Just update for the comments:
in old and new UI you can select which folder to execute in collection runner
Get all requests in the collection:
you can also get information about all the requests in a collection by using :
https://api.getpostman.com/collections/{{collection_UUID}}
to get uuid and api key goto :
https://app.getpostman.com
Now for generating api key >
goto account settings > api key and generate api key.
to get collection uuid goto specific workspace and collection and copy the uuid part from url:
Now in your collection
Rename all requests as:
get user details [Regression][Smoke][Somethingelse]
get account details [Regression]
Then Create a new request called initial request and keep it as the first request in your collection:
url: https://api.getpostman.com/collections/8xxxxtheuuidyoucopied
authorization: apikey-header : key: X-Api-Key and value: yourapikey
test-script :
pm.environment.unset("requestToRun")
reqeustlist = pm.response.json().collection.item.map((a) => a.name)
requestToRun = reqeustlist.filter((a) => a.includes(pm.environment.get("tag")))
let val = requestToRun.pop()
pm.environment.set("requestToRun", requestToRun)
val ? postman.setNextRequest(val) : postman.setNextRequest(null)
Now set the envirnoment variable as what you want to look for eg: run script that contains text "Regression" then set pm.environment.set("tag","Regression")
Now in your collection-pre-request add:
if (pm.info.requestName !== "initial request") {
let requestToRun = pm.environment.get("requestToRun")
let val = requestToRun.pop()
pm.environment.set("requestToRun", requestToRun)
val ? postman.setNextRequest(val) : postman.setNextRequest(null)
}
Output:
Example collection:
https://www.getpostman.com/collections/73e771fe61f7781f8598
Ran only reqeusts that has "Copy" in its name
Running collection with POSTMAN,but not with NEWMAN(With Environment.json).
My code under 'Tests' in 1st POSTMAN GET request:
pm.test("Retrieve cookie(TS01a20dbe)", function() {
let headerValue = pm.response.headers.get("Set-Cookie")
var headerValue1 = headerValue.match(/TS01a20dbe=(.*); Path/)[1];
pm.environment.set("TS01a20dbe", headerValue1);
});
Note:
pm.environment.set("TS01a20dbe", headerValue1); - Updating 'TS01a20dbe' value in environment variable when I run above GET request from POSTMAN, but not updating when I run the same from NEWMAN. So 'TS01a20dbe' value is not passed on to next POST request. Please see below.
{
"key": "Cookie",
"value": "TS01a20dbe={{TS01a20dbe}}; check=true; AMCVS_E9895AF6591C3FDF0A495C80%40AdobeOrg=1;
}
Here is the command i'm using to run collection from NEWMAN
newman run <collectionName.json> -e <environmentFileName.json> --insecure
From below Response, I want to fetch the value of "responseCode" and store temporarily. If a value is 1 then on Console, I want to write "Test PASS". Can anyone share code for this test?
{
"data":{
"transactionId":"$1"
},
"responseMessage":"Transaction successfully done. Transaction Id : txn_15594028419901124218",
"responseCode":1
}
I tried to use the following code to set the variable:
var jsonData = JSON.parse(responseBody);
pm.globals.set("responseCode",jsonData.data.responseCode);
This basic test would check that value in the response, store the variable and also write Test PASS to the console
pm.test("Check the Response Code is 1", () => {
pm.expect(pm.response.json().responseCode).to.eql(1);
pm.globals.set("responseCode", pm.response.json().responseCode)
console.log("Test PASS")
});
This doesn't account for the test failing and writing Test FAIL to the console, you kind of get that anyway in the Postman UI.
If you didn't want to wrap this in a test, you could just do something like:
if(pm.response.json().responseCode === 1){
pm.globals.set("responseCode", pm.response.json().responseCode)
console.log("Test PASS")
}
else {
console.log("Test FAIL")
}
I want to exeucute Tests script in postman based on IF condition.
for eg:
var data = JSON.parse(responseBody);
if(responseCode.code === 404 ){
tests["TEst1: Invalid ID passed"];
}
When I use the above one it is not executing. How to use if condition on tests
To test the response code, you can do it directly.
tests["Status code is 400"] = responseCode.code === 400;
You have to use below line when you want to test the data inside the Json.
var data = JSON.parse(responseBody);
tests["Success --> Request & Response account first name matched"] = data.firstName === postman.getEnvironmentVariable("firstName");