Karate - How to use retry until when there are 2 different requests in the same scenario - karate

If I send one request in a scenario and use retry until as shown in the syntax below then the retry until works fine:
Scenario Outline: x
Given url 'x'
Then retry until status 200
When method get
Examples:
| productId | postcode |
| 'xxxx' | 'yyyy' |
However, if I then send ANY other request afterwards (to make things simple I will just send exactly the same request)..
Scenario Outline: x
Given url 'x'
Then retry until status 200
When method get
//Send ANY other request here:
When method get
Examples:
| productId | postcode |
| 'xxxx' | 'yyyy' |
Then I see the following error message:
11:59:09.820 [main] WARN com.intuit.karate - retry condition evaluation failed: js failed:
>>>>
01: status 200
<<<<
org.graalvm.polyglot.PolyglotException: SyntaxError: Unnamed:1:7 Expected ; but found 200
status 200
^
How do I use retry until when there is more than one request sent in the scenario?

(1) retry until must come BEFORE each method keyword
(2) The correct syntax = retry until responseStatus == 200
Scenario Outline: x
Given url 'x'
Then retry until responseStatus == 200
When method get
//Send ANY other request here:
Then retry until responseStatus == 200
When method get
Examples:
| productId | postcode |
| 'xxxx' | 'yyyy' |

The retry should always be before the method keyword. Read the docs: https://github.com/karatelabs/karate#retry-until

Related

I want to run Scenario Outline in loop for one of the variable configurable

I have use case in which I am making server name configurable using Scenario outline for get call. But I also want to make another variable like ID configurable. I want using that id it should run for all server name mentioned in Scenario Outline. How can we achieve that?
Example
Scenario Outline: Test one get call
Given url: 'https://' + server+ 'v1/share/12345/profit'
When method get
Then status 200
Examples:
|server|
|server1|
|server2|
|server3|
|server4|
In above example server name, I made it configurable using scenario outline, but I want to make number entered in URL configurable & want that to run for all servers. How I will achieve that?
Just use another variable.
Examples:
| server | id |
| foo | 1 |
| foo | 2 |
| bar | 1 |
| bar | 2 |
And if you want to dynamically generate data using a function, all that is possible. Refer: https://github.com/karatelabs/karate#json-function-data-source

SQL How to flag a given sessionID based on values from another column

Forgive me I'm not massively familiar with SQL to do the below. But would love to learn the process of how to do it if possible.
I only have one table: Table name - SessionTracker
-----------------------------------------------------------------------------------------------------------------------------------
bundleID | sessionId | deviceID | eventType | codeValue
------------------------------------------------------------------------------------------------------------------------------------
com.package.random 3871207406642403679 333333-00000-0000-00000-000000000000000 REQUEST 1
com.package.random 3871207406642403679 333333-00000-0000-00000-000000000000000 EVENT 1
com.package.random 3871207406642403679 333333-00000-0000-00000-000000000000000 RESPONSE 1
com.package.random 3245233406642403679 000000-00000-0000-00000-000000000000000 REQUEST 1
com.package.random 3245233406642403679 000000-00000-0000-00000-000000000000000 EVENT 2
com.package.random 3245233406642403679 000000-00000-0000-00000-000000000000000 RESPONSE 2
com.package.random 871207406643e243433 000000-00000-0000-00000-000000000000000 REQUEST 1
com.package.random2 3243254325454535422 111111-00000-0000-00000-000000000000000 REQUEST 1
com.package.random3 4353453452525252465 222222-00000-0000-00000-000000000000000 REQUEST 1
com.package.random4 3453656456353252345 111111-00000-0000-00000-000000000000000 REQUEST 1
com.package.random5 4567568765745634563 111111-00000-0000-00000-000000000000000 REQUEST 1
I'd like to
Select all the sessions where the codeValue was different within that session.
From the example above:
I want to check is if a session which consists of request, event & response has a different value in one of each. Like the sessionId above (3871207406642403679) the code value is 1 in each so this wouldn't be flagged.
The second sessionId (3245233406642403679) the code value in one of the request, event & response has the code value 2 for event and response, so this would be flagged.
I'm hoping a query in databricks would work, is this possible?
In SQL, you could do this with aggregation and a having clause:
select sessionId
from mytable
group by sessionId
having min(codeValue) <> max(codeValue)
This gives you all sessionIds that have at least two distinct codeValues.

AWS Cloud Watch: Can we use stats twice in a cloud watch query?

I am working on a dashboard query where I want to have a count of all the transactions that took more than a certain amount to complete.
My query is something like:
fields message
| filter kubernetes.namespace_name = 'feature-7355'
| filter message like "INFO"
| filter message like "Metric"
| parse '[*] * [*] * - *' as logLevel, timeStp, threadName, classInfo, logMessage
| parse logMessage 'Header: [*]. Metric: [*]. TimeSpent: [*]. correlationId: [*]' as headers, metric, timeSpent, correlationId
| filter ispresent(correlationId)
| stats sum(timeSpent) as TotalTimeSpentByTransaction by correlationId
| filter TotalTimeSpentByTransaction > 2000
| stats count(timeCorrelationId) as correlationIdCount
When I try to execute this I am getting an error:
mismatched input 'stats' expecting {K_PARSE, K_SEARCH, K_FIELDS, K_DISPLAY, K_FILTER, K_SORT, K_ORDER, K_HEAD, K_LIMIT, K_TAIL}
Is there a way to work this out, Can someone help me resolve this?

