Cucumber Tags with Selenium

Most of the time, In cucumber projects, there will be many scenarios in single features files. We should be creating feature files based on the application feature or based on the functionality.

We try to keep all the related scenarios within the same feature file, and this is one of the reasons why we end up having more scenarios in the cucumber feature file.

For Example, you have got many different feature files that cover all the different functionalities of the application. Now there can be a particular situation in the project where you like to execute just a SmokeTests or Sanity or maybe Nightly Regressions to ensure nothing got broken, but at the same, you might not be having all these in the same file.

If you remember, we had a similar situation with TestNG test cases; there we took the help of TestNG Groups. In cucumber, we have a similar feature called Tags to group the features.

Tag starts with "@", followed by tag names like sanity test or smoke test or anything you wish, our tag will look like @SanityTests just above the scenario keyword.

One scenario can have more than one tag separated by space

@SanityTests
Scenario: Search Google for Chercher Tech
  Given There is opened "Chrome browser"
  Then I search "Chercher Tech" in searchbar

@SanityTests @Regression
Scenario: Search Bing for Chercher Tech
  Given There is opened "Chrome browser"
  Then I search "Chercher Tech" in searchbar

Now we have to specify the tag name which wants to run in the cucumber runner using tags = {"@SanityTests"} in CucumberOptions

package runner;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features= "features",
				glue= {"testDefinitions"},
				tags = {"SanityTests"})
public class TestRunner {

}

Combining tags Using AND & OR :

Sometimes you might need to run more than one tag at a time; in such cases, you can use AND & OR to combine the cucumber tags to run the feature files.

OR or Comma: Runs the scenario if it has at least one give tag, there are separated with comma, all the tags will be included in one double quote like {"Sanity, smoke, regression"}

@RunWith(Cucumber.class)
@CucumberOptions(features= "features",
				glue= {"testDefinitions"},
				tags = {"SanityTests, SmokeTests"})
public class TestRunner {

}

AND or Quotes: Runs the scenario if it has all the given tags, all the tags are separated with double quotes {"Sanity", "smoke", "regression"}

@RunWith(Cucumber.class)
@CucumberOptions(features= "features",
				glue= {"testDefinitions"},
				tags = {"SanityTests", "SmokeTests"})
public class TestRunner {

}

How to Ignore Cucumber Tests :

Sometimes you might need to skip tags in cucumber BDD, and you can use a special Character ~ to skip the tags. This also works both for Scenarios and Features; this can also work along with AND or OR.

@RunWith(Cucumber.class)
@CucumberOptions(features= "features",
				glue= {"testDefinitions"},
				tags = {"SanityTests", "~SmokeTests"})
public class TestRunner {

}

You make all the non tagged scenarios to run by disabling the tagged scenarios using ~ will all tags in Runner.

Dropdown values are sorted or not in selenium

Hooks in Cucumber

Hooks allow us to perform actions at various points in the cucumber test cycle.

@Before hooks will be run before the first step of each scenario. They will run in the same order of which they are registered.

@After hooks will be run after the last step of each scenario, even when there are failing, undefined, pending, or skipped steps. They will run in the opposite order of which they are registered.

Cucumber supports only two hooks (Before & After), which works at the start and the end of the test scenario.

When using hooks :

You can use hooks to run before/after each scenario, a group of scenarios according to the tags, all the scenarios in a feature, or all the scenarios of your project. They will run before the first step of your scenario, like the background, but it won’t need any step in your feature file.

You just need to define hooks, no need to associate the hooks, and cucumber takes care of associating. I have Hook file in steps definition folder

Consider below cucumber feature file.

Feature: Sample test
  Search Chercher Tech in Google and click the first result

	Scenario: Search Google for ChercherTech
	  Given There is opened Google
	  Then I search ChercherTech in searchbar

Hooke file containing @Before and @After

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {

	@Before
    public void beforeScenario(){
        System.out.println("*************Before Scenario***********");
    }

	@After
    public void afterScenario(){
        System.out.println("############After Scenario##########");
    }
}

Steps definition file

public class Steps_Sample {
	WebDriver driver;

	@Given("^There is opened Google$")
	public void there_is_opened_Google() throws Throwable {
		System.setProperty("webdriver.chrome.driver", "D:Eclipse progsdriverserverchromedriver.exe");
		driver = new ChromeDriver();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		driver.get("https://google.com");
	}

	@Then("^I search ChercherTech in searchbar$")
	public void i_search_ChercherTech_in_searchbar() throws Throwable {
	    driver.findElement(By.name("q")).sendKeys("CherCherTech");
	}
}

No change in Test Runner file

After hook is that even the scenario fails, after hook will execute for sure. hooks-selenium-cucumber-bdd

