How to store array values in an environment variable in Postman - arrays

I am using a postman to automate apis.
Now I am using following request , lets say :-
{
"customerId": "{{currentClientId}}"
}
Where clientid is a dynamic variable whose value is substituted dynamically as 1 , 2, 3,4 so on..
I call this request multiple times using setNextRequest call in this eg lets say 10.This is being done using a counter variable. I am initialising the counter in my previous request to 0 and using for loop with value as counter as 10 calling the request 10 times.There is no response in body just successful http code 204.
I want to store all these clientids coming in request into an environment Client array variable so I wrote a following pre-request script:-
counter = pm.environment.get("counter");
ClientArray = pm.environment.get("ClientArray");
ClientArray.push(pm.environment.get("currentClientId"));
pm.environment.set("ClientArray",ClientArray);
In Test Script, wrote following code :-
counter = pm.environment.get("counter");
if(counter<=10) {
console.log("hi");
postman.setNextRequest("Request");
counter++;
pm.environment.set("counter",counter);
console.log("Counter",counter);
}
The above scipts is throwing
TypeError | ClientArray.push is not a function.
Could someone please advice how to achieve this.

When you retrieve a value from an environment variable like you're doing:
ClientArray = pm.environment.get("ClientArray");
You're not getting an array, you're getting a string which is why you're getting that error. You need to treat the variable like a string, append the currentClientId much like you do for the counter. Something like:
var currentClientIds = pm.environment.get("ClientArray");
currentClientIds = currentClientIds + "," + currentClientId
When you're done appending i.e. out of your loop simply take the string and convert it to an array:
var currentClientIds = pm.environment.get("ClientArray");
var idsArr = curentClientIds.split(',');

Related

Rails Ransack, initialize from front end as an array

In the React front end, the ransack parameter is initialized like so:
const statusFilter = 'ransack[status_in]=incomplete';
In the backend, I've got
#params["ransack"]&.each do |filter, value|
so that the first line produces
filter = "status_in"
value = "incomplete"
Everywhere else in the app after initializing, the status_in parameter is used as an array, so that multiple statuses can be selected. So I would like to always treat this parameter as an array, not a string, if possible.
My desired output:
value = ["incomplete"]
I've tried
const statusFilter = "ransack[status_in]=['incomplete']";
But that results in
value = "['incomplete']"
I could probably just check whether the type is a string on the first usage, and then convert it to an array. Something like:
value = [value] if value.class == String
But it seems like there should be a way to accomplish this by slightly changing the front so that I don't need to add another line in the back.

Use feeder next 10 results and repeat the request 10 times in Gatling

I am using Gatling 3.6.1 and I am trying to repeat the request 10 times for the next 10 products from the feeder file. This is what I tried:
feed(products, 10)
.repeat(10, "index") {
exec(session => {
val index = session("index").as[Int]
val counter = index + 1
session.set("counter", counter)
})
.exec(productIdsRequest())
}
private def productIdsRequest() = {
http("ProductId${counter}")
.get(path + "products/${product_code${counter}}")
.check(jsonPath("$..code").count.gt(2))
}
I am having trouble getting the counter value to my API URL.
I would like to have something like
products/${product_code1},
products/${product_code2} etc.
But instead, I get the error 'nested attribute definition is not allowed'
So basically I would like that every request gets called with one product from the feeder (in the batch of 10 products)
Can you please help?
Thanks!
Disclaimer: I don't know how realized your feeder products.
If I clearly understand you - just need to move .repeat on high level:
.repeat(10, "counter") {
feed(product)
.exec(http("ProductId ${counter}")
.get("products/${product_code}")
.check(jsonPath("$..code").count.gt(2)))
}

Google Script is returning the index of the array but I need the value

