This is an sample project to demonstrate how to work with Selenium and cucumber for Java
⛳There are still two branches with Cucumber 5 integration and Cucumber selenium with jenkins & Extent reporting also.
Strict: if strict option is set to false then at execution time if cucumber encounters any undefined/pending steps then cucumber does not fail the execution and undefined steps are skipped and BUILD is SUCCESSFUL
and if Strict option is set to true then at execution time if cucumber encounters any undefined/pending steps then cucumber does fails the execution and undefined steps are marked as fail
dryRun : It is used to verify that all steps of the feature file defined on step generator or glue code file or not. Syntax is : dryRun= true
One thing keep in mind that when dryRun=true then entire code should not run only it checks that all the methods matched with feature file or not.
So in case any of the function is missed in the Step Definition for any Step in Feature File, it will give us the message. So If you writing scenarios first and then implementing step definitions then add dryRun = true.
In this example, we will pass the test data using the data table and handle it using Raw() method.
Scenario: Successful Login with Valid Credentials
Given User is on Home Page
When User Navigate to LogIn Page
And User enters Credentials to LogIn
| testuser_1 | Test@153 |
Then Message displayed Login Successfully
The implementation of the above step will belike this:
@When("^User enters Credentials to LogIn$")
public void user_enters_testuser__and_Test(DataTable usercredentials) throws Throwable {
//Write the code to handle Data Table
List<List<String>> data = usercredentials.raw();
//This is to get the first data of the set (First Row + First Column)
driver.findElement(By.id("log")).sendKeys(data.get(0).get(0));
//This is to get the first data of the set (First Row + Second Column)
driver.findElement(By.id("pwd")).sendKeys(data.get(0).get(1));
driver.findElement(By.id("login")).click();
}
Scenario: Successful Login with Valid Credentials
Given User is on Home Page
When User Navigate to LogIn Page
And User enters Credentials to LogIn
| Username | Password |
| testuser_1 | Test@153 |
| testuser_2 | Test@154 |
Then Message displayed Login Successfully
@When("^User enters Credentials to LogIn$")
public void user_enters_testuser_and_Test(DataTable usercredentials) throws Throwable {
//Write the code to handle Data Table
for (Map<String, String> data : usercredentials.asMaps(String.class, String.class)) {
driver.findElement(By.id("log")).sendKeys(data.get("Username"));
driver.findElement(By.id("pwd")).sendKeys(data.get("Password"));
driver.findElement(By.id("login")).click();
}
}
Feature: Login Action
Scenario: Successful Login with Valid Credentials
Given User is on Home Page
When User Navigate to LogIn Page
And User enters "testuser_1" and "Test@123"
Then Message displayed Login Successfully
@When("^User enters \"(.*)\" and \"(.*)\"$")
public void user_enters_UserName_and_Password(String username, String password) throws Throwable {
driver.findElement(By.id("log")).sendKeys(username);
driver.findElement(By.id("pwd")).sendKeys(password);
driver.findElement(By.id("login")).click();
}
Feature: Login Action
Scenario Outline: Successful Login with Valid Credentials
Given User is on Home Page
When User Navigate to LogIn Page
And User enters "<username>" and "<password>"
Then Message displayed Login Successfully
Examples:
| username | password |
| testuser_1 | Test@153 |
| testuser_2 | Test@153 |
@When("^User enters \"(.*)\" and \"(.*)\"$")
public void user_enters_UserName_and_Password(String username, String password) throws Throwable {
driver.findElement(By.id("log")).sendKeys(username);
driver.findElement(By.id("pwd")).sendKeys(password);
}
CucumberRunner class extends AbstractTestNGCucumberTests and CucumberRunner class is specified in testNG.xml file.
Cucumber basics
Integrating cucumber-JVM with TestNG
@CucumberOptions(
format={"pretty","json:path/to/json_repot.json"},
features = "Path_to_features_file",
glue="com.sri.stepDefinition",
tags={"@smoke,@regression")
)
public class TestRunner extends AbstractTestNGCucumberTests{}
Cucumber extent report
Cucumber with Extent report
Scenario scenario
"Feature Name : " + scenario.getId().split(";")[0]
"Scenario Name : " + scenario.getName()
Cucumber tags
Tag the scenarios in your feature files with the desired tags. For example
@smoke
Scenario: Verify login functionality
Given user navigates to the login page
When user enters valid credentials
Then user should be logged in successfully
Create a TestNG XML file where you can specify the tags you want to run. Here's an example
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="CucumberSuite" parallel="methods" thread-count="2">
<test name="SmokeTest">
<classes>
<class name="path.to.TestNGCucumberRunner">
<methods>
<include name="^.*@smoke.*$"/>
</methods>
</class>
</classes>
</test>
</suite>
Tag your feature files with unique identifiers. For example, you can use the @Feature tag in your feature files:
@FeatureLogin
Feature: Login functionality
Scenario: Verify login functionality
Given user navigates to the login page
When user enters valid credentials
Then user should be logged in successfully
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="CucumberSuite" parallel="methods" thread-count="2">
<test name="LoginFeature">
<classes>
<class name="path.to.TestNGCucumberRunner">
<methods>
<include name="Login.feature"/>
</methods>
</class>
</classes>
</test>
</suite>
Update TestNG runner class includes the CucumberOptions annotation with the glue path and the location of your feature files. Ensure the feature path in the runner class matches the specified feature file in the TestNG XML.
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
@CucumberOptions(
features = "src/test/resources/features/Login.feature",
glue = "com.example.steps",
plugin = {"pretty", "html:target/cucumber-reports"}
)
public class TestNGCucumberRunner extends AbstractTestNGCucumberTests {
}
Command line argument to run only the scenarios
mvn test -Dcucumber.filter.tags="@tagname"
Running a specific feature file
How to run specific rows from Cucumber examples
Add a cucumber runner by extending the AbstractTestNGCucumberTests class and overriding the scenarios method in the parallel package (same name as step definition package) in src/test/java folder. Set the parallel option value to true for the DataProvider annotation.
package parallel;
import org.testng.annotations.DataProvider;
import io.cucumber.testng.AbstractTestNGCucumberTests;
public class RunCucumberTest extends AbstractTestNGCucumberTests{
@Override
@DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
}
Add the Maven Surefire plugin configuration to the build section of the POM.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
If you have multiple runners, set the parallel configuration to classes to reduce execution times. In addition the threadCount can be set to to the desired value or useUnlimitedThreads can be set to true.
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>