Acceptance testing with Cucumber and Selenium(Java)

In this post, I am going to show how we can write the acceptance test script with Cucumber and Selenium.

Refer my earlier post for Ruby/Cucumber Acceptance testing with Cucumber and Capybara

My objective is to write an acceptance test which opens up the browser and goes to ‘Yelp’ site and search for a restaurant and validate the results.

Refer the below feature file.
java-cucumber-selenium-test/src/test/resources/yelp/test/yelp.feature



Feature: Search Restaurants

  Scenario: Go to yelp and search for valid restaurant
    Given a user goes to Yelp
    When Search for taco bell
    Then See the List of taco bell Restaurants and confirm results contains Lower Greenville

  Scenario: Go to yelp and search for restaurant
    Given a user goes to Yelp
    When Search for Qboba
    Then See the List of Qboba Restaurants

  Scenario: Go to yelp and search for restaurant
    Given a user goes to Yelp
    When Search for Chipotle
    Then See the List of Chipotle Restaurants

  Scenario: Go to yelp and search for invalid restaurant
    Given a user goes to Yelp
    When Search for hhahsdahsdhasd
    Then See No Results found error message

  Scenario Outline:Go to yelp and search for <searchText>
    Given a user goes to Yelp
    When Search for <searchText>
    Then See the List of  Restaurants
    Examples:
      | searchText               |
      | Scardello                |
      | Roti Grill               |
      | Mughlai Restaurant       |
      | Spice In The City Dallas |


Refer the below Junit test file
java-cucumber-selenium-test/src/test/java/yelp/test/YelpTest.java



package yelp.test;

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

@RunWith(Cucumber.class)
public class YelpTest {
}

Refer the below Step definitions file.

java-cucumber-selenium-test/src/test/java/yelp/test/definitions/YelpStepDefinition.java



package yelp.test.definitions;

import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;

public class YelpStepDefinition {

    protected WebDriver driver;

    @Before
    public void setup() {
        driver = new FirefoxDriver();
        //Loading the driver
        System.setProperty("webdriver.gecko.driver", "/usr/local/bin/geckodriver");
    }

    @Given("^a user goes to Yelp$")
    public void goToYelp() {
        //Get the Yelp home page
        driver.get("https://www.yelp.com/dallas");
    }

    @When("^Search for (.*?)$")
    public void doSearch(String searchTerm) throws InterruptedException {
        WebElement searchDescElement = driver.findElement(By.id("find_desc"));
        searchDescElement.sendKeys(searchTerm);

        WebElement submit = driver.findElement(By.id("header-search-submit"));
        submit.submit();
    }

    @Then("^See the List of (.*?) Restaurants$")
    public void verifyContents(String restaurant) {

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        assertEquals(true, isContentAvailable(restaurant));
    }

    @Then("^See the List of (.*?) Restaurants and confirm results contains (.*?)$")
    public void verifyContentsWithLandmark(String restaurant, String landMark) {
        //Create an Explicit wait to make sure that the page is loaded and driver updates the page data.
        WebDriverWait myWait = new WebDriverWait(driver, 10);
        myWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("yelp_main_body")));
        assertEquals(true, isContentAvailable(restaurant, landMark));
    }

    public boolean isContentAvailable(String... contents) {
        WebElement searchResultsElement = driver.findElement(By.id("yelp_main_body"));
        boolean result = false;
        for (String content : contents) {
            result = searchResultsElement.getText().contains(content);
        }
        return result;
    }

    @Then("^See No Results found error message")
    public void verifyContents() {
        //Create an Explicit wait to make sure that the page is loaded and driver updates the page data.
        WebDriverWait myWait = new WebDriverWait(driver, 10);
        myWait.until(ExpectedConditions.visibilityOfElementLocated(By.id("yelp_main_body")));
        assertEquals(true, driver.getPageSource().contains("No Results"));
    }

    @After
    public void closeBrowser() {
        driver.quit();
    }
}


