APIs are not running in iterations after running a multiple request api - postman

/api/stores triggers an array of different data in postman:
#pre-request script
var managers= pm.globals.get("managers");
var ref= pm.globals.get("ref");
if(!managers && !ref){
managers=[0,1];
ref=["QA0","QA1"];
}
var currentmanager=managers.shift();
pm.globals.set("manager",currentmanager);
pm.globals.set("managers",managers) ;
var currentref=ref.shift();
pm.globals.set("refeng",currentref);
pm.globals.set("ref",ref) ;
#Test script
var managers=pm.globals.get("managers");
var ref=pm.globals.get("ref");
if(managers && managers.length>0 && ref && ref.length>0){
postman.setGlobalVariable("currentmanager",managers.shift());
postman.setGlobalVariable("currentref",ref.shift());
postman.setNextRequest("https://staging-api.toters-api.com/api/stores");
}
else{
postman.clearGlobalVariable("manager");
postman.clearGlobalVariable("managers");
postman.clearGlobalVariable("ref");
postman.clearGlobalVariable("refeng");
}
But when running all APIs in 2 iterations, all APIs that ran under /api/stores didnt run in the 2nd iteration
APIs are not running in 2nd iteration after running a multiple request api

Related

Postman: Set a request header from the output of a program

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

Postman - Newman running from NodeJS

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

How to execute tests in postman based on IF condition

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

How can I run a single endpoint multiple times?

I have a Collection that has three endpoints. The first one creates an asset, the second one adds a file to the asset, and the third one lists all the assets.
How can I run the second one, the one that adds a file to the asset, more than once per each iteration of the Runner?
I'd like the test to create an asset and add multiple files to it for each iteration.
Any suggestions? I know I can duplicate the endpoint, but I was wondering if there was a programmatic way to do it.
Create 2 environment variables:
"Counter" (Number of times you want the request to run)
"RequestNumber" = 1 (To track the current request number)
Add this code to the test section of the request you want to run multiple times:
const counter = pm.environment.get("Counter");
const requestNumber = pm.environment.get("RequestNumber") || 1;
if (requestNumber < counter) {
postman.setNextRequest("RequestName");
requestNumber ++;
pm.environment.set("RequestNumber", requestNumber);
}
else {
pm.environment.set("RequestNumber", 1);
}
Instead of using postman.setNextRequest(), a bit cleaner way to hit the same endpoint is to use pm.sendRequest().
In Test or Pre-request Script, you can create a request object that would describe the request you want to send (URL, HTTP method, headers body, etc.) and put it in pm.sendRequest() function.
Consider:
const requestObject = {
url: 'https://postman-echo.com/post',
method: 'POST',
header: 'headername1:value1',
body: {
mode: 'raw',
raw: JSON.stringify({ key: "this is json" })
}
}
pm.sendRequest(requestObject, (err, res) => {
console.log(res);
});
To run the same request multiple times just put the function in for/for..in/for..of/forEach loop.
Consider:
for(let iteration = 0; iteration < 5; iteration++) {
pm.sendRequest(requestObject, (err, res) => {
console.log(res);
});
}
If you want you can modify the requestObject inside your loop.
Check out the Postman Documentation for more details.
So far, there is no straight forward solution using Postman, to configure several hits for the same request within a folder/collection.
Nevertheless, you can write some code in Pre-request script section, by adding a counter with number of hits you want and call postman.setNextRequest("request_name") method (read more about it from here) with you current request.
Out of Postman app scope, you can export your collection (as JSON file) and write some javascript code using newman which is a Command-line companion utility for Postman (more about newman from here) which gets a run method with a lot of iteration count and data options that would help you (for example, putting your second request in folder and iterates through it).
Hope that helps!

How to make multiple parallel web html requests in a Chrome Extension?

I'd like to retrieve and parse multiple html pages within a Chrome extension.
Using Web Workers for each request seemed like a simple way to make them execute in parallel. Is that possible? My attempt failed, perhaps because it's a known permissions bug.
As a workaround, I guess I could have the main extension page do multiple asynchronous XmlHttpRequests, then have the callback send the result page to Web Workers for parallel parsing. But that method raises the question of how many asynchronous parallel requests can Chrome make at once? That question has been asked here, without answer.
The Chrome Extension I'm writing is a Browser Action.
Code for the worker:
// Triggered by postMessage in the page
onmessage = function (evt) {
var message = evt.data;
postMessage(message.count + " started");
update(message.count, message.url);
};
// parse the results page
function parseResponse(count, url, resp) {
var msg = count.toString() + " received response ";
postMessage(msg);
}
// read the Buganizer URL and parse the result page
var update = function(count, url) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parseResponse(count, url, xhr.responseText);
}
}
xhr.onerror = function(error) {
var msg = "!>: " + count + ": error ";
postMessage(msg);
}
var url = "http://www.hotgrog.com"; // for testing (manifest has permissions for this url)
xhr.open("GET", url, true);
xhr.send();
postMessage(url);
}
Have you looked into trying asynchronous-loaders such as RequireJS or Curl?
Take a look at the authors explanation as to WHY we should use his product.