I have a google spreadsheet that gets data logged to it via a google form.
When the form is logged each time, it triggers a script that gets values from a certain section using:
var tabNumsVal = sheet.getSheetValues(lastRow, tabOneCol.getColumn(), 1, 6)[0];
When I check the array, I can see that the array has the values such as:
0: 12
1: 24
2: 26W
3: 0
4: 0
5: 0
However when I use the following command, it puts the index numbers (0 to 5) into the array instead of the values in the array.
var tabNumsFinal = [];
for (var tabard in tabNumsVal) {
if (tabard !== "") {
tabNumsFinal.push(tabard);
}
}
It used to work but I have had to upgrade my code to Google Script v8 and it seems that this has broken the code.
I had to alter the 'for each' code block to a 'for' code block and it seems this is handling the values differently.
I am quite sure this is simple for many people but I really only touch Google Script 1 time each year. I have tried using Logger.log(tabard) to output the data to the execution log, but it just traverses the code and doesn't output anything. I figured this might be because of the !== "" operator, so I placed it above the if statement but still inside the for statement and it still outputs nothing.
I tried using Logger.log(tabNumsVal) and Logger.log(tabNumsFinal) and again it output nothing.
To recap:
The data from the form is returning correctly into the columns of the spreadsheet, hence it is showing inside the array properly. It's just that the index numbers are being output instead of the values from the array.
Since you're using for in loop, tabard is the index here.
var tabNumsFinal = [];
for (var i in tabNumsVal) {
let val = tabNumsVal[i];
if (val !== "") {
tabNumsFinal.push(val);
}
}
For in loop

javascript evaluation failed- karate

I am trying to call an API in second feature file , passing arguments from first feature file . These has to be passed as a param for second API
* def activeDetails =
"""
function(times){
for(i=0;i<=times;i++){
karate.log('Run test round: '+(i+1));
karate.call('getActiveRouteDetails.feature', { token: token, currentPage: i });
}
java.lang.Thread.sleep(1*1000);
}
"""
* call activeDetails totalPages
In my second feature , I am able to print the values passed , Getting error while passing it as a param 'no step-definition method match found for: param pageNumber'
And print currentPage
And print token
And param pageNumber = '#currentPage'
And param token = token
Watch the white space around the = sign. Normally if you use IDE support you can avoid these issues. You seem to have an extra space after pageNumber.
So make this change:
And param pageNumber = currentPage
I request you to please read the docs and examples. You are still un-necessarily making 2 calls. And over complicating your test.

How to increment a variable in Gatlling Loop

I am trying to write a Gatling script where I read a starting number from a CSV file and loop through, say 10 times. In each iteration, I want to increment the value of the parameter.
It looks like some Scala or Java math is needed but could not find information on how to do it or how and where to combine Gatling EL with Scala or Java.
Appreciate any help or direction.
var numloop = new java.util.concurrent.atomic.AtomicInteger(0)
val scn = scenario("Scenario Name")
.asLongAs(_=> numloop.getAndIncrement() <3, exitASAP = false){
feed(csv("ids.csv")) //read ${ID} from the file
.exec(http("request")
.get("""http://finance.yahoo.com/q?s=${ID}""")
.headers(headers_1))
.pause(284 milliseconds)
//How to increment ID for the next iteration and pass in the .get method?
}
You copy-pasted this code from Gatling's Google Group but this use case was very specific.
Did you first properly read the documentation regarding loops? What's your use case and how doesn't it fit with basic loops?
Edit: So the question is: how do I get a unique id per loop iteration and per virtual user?
You can compute one for the loop index and a virtual user id. Session already has a unique ID but it's a String UUID, so it's not very convenient for what you want to do.
// first, let's build a Feeder that set an numeric id:
val userIdFeeder = Iterator.from(0).map(i => Map("userId" -> i))
val iterations = 1000
// set this userId to every virtual user
feed(userIdFeeder)
// loop and define the loop index
.repeat(iterations, "index") {
// set an new attribute named "id"
exec{ session =>
val userId = session("userId").as[Int]
val index = session("index").as[Int]
val id = iterations * userId + index
session.set("id", id)
}
// use id attribute, for example with EL ${id}
}
Here is my answer to this:
Problem Statement: I had to repeat the gatling execution for configured set of times, and my step name has to be dynamic.
object UrlVerifier {
val count = new java.util.concurrent.atomic.AtomicInteger(0)
val baseUrl = Params.applicationBaseUrl
val accessUrl = repeat(Params.noOfPagesToBeVisited,"index") {
exec(session=> {
val randomUrls: List[String] = UrlFeeder.getUrlsToBeTested()
session.set("index", count.getAndIncrement).set("pageToTest", randomUrls(session("index").as[Int]))
}
).
exec(http("Accessing Page ${pageToTest}")
.get(baseUrl+"${pageToTest}")
.check(status.is(200))).pause(Params.timeToPauseInSeconds)
}
So basically UrlFeeder give me list of String (urls to be tested) and in the exec, we are using count (AtomicInteger), and using this we are populating a variable named 'index' whose value will start from 0 and will be getAndIncremented in each iteration. This 'index' variable is the one which will be used within repeat() loop as we are specifying the name of counterVariable to be used as 'index'
Hope it helps others as well.

Resources