How to assert substring in karate framework - karate

I am getting an array of URLs as a response. I want to check that each URL from the array contains a specific word.
How can I check this in karate framework?
My response is :
response {
"docs":[{
"url":"http://url/1.com"
"title": "some title"
},{
"url":"http://url/2.com"
"title":"ABC"
}]
}
}
Now I want to check that each url field value contains word 'url'.How can I check this as match each $.response.docs.url contains 'url' does not work for me.

Please refer to the match each syntax. Here is an example:
* def response = [ 'http://url-one.com', 'http://url-two.com', ]
* match each response contains 'url'
EDIT - after question was edited. Here is your working example:
* def response =
"""
{
"docs":[
{
"url":"http://url/1.com",
"title":"some title"
},
{
"url":"http://url/2.com",
"title":"ABC"
}
]
}
"""
* def urls = $response.docs[*].url
* match each urls contains '/url/'

Related

is it possible to extract the value of one of the key value pairs in request to be asserted

peter had provided me a solution to use karate 0.9.3 to apply assertion from examples
Trying to do some assertion from request, which will be present in response
i was wondering if it is possible to assert a value from request instead of full request.
**Background:**
* configure headers = read('classpath:merchantServiceheaders.js')
Given url MservUrl
And path 'XXXXXX'
And request Data
When method POST
Then status 200
And match response != null
And match $ contains {serviceName: 'XXXXX'Service', responseMessage:
'Success' }
And match each $.clauses..responseMessage == 'Success'
And match each $..predicate != null
And match each $..predicate == '#present'
And match each $..predicate == '#regex [^0-9]+[0-9]*$'
And match $..predicate contains Data.clauses.subject
Examples:
|Data! |
|'{"clauses":[{"subject":"XXXX","predicate":"999999"},
{"subject":"XXXXX","predicate":"99999"}]}'|
what i am trying to do is on the And match $..predicate contains Data.clauses.subject
is that possible?
Yes, it is very much possible if Data is defined as a variable. But note that $..predicate will always be a JSON array: https://github.com/intuit/karate#get-plus-index
If you want help, please create a proper simple working example.
Sample Code:
Feature: Validation
Scenario:
* def resp = {predicate : "4325325456545646"}
* def data =
"""
{
"clauses": [
{
"subject": "5432154321543210",
"predicate": "4432154321543210"
},
{
"subject": "4325325456545646",
"predicate": "4325325456545646"
}
]
}
"""
* def sublist = get data.clauses[*].subject
* print sublist
* match sublist contains resp.predicate

karate - how to match partial string of the field in response?

i have a json response as below where i just want to match the string "harry"
in autoComplete, id in autoCompleteAuthors
Response {"data": {
"autoComplete": [
"Harry Hole"
],
"autoCompleteAuthors": [
{
"id": "search_authors_harry martinson",
"title": "Harry Martinson",
"type": "Authors"
}
]
}
}
Please suggest how to perform this validations using contains?
i tried like below which is not working
* def autoComlete = get response.data.autoComplete[*]
* match autoComlete contains any 'harry'
you can use match each and #regex marker in karate,
Case sensitive matching
* match each $response.data.autoComplete == "#regex .*Harry.*"
Case in sensitive matching
* match each $response.data.autoComplete == "#regex (?i).*harry.*"
Hope this works for your need.
Edit:
As requested on comments to pass name
* def query = 'harry'
* match each $response.data.autoComplete == "#regex (?i).*" + query + ".*"

Karate API framework - Validate randomly displayed items in response

I am using Karate API framework for the API automation and came across with one scenario, the scenario is when I am hitting a post call it gives me some json response and few of the items are having tags whereas few of them are showing tags as blank to get all the tags below is the feature file scenario line
* def getTags = get response.items[*].resource.tags
It is giving me response as
[
[
],
[
],
[
{
"tags" : "Entertainment"
}
],
[
],
[
{
"tags" : "Family"
}
],
As you can see out of 5 or 6 tags only 2 tags are having the value, so I want to capture if any tags value is showing or not. What would be the logic for the assertion considering these tags can all come as empty and sometimes with come with a string value. In above case "Family" & "Entertainment"
Thanks in advance !
* match each response.items[*].resource.tags == "##string"
This will validate that tags either doesn't exist or is a string.
I think you can use a second variable to strip out the empties, or maybe your original JsonPath should use .., you can experiment:
* def allowed = ['Music', 'Entertainment', 'Documentaries', 'Family']
* def response =
"""
[
[
],
[
],
[
{
"tags":"Entertainment"
}
],
[
],
[
{
"tags":"Family"
}
]
]
"""
* def temp = get response..tags
* print temp
* match each temp == "#? allowed.contains(_)"

Karate : Dynamically input values from embedded expressions in a JSON file

* def mpRequestJson =
"""
{
"entity": '<entity>',
"consent": {
"PHONE": <updategetPhonePref>,
"EMAIL": true,
"POST": false,
"SMS": <updategetSMSPref>
},
"notices": [{
"title": "Privacy policy",
"version": "NA"
}],
"source": "web"
}
"""
Given path '<entity>'
And request mpRequestJson
When method PUT
Then status 200
And match $.consent.PHONE == '<updategetPhonePref>'
And match $.consent.SMS == '<updategetSMSPref>'
Examples:
|entity | updategetPhonePref|updategetSMSPref|
|xyz| #(updategetPhonePref)|#(updategetSMSPref)|
If i want to store the JSON request in a JSON file rather than in the feature file, what should be my JSON file?
In the JSON use embedded expressions, e.g.
entity: '#(entity)'
Then you can read it from a file:
* def mpRequestJson = read('my.json')
But before the read you should initialize variables that have to be substituted. So you will have some extra lines.
* def entity = '<entity>'
One way to reduce the extra lines is to create a temp JSON:
* def data = { entity: '<entity'>, phone: '<updategetPhonePref>' }
And then you can do this in the JSON:
entity: '#(data.entity)'
Read the docs on data driven tests also please.

Matching values from response to values from DB

My response looks as follows :
{
"data":[
{
"foo":bar1
"user_email":"user#user.com",
"user_id":1
},
{
"foo":bar2
"user_email":"user#user.com",
"user_id":1
}
]
}
* def DBOutput = #fetching values from DB
* match response.data[*].foo contains [DBOutput1[0][0],DBOutput1[1][0]]
DBOutput1 has data as follows : [["bar1"],["bar2"]]
This match fails, for some reasons value passed into the expected list in match statement is DBOutput1[0][0]
This is the error I am getting actual: ["bar1","bar2"], expected: 'DBOutput1[0][0]',
You have some seriously malformed JSON in your example above. The below snippet works, just paste it into a new Scenario:
* def response =
"""
{
"data":[
{
"foo": "bar1",
"user_email":"user#user.com",
"user_id":1
},
{
"foo": "bar2",
"user_email":"user#user.com",
"user_id":1
}
]
}
"""
* match response.data[*].foo contains ['bar1', 'bar2']
Now it is up to you to fix your test, without knowing what your DBOutput is no one can help further.
I iterated over the DBoutput and stored them in a new array list. I then matched the response to the list and it worked.
match response.data[*].foo contains ListFromDB