Follow the below steps to run the test script

1. Download the repository
2. Download the ‘gecko’ driver from https://github.com/mozilla/geckodriver/releases and copy it into ‘/usr/local/bin/’
3. Do ‘mvn clean install’
4. Maven builds the test class and runs it. We can also run the test case(YelpTest.java) from any IDE as normal Junit test case.

Acceptance testing with Cucumber and Capybara

Cucumber is a software testing tool used for defining the acceptance test cases and running it.

Cucumber itself is written in Ruby Programming language. It uses ‘Gherkin’ language to define the test cases and acceptance tests are written in behavior-driven development style.

Please refer the below links to know more about Cucumber(Features, Step Definitions)

https://cucumber.io/

https://en.m.wikipedia.org/wiki/Cucumber_(software)

Capybara is a library used for simulating the user actions. Please refer https://github.com/teamcapybara/capybara to know more about Capybara.

In this article, I am going to show how we can test the “Yelp” website with Cucumber and Capybara.

My objective is to write an acceptance test which opens up a browser and goes to ‘Yelp’ site and search for a restaurant and validate the results.

Here is the Feature file. It’s written in Gherkin language.

Refer the code at https://github.com/dkbalachandar/ruby-cucumber-test

ruby-cucumber-test/features/yelp.feature

@run
Feature: Search Restaurants
  Scenario: Go to yelp and search for valid restaurant
    Given a user goes to Yelp
    When Search for taco bell
    Then See the List of taco bell Restaurants

   Scenario: Go to yelp and search for restaurant
    Given a user goes to Yelp
    When Search for Qboba
    Then See the List of Qboba Restaurants

   Scenario: Go to yelp and search for restaurant
    Given a user goes to Yelp
    When Search for Chipotle
    Then See the List of Chipotle Restaurants
  
  Scenario: Go to yelp and search for invalid restaurant
    Given a user goes to Yelp
    When Search for hhahsdahsdhasd
    Then See No Results found error message

  Scenario Outline:Go to yelp and search for <searchText> 	
    Given a user goes to Yelp
    When Search for <searchText> 	 
    Then See the List of  Restaurants
    Examples:
	    |searchText|
	    |Scardello|
	    |Roti Grill|
	    |Mughlai Restaurant|
	    |Spice In The City Dallas|			


Here is the step definitions file. Its a Ruby file and uses Capybara to simulate the user actions.

ruby-cucumber-test/features/step_definitions/yelp-step.rb


Given(/^a user goes to Yelp$/) do    
  visit "https://www.yelp.com"   
end

When(/^Search for (.*?)$/) do |searchTerm|
  fill_in 'dropperText_Mast', :with => 'Dallas, TX'    
  fill_in 'find_desc', :with => searchTerm
  click_button('submit')
end

Then(/^See the List of (.*?) Restaurants$/) do |searchTerm|  
 expect(page).to have_content(searchTerm)
 expect(page).to have_no_content('No Results')
end

Then(/^See No Results found error message$/) do
 expect(page).to have_content('No Results')
end

This file has all the Env related configurations. I have used ‘Chrome’ as my default browser instead of Firefox. Those configurations can be defined here.

ruby-cucumber-test/features/support/env.rb


require 'capybara/cucumber'
require 'colorize'
require 'rspec'
Capybara.default_driver = :chrome 
Capybara.register_driver :chrome do |app|
   Capybara::Selenium::Driver.new(app, :browser => :chrome)
end

Below is the Gemfile for my program. This file is used for describing gem dependencies for Ruby program.

ruby-cucumber-test/Gemfile


source "https://rubygems.org"

gem "cucumber"
gem "capybara"
gem "selenium-webdriver"
gem "rspec"
gem "chromedriver-helper"

Follow the below steps to run this 


1. Install Bundler (http://bundler.io/): gem install bundler
2. Run bundler: bundle install
3. Start test: cucumber --tag @run

After running the test case, the output will be like below.

cucumber.jpg