Tagged Hooks in Cucumber :

Tagged Hooks are much like the scenario hooks, but the only difference is that they are executed before and after the specified tag.

Let me put it in a simple way, Consider you have 10 different tags like sanity, Regression, Smoke tests, sometime you might want to check them with different URLs, or you may want to perform some special operation based on the tag, you can achieve such kind of things through the Tagged Hooks.

These Tagged hooks will be very specific to the particular tags, so these are not common for all scenarios.

So basically, they can also be run in the following two ways:

  • Before ('tagName')
  • After ('tagName')

Let's write Feature file which has three scenarios with tags called @Sanity, @Smoke, @Regression respectively

Feature: Sample Cucumber JVM BDD test
  Search Chercher Tech in Google and click first result

	@Sanity
	Scenario: Search Google for Chercher Tech
	  Given Google is printed

	@Smoke
	Scenario: Search Bing for Chercher Tech
	  Given Bing is printed

	@Regression
	Scenario: Search DuckDuckGo for Chercher Tech
	  Given DuckDuckGo is printed

Step definition file would look like

public class Steps_Sample {
	@Given("^Google is printed$")
	public void google_is_printed() throws Throwable {
	    System.out.println("Google");
	}

	@Given("^Bing is printed$")
	public void bing_is_printed() throws Throwable {
		System.out.println("Bing");
	}

	@Given("^DuckDuckGo is printed$")
	public void duckduckgo_is_printed() throws Throwable {
		System.out.println("DuckDuckGo");
	}
}

Hooks file name Hooks.java

package testDefinitions;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {

	@Before
    public void beforeScenario(){
        System.out.println("*************Before Scenario***********");
    }
	@After
    public void afterScenario(){
        System.out.println("############After Scenario##########");
    }
	@Before("@Sanity")
    public void beforeGoogle(){
        System.out.println("*******before Google*******");
    }
	@Before("@Smoke")
    public void beforeBing(){
        System.out.println("*********before Bing*******");
    }
	@Before("@Regression")
    public void beforeDuckDuckGO(){
		System.out.println("*********before DuckDuckGO*******");
    }
	@After("@Sanity")
    public void afterGoogle(){
        System.out.println("$$$$$$$$$$$ After Google $$$$$$$$$$");
    }
	@After("@Smoke")
    public void afterBing(){
		System.out.println("$$$$$$$$$$$ After Bing $$$$$$$$$$");
    }
	@After("@Regression")
    public void afterDuckDuckGo(){
        System.out.println("$$$$$$$$$$$ After DuckDuckGo $$$$$$$$$$");
    }
}

There is no change to Test Runner File

Hooks file name Hooks.java

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features= "features",
				glue= {"testDefinitions"})
public class TestRunner {

}

Common Tagged Hooks :

Sometime in your scenarios, there could be common pre and post steps. In such cases, you can combine them in hooks.

the common Hooks file may look like below

package testDefinitions;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {

	@Before("@Sanity, @Smoke")
    public void beforeSanitySmoke(){
        System.out.println("*******before SanitySmoke*******");
    }
	@Before("@Regression")
    public void beforeDuckDuckGO(){
		System.out.println("*********before DuckDuckGO*******");
    }

	@After("@Sanity, @Smoke")
    public void afterSanitySmoke(){
		System.out.println("$$$$$$$$$$$ After SanitySmoke $$$$$$$$$$");
    }
	@After("@Regression")
    public void afterDuckDuckGo(){
        System.out.println("$$$$$$$$$$$ After DuckDuckGo $$$$$$$$$$");
    }
}

Order of execution of hooks :

If you have worked with the TestNG, you might be familiar with the priority of test; basically, priority make the execution order of TestNg script

We can achieve the execution order using the value in the hooks in cucumber; the value parameter decides on sequence cucumber should run the tests.

Set the Order for Cucumber Hooks :
  • @Before(order = intValue) : runs from lowest to highest, means value 0 would run first, and 1 will be after 0.
  • @After(order = intValue) : runs from highest to lowest, means opposite of @Before. Value 1 will run first, and 0 would be after 1.
package utilities;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class Hooks {

	@Before(order=1)
    public void beforeScenarioOne(){
        System.out.println("****** beforeScenarioOne *******");
    }
	@Before(order=0)
    public void beforeScenarioTwo(){
        System.out.println("****** beforeScenarioTwo *******");
    }

	@After(order=0)
    public void afterScenarioOne(){
        System.out.println("****** afterScenarioOne *******");
    }
	@After(order=1)
    public void afterScenarioTwo(){
        System.out.println("****** afterScenarioTwo *******");
    }
}

Parameterize Cucumber BDD with selenium

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions