How to get the value of JSON element having # in the name in Karate [duplicate] - karate

This question already has an answer here:
Get json value with hyphen from response
(1 answer)
Closed 1 year ago.
This is my json response
{
"meta": {
"type": "event-search",
"#href": "https://<ip>:<port>/SentinelRESTServices/objects/event-search/10c21c52229bfe0545BD7802A74E10398534005056869AAA"
}
}
I want to get the value for #href.
When i print meta.type I am able to get the value 'event-search', but same doesn't work for #href.
I tried to escape it using \\ (meta.\\#href) but i got empty value.
Is there a way to escape # and fetch the value?
Please help!!

Please use the square-bracket JS approach to extract nested properties when there are special characters in the key-names.
Example:
* def response = { meta: { '#href': 'foo' } }
* match response.meta['#href'] == 'foo'

Related

How to add variable in multiline string in Karate? [duplicate]

This question already has an answer here:
Karate print json with embedded expression in it
(1 answer)
Closed 1 year ago.
Trying to use variable in multiline string but without success. May you please give me some hint how to do that? Thank you.
* def LocalDateTime = Java.type('java.time.LocalDateTime')
* def createDate = LocalDateTime.now()
And request
"""
{
"id": 444444,
"date": "#createdDate",
...
Read the docs: https://github.com/karatelabs/karate#embedded-expressions
It should be:
And request
"""
{
"id": 444444,
"date": "#(createdDate)"
}
"""

Karate API Converting String from JSON Response into UPPERCASE [duplicate]

This question already has an answer here:
How to extract value in double quotes from a response header in karate
(1 answer)
Closed 1 year ago.
JSON Response has __typename in the response.
I am defining and storing it so I can use this in the next graphQL Request
def contentType1 = response.data.getPublicList.items[0].__typename
__typename comes back as "Movie"
The next Request requires "Movie" to be "MOVIE"
query {
getContentById(id: "", contentType: "MOVIE") {
Is there a way I can convert/define the entire string value as UPPERCASE?
That should be easy, behind the scenes it is a "Java" string, so there are methods you can use:
* def contentType1 = 'Movie'
* def after = contentType1.toUpperCase()
* match after == 'MOVIE'
EDIT: If you want to convert "in place", just do JS-style operations:
* def data = { foo: 'bar' }
* data.foo = data.foo.toUpperCase()
* match data == { foo: 'BAR' }
If you need more sophistication, please look at the docs for JSON transforms: https://github.com/karatelabs/karate#json-transforms

Replace Json key in Karate [duplicate]

This question already has an answer here:
Karate API function/keyword to substitute JSON placeholder key with argument passed
(1 answer)
Closed 1 year ago.
I need to send a Json to an endpoint but I need to replace a key with a variable.
I've this code
.....
* def idJson = response.id
Given path <mypath>
And headers {Authorization: '#(auth)'}
And request read('classpath:myjson.json')
.....
The myjson.json file is
{
"a":
{
...
"b":false,
"c":true
},
"d":
{
'#(idJson)':
{
"Key":[
.....
]
}
}
}
But the value is not replace in the json. When I perform the request I see that the json contains the string '#(idJson)' instead of the value of the variable. Any idea about how to solve this?
Thank you
Embedded expressions cannot be used to modify a JSON key. You have to use a JS operation like this:
* def idJson = 'foo'
* def body = {}
* body[idJson] = 'bar'
* url 'https://httpbin.org/anything'
* request body
* method post
* status 200
* match response.json == { foo: 'bar' }
Note that d could be replaced like this so you can still read the file and be dynamic:
{ "d": "#(temp)" }
And temp can be JSON that is defined in your feature before reading the file.
If this is too troublesome, please contribute code :)

Karate - String concatenation of JSON value with a variable [duplicate]

The embedded expressions are not replaced when appended, prepended or surrounded by characters in the following simplified and very basic scenario:
* def jobId = '0001'
* def out =
"""
{
"jobId": "#(jobId)",
"outputMetadata": {
"fileName_OK": "#(jobId)",
"fileName_Fail_1": "some_text_#(jobId)",
"fileName_Fail_2": "#(jobId)-and-some-more-text",
"fileName_Fail_3": "prepend #(jobId) and append"
}
}
"""
* print out
Executing the scenario returns:
{
"jobId": "0001",
"outputMetadata": {
"fileName_OK": "0001",
"fileName_Fail_1": "some_text_#(jobId)",
"fileName_Fail_2": "#(jobId)-and-some-more-text",
"fileName_Fail_3": "prepend #(jobId) and append"
}
}
Is it a feature, a limitation, or a bug? Or, did I miss something?
This is as designed ! You can do this:
"fileName_Fail_2": "#(jobId + '-and-some-more-text')"
Any valid JS expression can be stuffed into an embedded expression, so this is not a limitation. And this works only within JSON string values or when the entire RHS is a string within quotes and keeps the parsing simple. Hope that helps !

Dataweave check if a value is contained within a YAML list

I want to check if the value present in the YAML list.
I have product.yaml
intGrp:
- "A"
- "CD"
- "EF"
- "ABC"
- "CDEF"
From transform message I want to check
If (intGrp contains payload.myvalue) this else that
Tried
%dw 2.0
var prop = Mule::p('intGrp')
output application/json
---
{
a: prop contains ("A")
}
But that doesn't solve my problem. Because I want to do an exact string match. i.e if I give
a: prop contains ("AB") I should get a false as there is no product as "AB".
Any help would be highly appreciated.
Thank you
The problem is that the YAML array is interpreted as a comma separated string in the property. The contains() function works differently in strings than in array. In strings it searches for a matching substring, hence 'AB' returns true. You could convert the string it back to an array using the splitBy() DataWeave function. I'm showing both side by side to highlight the difference:
%dw 2.0
var prop = Mule::p('intGrp')
var propArray = Mule::p('intGrp') splitBy ','
output application/json
---
{
raw: prop,
array: propArray,
a: propArray contains ("A"),
ab: propArray contains ("AB")
}
The output is:
{
"raw": "A,CD,EF,ABC,CDEF",
"array": [
"A",
"CD",
"EF",
"ABC",
"CDEF"
],
"a": true,
"ab": false
}
Note that if any of the entries contains a comma it will be split too.