Karate - substring - lastindexof trim/ strip/ slice help needed - karate

I have a tricky authentication issue which requires multiple calls to ultimately obtain an access-token.
I am currently stumbling on the conversion of a returned correlation-id to a correct format.
The correlationID from a post response is returned as: Id-c5ea93607b0682a76040b5db 0; Id-c5ea93607b0682a76040b5db 2
I need to convert to c5ea93607b0682a76040b5db
I have tried with * def serviceId1 = correlationID.substring(correlationID.lastIndexOf('-')+ 1).trim()
which is resulting in c5ea93607b0682a76040b5db 2
I need to strip the " 2" value from the backend of the id to make it
from: 'c5ea93607b0682a76040b5db 2'
to: 'c5ea93607b0682a76040b5db'
I have tried many ways but cant refine to get working - ANY HELP IS MUCH APPRECIATED
The code below:
Scenario: Obtaining access_token
* def correlationID = 'Id-c5ea93607b0682a76040b5db 0; Id-c5ea93607b0682a76040b5db 2'
* def serviceId1 = correlationID.substring(correlationID.lastIndexOf('-')+ 1).trim()
* print 'correlationID ' + correlationID
* print 'serviceID ' + serviceId1
is resulting in c5ea93607b0682a76040b5db 2 ( I want to strip the trailing " 2" - how can I do this?

Here you go:
* def temp = 'c5ea93607b0682a76040b5db 2'
* def pos = temp.lastIndexOf(' ')
* def fixed = temp.substring(0, pos)
* match fixed == 'c5ea93607b0682a76040b5db'

Related

Not able to extract text format response in karate [duplicate]

I want a specific value from the response header etag.
Response header:
etag: W/"118-pbdwwFo9SKNhD3Lx5iHJyngpq00"
Karate Code:
* def etag = responseHeaders['etag'][0]
* print 'Value of Etag is', etag
* def etagValue = etag.substring(etag.lastIndexOf('-') + 1)
* print 'Value of Etag is', etagValue
It is giving me the value of complete etag which is expected. Now I want to only get specific values as below.
etag variable has value
W/"118-pbdwwFo9SKNhD3Lx5iHJyngpq00"
etagValue variable has value here how to remove double quotes from end
pbdwwFo9SKNhD3Lx5iHJyngpq00"
Expected value where - is left boundary and " is right boundary of the value I need.
pbdwwFo9SKNhD3Lx5iHJyngpq00
Use indexOf() two times. Here you go:
* def etag = 'W/"118-pbdwwFo9SKNhD3Lx5iHJyngpq00"'
* def temp1 = etag.substring(etag.indexOf('-') + 1)
* def temp2 = temp1.substring(0, temp1.indexOf('"'))
* match temp2 == 'pbdwwFo9SKNhD3Lx5iHJyngpq00'
For completeness, there is also a karate.extract() API that can use regex:
* def extracted = karate.extract(etag, '-([^\\"]+)"', 1)
* match extracted == 'pbdwwFo9SKNhD3Lx5iHJyngpq00'

Karate - Unable to replace graphql query variables through data driven scenario outline 'examples' [duplicate]

I am not sure why replace is not working.
I have a graphql query:
mutation updateLocation{
updateLocation(input: {
address:"<address>",
id:"<storeID>",
name:"<name>",
workingHours: [
{
closingTime:"<closingTime>",
isClosed:false,
openingTime:"<openingTime>"
}
.......
And in feature file I have this:
Given def query = read ('classpath:graphQL/updateStore.graphql')
* replace query.address = "<address>"
* replace query.regionId = "<regionId>"
* replace query.name = "<name>"
* replace query.closingTime = "<closingTime>"
* replace query.openingTime = "<openingTime>"
* replace query.storeID = storeId
And request { query : '#(query)'}
When method post
Then status 200
Examples:
|address |regionId |name |closingTime |openingTime |
|Adrs1 |286 |st1 |20:00 |10:00 |
The replace works for address, regionid, and name but it does not work for closing time or opening time, these two values stay empty.
Also if I define header in background like this:
Given header Authorization = 'Bearer ' + token
I still have to add this line for each request in the same scenario, or I have been missing something?
Works for me:
* def query = 'closingTime:"<closingTime>"'
* replace query.closingTime = '20:00'
* match query == 'closingTime:"20:00"'
So please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Note that * replace query.closingTime = closingTime should work. I recommend avoiding confusion by using different names for the Examples columns.

Karate replace in graphql

I am not sure why replace is not working.
I have a graphql query:
mutation updateLocation{
updateLocation(input: {
address:"<address>",
id:"<storeID>",
name:"<name>",
workingHours: [
{
closingTime:"<closingTime>",
isClosed:false,
openingTime:"<openingTime>"
}
.......
And in feature file I have this:
Given def query = read ('classpath:graphQL/updateStore.graphql')
* replace query.address = "<address>"
* replace query.regionId = "<regionId>"
* replace query.name = "<name>"
* replace query.closingTime = "<closingTime>"
* replace query.openingTime = "<openingTime>"
* replace query.storeID = storeId
And request { query : '#(query)'}
When method post
Then status 200
Examples:
|address |regionId |name |closingTime |openingTime |
|Adrs1 |286 |st1 |20:00 |10:00 |
The replace works for address, regionid, and name but it does not work for closing time or opening time, these two values stay empty.
Also if I define header in background like this:
Given header Authorization = 'Bearer ' + token
I still have to add this line for each request in the same scenario, or I have been missing something?
Works for me:
* def query = 'closingTime:"<closingTime>"'
* replace query.closingTime = '20:00'
* match query == 'closingTime:"20:00"'
So please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue
Note that * replace query.closingTime = closingTime should work. I recommend avoiding confusion by using different names for the Examples columns.

Change type from string to float/double for a key value of any json object in an array

i have a json as follows:
* def first = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":"57.0928","name":"XYZN","longitude":"9.8492"}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":"1.234","name":"ABCN","longitude":"29.8482"}]
def second = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":57.0928,"name":"XYZN","longitude":9.8492}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":1.234,"name":"ABCN","longitude":29.8482}]
i want to compare these two, but its failing because the first json has longitude and latitude as string while second json has them as numbers.
Also, i dont want to change second json and has to be used as it is.
Please suggest how can i change the type from string to number in first?
I tried https://github.com/intuit/karate#floats-and-integers
but it didnt work out for object array.
Sample Code:
Feature:
Scenario:
* def first = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":"57.0928","name":"XYZN","longitude":"9.8492"}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":"1.234","name":"ABCN","longitude":"29.8482"}]
* def second = [{"country":"X","code":"XY","cityName":"XYZN","city":"XYZ","timezone":"XYZT","latitude":57.0928,"name":"XYZN","longitude":9.8492}, {"country":"A","code":"AB","cityName":"ABCN","city":"ABC","timezone":"ABCT","latitude":1.234,"name":"ABCN","longitude":29.8482}]
* def first_formatted = []
* def fun = function(x){x.latitude = Number(x.latitude); x.longitude = Number(x.longitude); karate.appendTo(first_formatted, x); }
* karate.forEach(first, fun)
* print first_formatted
* match first_formatted == second

Unable to Parse the variable value to the array variable

I was trying to pass the variable 'i' value to a array index 'locations[i]' using below karate code. but throwing an error saying unable to parse. Please suggest be for any changes.
Feature: Verify Branches
Background: For loop implementation
Given url ''
When method GET
Then status 200
* def i = 0
* def z = $.locations[i].zip
* def p = $.locations[i].phone
* def fun =
"""
function(locations){
for (var i = 0; i < locations.length; i++)
{
print(i)
print('Element at Location ' + i +':' + p)
}
}
"""
Scenario: Validate the locations
Given url ''
When method GET
Then status 200
* call fun p
It is hard to make out anything since you have not provided the value of the response. There are many things wrong here. But I'll try.
Take this line:
* def z = $.locations[i].zip
This will not work, Karate does not support variables within JsonPath by default, refer the docs: https://github.com/intuit/karate#jsonpath-filters
And I think you are un-necessarily using JsonPath where normal JavaScript would have been sufficient:
* def z = response.locations[i].zip
Also it seems you are just trying to loop over an array and call a feature. Please refer to the documentation on Data Driven Features.
Take some time and read the docs and examples please, it will be worth your time. One more tip - before I leave you to understand Karate a little better. There is a way to convert a JSON array into another JSON array should you need it:
* def fun = function(x){ return { value: x } }
* def list = [1, 2, 3]
* def res = karate.map(list, fun)
* match res == [{ value: 1 }, { value: 2 }, { value: 3 }]
So there should never be a need for you to manually do a for loop at all.