how to dynamically set an value in json read from file in Karate

I want to dynamically set value for some elements in JSON(read from a file) using data driven feature of KARATE framework. Here are more details:
request.json -> { wheels : <wheel>, color: '<color>' }
Feature: Read json input from file and iterate over data table values
Background:
* url ''
* def reqJson = read('request.json')
* print reqJson
Scenario Outline: Test file read
# I want to avoid writing below set statements for each element in request
#* set reqJson.wheels = <wheel>
#* set reqJson.color = '<color>'
Given path ''
And request reqJson
When method POST
Then status 200
And match response contains {mode: '<result>'}
Examples:
| wheel | color | result |
| 4 | red | car |
| 2 | any | bicycle |
I am developing automation framework using Karate, my intention is to save sample request in JSON file for a given API and then during execution I want element values to be replaced with the ones given in the table above.I don't want to write set statement for each element either(commented lines above)
P.S.: I tried with calling other feature file using table approach. However, I want to keep one feature file per API, hence want to know if there is any way possible for the above approach
I think you have missed embedded expressions which is simpler than the set keyword in many cases, especially when reading from files.
For example:
request.json -> { wheels : '#(wheels)', color: '#(color)' }
And then this would work:
* def wheels = 4
* def color = 'blue'
* def reqJson = read('request.json')
* match reqJson == { wheels: 4, color: 'blue' }
If you go through the demo examples you will get plenty of other ideas. For example:
* table rows
| wheels | color | result |
| 4 | 'blue' | 'car' |
| 2 | 'red' | 'bike' |
* call read('make-request.feature') rows
And where make-request.feature is:
Given path ''
And request { wheels: '#(wheels)', color: '#(color)' }
When method POST
Then status 200
And match response contains { mode: '#(result)' }

Use random var in behat tests to produce unique usernames

Right now I am creating users using something like the following
Given users:
| name | status | roles |
| kyle | 1 | authenticated user |
| cartman | 1 | admin |
Is there a possibility to add random strings in these names?
If I didn't misunderstand, you can do this instead.
Gherkin
Scenario: Create random users
Given I create "3" users
FeatureContext
var $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var $status = [0, 1];
var $roles = ['authenticated user', 'admin', 'superman'];
/**
* #Given /^I create "([^"]*)" users$/
*/
public function createDummyUsers($count)
{
for ($i = 0; $i < $count; $i++) {
$name = substr(str_shuffle($this->str), 0, 8);
$status = $this->status[array_rand($this->status, 1)];
$role = $this->roles[array_rand($this->roles, 1)];
echo "You've just created $name - $status -$role" . PHP_EOL;
}
}
Prints
You've just created mqBWAQJK - 1 - superman
You've just created WYuAZSco - 0 - admin
You've just created HCNWvVth - 1 - admin
You've just created EmLkVRpO - 1 -superman
You've just created pxWcsuPl - 1 -authenticated user
You've just created mLYrlKdz - 0 -superman
The RandomContext functionality from drupal/drupal-extension allows for usage like this:
Given I fill in "E-mail address" with "<?username>#example.org"
or
Given users:
| name | email | status | roles |
| <?standard> | <?standard>#example.org | 1 | authenticated |
| <?admin> | <?admin>#example.org | 1 | admin |
Each token (eg <?username>, <?firstname>) used in a feature will be randomly transformed with a (random string) value for that feature execution. This is implemented with the use of Behat's #Transform functionality, meaning that your tokens will be substituted before execution of that step - so it works to generate random inputs anywhere you might need to use random input as part of your feature.
You can reference the same token later in your feature, eg to verify that the random value input earlier has been returned correctly, and the randomly generated value will be recalled. So, the first and second usages of <?admin> in the example above will both be replaced by the same generated value.
If you are using drupal/drupal-extension then this can be enabled by adding Drupal\DrupalExtension\Context\RandomContext to the enabled contexts in your behat.yml.
If you aren't using Drupal, then the source linked above will demonstrate how you could implement the same for your own usage.
I've created a solution on that you can try.
https://github.com/JordiGiros/MinkFieldRandomizer
MinkFieldRandomizer is a random (with sense) information generator for filling browser form fields in Behat Mink Selenium tests. It brings the option to run your tests in a more realistic way changing the information you use to fill in the forms in every test you run.
You can easily add it to your project by Composer.
One example:
Then Fills in form fields with provided table
| "f_outbound_accommodation_name" | "{RandomName(10)}" |
| "f_outbound_accommodation_phone_number" | "{RandomPhone(9)}" |
| "f_outbound_accommodation_address_1" | "{RandomText(10)}" |
I hope you try it!
And you're welcome to add new functionalities or fork it or do wathever you want.
Cheers