How to handle dynamic step in cucumber without AfterStep hook? - java

I am currently using cucumber(info.cukes)-Selenium to run automation test.
Now, I have a situation where a specific step can occur at any point of the flow.
So, I have to design a cucumber scenario to verify the dynamic page in every step.
How I can implement this without AfterStep hook? (cucumber(info.cukes) won't support AfterStep hook)
Example:
Scenario: Complect the order.
Given: Open URL with chrome browser
When: Login with correct ID and password
Then: Complect the details on step 1
And: Complect the details on step 2
And: Complect the details on step 3
My application has a dynamic page which can appear between any pages, so I need to check if the page is displayed or not in every step and the execute the specifc task when the dynamic page is displayed and then move to the next step in the scenario.
Could you please someone help me to achieve this scenario with cucumber Selenium automation.
Thanks for your help.

When it comes to keeping end-to-end test code DRY, page objects are almost always the answer (or at least, they're a great place to start). Even if you had the AfterStep hook, I'd caution about adding too much implicit stuff there, it can be a real headache to follow the flow and debug, especially for others.
In your case, I could imagine a page object for the three pages in the workflow, and each one has a clickSubmit() method that checks for the URL of the mystery page and completes it if present. Something like
public void clickSubmit() {
click(By.className("submitButton"));
if (driver.getCurrentUrl().contains("mysterypage")) {
MysteryPage mysteryPage = new MysteryPage(driver);
mysteryPage.completeForm();
mysteryPage.clickSumbit();
}
}
Admittedly, its a little strange for a method called clickSubmit to be doing all that, so maybe it would be better for a helper method to exist up in the test, and just be called at the end of each step.
As an afterthought, if you have real business rules around when and where this intermediate page shows up, and it's not just random, it may be worth capturing in the gherkin. If the user really cares that it shows up here and not there, but you made the gherkin blind to its appearance so it always "just works", you could be masking off a bug.

Related

Karate framework: how to reuse variable used in one sceario to be called in another without declaring it as global variables [duplicate]

Does Karate supports a feature where you can define a variable in a scenario and reuse it in other scenarios in the same feature file. I tried doing the same but get an error. What's the best way to reuse the variables within the same feature file ?
Scenario: Get the request Id
* url baseUrl
Given path 'eam'
When method get
Then status 200
And def reqId = response.teams[0]resourceRequestId
Scenario: Use the above generated Id
* url baseUrl
* print 'From the previous Scenario: ' + reqId
Error:
Caused by: javax.script.ScriptException: ReferenceError: "reqId" is not defined in <eval> at line number 1
Use a Background: section. Here is an example.
EDIT: the variable if in the Background: will be re-initialized for every scenario which is standard testing framework "set up" behavior. You can use hooks such as callonce - if you want the initialization to happen only once.
If you are trying to modify a variable in one scenario and expect it to be now having that modified value when the next Scenario starts, you have misunderstood the concept of a Scenario. Just combine your steps into one Scenario, because think about it: that is the "flow" you are trying to test.
Each Scenario should be able to run stand-alone. In the future the execution order of Scenario-s could even be random or run in parallel.
Another way to explain this is - if you comment out one Scenario other ones should continue to work.
Please don't think of the Scenario as a way to "document" the important parts of your test. You can always use comments (e.g. # foo bar). Some teams assume that each HTTP "end point" should live in a separate Scenario - but this is absolutely not recommended. Look at the Hello World example itself, it deliberately shows 2 calls, a POST and a GET !
You can easily re-use code using call so you should not be worrying about whether code-duplication will be an issue.
Also - it is fine to have some code duplication, if it makes the flow easier to read. See this answer for details - and also read this article by Google.
EDIT: if you would like to read another answer that answers a similar question: https://stackoverflow.com/a/59433600/143475

Java Cucumber: creating scenario outlines with dynamic examples

We have a test where basically we need to input a specific value in a web site and make sure another value comes out. The data of the input-output for this is stored in an XML file.
Now we can create a single Scenario that runs once and loops through, submitting each value however we run into some reporting problems, if 2 out of 100 pairs fail we want to know which ones and not just have an assertion error for the whole scenario.
We would get much clearer reporting using a Scenario Outline where all the values are in the examples table. then the scenario itself runs repeatedly and we can fail an individual set as an assertion error and have that kick back clearly in a report.
Problem: we do not want to hard code all the values from the xml into the .feature. it's noisy but also if the values change it's slow to update. we would rather just provide the XML parse it and go, if things change we just drop in an updated XML.
Is there a way to create dynamic examples where we can run the scenario repeatedly, one for each data case, without explicitly defining it in the examples table ?
Using Cucumber for this is a bad idea. You should test this functionality lower down your stack with a unit test.
At some point in your code, after the user has input their value, the value will be passed to a method/function that will return your answer. This is the place to do this sort of testing.
A cucumber test going through the whole stack will upwards of 3 orders of magnitude slower than a well written unit tests. So you could test thousands of pairs of values in your unit test in the time it takes to run one single cuke.
If you do this sort of testing in Cucumber you will quickly end up with a test suite that takes far too long to run, or that can only be run quickly at great expense. This is very damaging to a project.
Cuking should be about one happy path (The user can enter a value and see the result) and maybe a sad path (the user enters a bad value and sees an error/explanation). Anything else needs to be pushed down to unit tests.
The NoraUi framework does exactly what you want to do in your project. The NoraUi code is open source. If you have questions about this framework, you can post an issue with the tag "Question"

how to pass the data(from Examples) of one feature file to other feature file?

When I first execute a feature file , am updating the fields of it during run time. The same field's value is required to pass to other feature file. Is it possible to pass the data of one feature file to another feature file using java?
feature file 1:
scenario outline: test xxx functionality
Examples :
|user|password|
|abc|pass|
feature file2:
Scenario Outline : test yyy functionality
Examples:
|user|password|
| | |
Here, I want the data that is there in the feature file1 to be passed to feature file 2 i.e, abc and pass should be copied to Examples of feature file 2.
Please do suggest.Thanks in advance!!
Passing values from one feature file to another is not supported. It would force you to execute your scenarios in a specific order. That is a well known anti pattern. Your scenarios should be possible to execute in any order and that is not possible if you expect one scenario to be executed before another.
So how should you be able to reuse your setup from the first feature file in the second? The short answer is don’t. Instead implement a helper that the features that need the user to be setup can use to prepare the system under test. Call this helper from each scenario that need this setup before it’s execution. This may sound as a lot of unnecessary work, but it will save you from a lot of problems with scenarios that depends on each other and leaves your system in unexpected states between executions.
Strictly speaking, you should not be passing data from one BDD test to another. This would defeat the purpose of having an independent unit BDD test. In general, software unit tests are supposed to be independent of one another.
That being said, you can certainly persist some state from one step definition and then reuse it another one:
#When("^I login with username \"(.*)\"$")
public void enterUsername(String username) {
// do something with username
// make a database call and insert the username in a temporary table
}
Then, in the second feature file you can query the same table and retrieve the username.
This may not be exactly what you have in mind, but the general idea is just to persist some state during the first test, which can then be used in a second test.

a single method to check if a web element is covered or not

I am using Selenium and Java to write a test. I use ExpectedConditions.elementToBeClickable to click on web elements, but sometimes they are covered by others and as you know ExpectedConditions.elementToBeClickable only checks if the element is enabled and visible, so is there any method to check if it's covered or not?
by the way I do not want to use codes like:
try{
//click on the element
}
catch(Exception e)
{//it's covered
}
I am looking for something like:
blabla.isCovered();
because sometimes for example I want to check of a whole window is covered or not.
If you don't want to use that sort of code, perhaps you should add additional logic to your checkifClickable method than just enabled and visible. Although, I am betting your real question is more along the lines of "How can I check for these conditions prohibiting me from clicking that may be not be apparent from information provided by the DOM".
This is something that makes Automation more difficult than people realize, because you must have detailed knowledge of the site. Is it an element that pops up due to logic or a condition? Then the solution is to close it. Is it a resolution of rendering issue? Then resize window. There is no real cure-all method, you have to tweak the automation logic to suit the site you are working for.
Are you not wanting to click at all and know previously?
If you specifically just don't want to use Try, then implement an assertion that a property changed after you clicked and then set a bool.

Jbehave: I could get an example of Jbehave running and I have few questions on this.

Here is the example that I could get working. http://ivanz.com/2011/05/25/java-bdd-with-jbehave-and-watij-in-eclipse-with-junit/
Questions:
This example has one story. If i need to have more than one story,
Can i write it in the same file or should I create a new .story file
for every story that I have?
One story can have more than one scenarios, how to handle this kind of scenario
Please help...
Generally speaking, a story contains one or more scenarios about a specific behaviour/feature of the software.
For example, a "Login Story" handles all cases of a user trying to log in, with valid data, expired accounts, already logged in, and so forth. Trying to cover the logout feature is, pun intended, a different story.
Hence, by convention, one story file contains only the scenarios of one story. The framework does not limit you to put in the logout scenarios into the same story file handling the login scenarios, but there's only one block of narrative available.
It furthermore allows you to separate the corresponding steps better; e.g. the necessary binding steps for logout do not need to be available during the login story.
As for adding further scenarios into a story file, simply separate them with a new line and start with the "Scenario: " keyword.
e.g.:
Scenario: Successfull login
Given ...
When ...
Then ...
Scenario: Login with no password
Given ...

Categories

Resources