Fetching few elements using "$.[:2]" operator throws error in karate. might be a bug - karate

Example:
Scenario: test
* def response =
"""
[
"YEN01",
"DP258",
"SA661",
"BT202",
"UR809"
]
"""
* def subset = response.[:2]
* print subset
I tried response..[:2] . and also tried with enclosing in ().
Let me know if any one got this working.

Just adding one character will fix your problem !
* def subset = $response.[:2]
Karate defaults to JavaScript and when you want JsonPath evaluation you need to give a little hint to Karate. This is explained in the docs: https://github.com/intuit/karate#get-short-cut

Related

Karate : How to refer or read variable in Examples section which is defined in Scenario Outline

In karate framework, I am trying refer variable in Examples section which is defined in Scenario Outline. Below is the code snippet of feature file.
Scenario Outline:
* print __row
* def data = read('test.csv')
* def selected = 'TRUE'
* def fun = function(x){ return x.Status == selected }
* def filtered = karate.filter(data, fun)
* print filtered
Examples:
| filtered |
After I execute this, getting below error.
*js failed:
org.graalvm.polyglot.PolyglotException: ReferenceError: "filtered" is not defined*
Can any one please let me know how this can be achieved?
The Scenario Outline is the last thing to take control so you need to understand the flow. Please refer to this answer: https://stackoverflow.com/a/75155712/143475
Maybe you should get a normal Scenario Outline to work before trying advanced things. Take some time to read the documentation: https://github.com/karatelabs/karate#data-driven-tests

How do use fuzzy matching validation for either a non-present key or an empty array?

In karate version 0.9.6 I used the following match statement in a .feature file and it worked for validating the value to be an empty array or a key that was not present.
def example = {}
match example.errors == '##[0]'
In 1.0 the documentation example suggests that this should check for the key being present and null or an empty array and testing this fails with a validation error that the value is not present.
From https://karatelabs.github.io/karate/#schema-validation
# should be null or an array of strings
* match foo == '##[] #string'
This appears to be an undocumented breaking change from pre-1.0 to 1.0.
My question is: how do I construct a validator to cover this case correctly when the key is allowed to be absent but if it is present it must be an empty array?
I've found an undesirable solution for now but am leaving this open in case someone has a better answer.
I'm validating the entire parent object with a minimal schema:
Replace
match $.errors == '##[0]'
With
* match $ == { data: '#object', extensions: '##object', errors: '##[0]' }
While more brittle and verbose it is technically working.
This indeed looks like an in-intended breaking change. Here is another workaround:
* def example = {}
* def expected = example.errors ? '#[0]' : '#notpresent'
* match example.errors == expected
I see you have opened an issue here: https://github.com/karatelabs/karate/issues/1825
EDIT: this might be an improvement over the workaround you came up with in your answer:
* match example contains { errors: '##[0]' }

Remove elements from a list in karate?

after using scripAll() to get list of style attribute values, I need to eliminate a few. Wanted to know if there is something like remove() in python which can be used for the same.
Example:
* def list_colors = ["rgb(245,60,86)", "rgb(245,60,86)", "rgb(245,00,00)", "rgb(245,00,00)" ]
Want to remove rgb(245,00,00) from the list. How can I do this in karate?
Thanks
I think you missed that scriptAll() can take a third "filter function" argument, please refer the docs: https://github.com/intuit/karate/tree/master/karate-core#scriptall-with-filter
* def list_colors = scriptAll('.my-css', "_.style['display']", x => !x.includes('245,00,00'))
Otherwise please refer JSON transforms: https://github.com/intuit/karate#json-transforms
* def filtered = karate.map(list_colors, x => !x.includes('245,00,00'))

How to properly create and use dynamic Xpath in JSON (Page Object Model) - Karate DSL

For example, I have this sample JSON object in pages folder which contains all the XPaths for specific page.
{
"pageTitle1": "//*[#class='page-title' and text()='text1']",
"pageTitle2": "//*[#class='page-title' and text()='text2']",
"pageTitle_x" : "//*[#class='page-title' and text()='%s']"
}
* def pageHome = read('classpath:/pages/pageHome.json')
* click(pageHome.pageTitle_x) <-- how to properly replace %s in the string?
Update: I tried the replace function, not sure if this is the proper way.
* click(pageHome.pageTitle_x.replace("%s","new value"))
First a bit of advice. Trying to be "too clever" like this causes maintainability problems in the long run. I have said a lot about this here, please read it: https://stackoverflow.com/a/54126724/143475
That said, you can write re-usable JS functions that will do all these things:
* def pageTitle = function(x){ return "//*[#class='page-title' and text()='" + x "']" }
Now using that you can do this:
* click(pageTitle('foo'))
If you redesign the function even this may be possible:
* click(pageTitle(pageHome.pageTitle_x, 'foo'))
But see how things become more complicated and less readable. The choice is yours. Note that anything you can do in JS (e.g. String.replace()) will be possible, it is up to you and your creativity.

Karate - get all specific field values from a response

On karate 0.6.0, the following code returned an array with all the ids:
def get = call read('wishlist-products-get.feature') id
def wishlist = get.response.wishlist_products
ids = wishlist[*].product_info.id
now on version 0.9.0 the same returns the following error:
wishlist[*].product_info.id, :1:9 Expected an operand but found *
Can someone tell me what change?
Thanks!
You must use the get keyword to save the results of a JsonPath expression as described in the docs.
* def ids = get wishlist[*].product_info.id