Browser Automation

Cucumber is not a browser automation tool, but it works well with the following browser automation tools.

Selenium WebDriver 🔗︎

WebDriver is designed to provide a simpler, more concise programming interface in addition to addressing some limitations in the Selenium-RC API. Selenium-WebDriver was developed to better support dynamic web pages where elements of a page may change without the page itself being reloaded. WebDriver’s goal is to supply a well-designed object-oriented API that provides improved support for modern advanced web-app testing problems.

Selenium-WebDriver can be used in multiple programming languages, including Java, JavaScript, Ruby and Kotlin.

Let us look at an example of Cucumber using Selenium-WebDriver in UI testing, by converting the Selenium-Web driver by example.

We can express the example as the following scenario:

Scenario: Finding some cheese
   Given I am on the Google search page
   When I search for "Cheese!"
   Then the page title should start with "cheese"
package class.example;

import cucumber.api.java.After;
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.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class ExampleSteps {

    private final WebDriver driver = new FirefoxDriver();
    @Given("^I am on the Google search page$")
    public void I_visit_google() {
    driver.get("https:\\www.google.com");
   }

   @When("^I search for \"(.*)\"$")
     public void search_for(String query) {
        WebElement element = driver.findElement(By.name("q"));
        // Enter something to search for
        element.sendKeys(query);
        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();
   }

   @Then("^the page title should start with \"(.*)\"$")
   public void checkTitle(String titleStartsWith) {
       // Google's search is rendered dynamically with JavaScript
       // Wait for the page to load timeout after ten seconds
       new WebDriverWait(driver,10L).until(new ExpectedCondition<Boolean>() {
           public Boolean apply(WebDriver d) {
               return d.getTitle().toLowerCase().startsWith(titleStartsWith);
           }
       });
    }

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

import cucumber.api.Scenario
import cucumber.api.java8.En
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.WebDriverWait

class ExampleSteps: En {

    lateinit var driver: WebDriver

    init {
        Given("^I am on the Google search page$") {
            driver.get("https:\\www.google.com")
        }

        When("^I search for \"(.*)\"$") { query: String ->
            val element: WebElement = driver.findElement(By.name("q"));
            // Enter something to search for
            element.sendKeys(query)
            // Now submit the form. WebDriver will find the form for us from the element
            element.submit()
        }

        Then("^the page title should start with \"(.*)\"$") { titleStartsWith: String ->
            // Google's search is rendered dynamically with JavaScript
            // Wait for the page to load timeout after ten seconds
            WebDriverWait(driver, 10L).until { d ->
                d.title.toLowerCase().startsWith(titleStartsWith)
            }
        }

        After { scenario: Scenario ->
            driver.quit()
        }
    }
}
var driver = new webdriver.Builder().build();
driver.get('http://www.google.com');

var element = driver.findElement(webdriver.By.name('q'));
element.sendKeys('Cheese!');
element.submit();

driver.getTitle().then(function(title) {
  console.log('Page title is: ' + title);
});

driver.wait(function() {
  return driver.getTitle().then(function(title) {
    return title.toLowerCase().lastIndexOf('cheese!', 0) === 0;
  });
}, 3000);

driver.getTitle().then(function(title) {
  console.log('Page title is: ' + title);
});

driver.quit();
require 'rubygems'
require 'selenium-webdriver'

Given(/^I am on the Google search page$/) do
  driver = Selenium::WebDriver.for :firefox
  driver.get "http://google.com"
end

When(/^I search for "([^"]*)"$/) do
  element = driver.find_element(name: "q")
  element.send_keys "Cheese!"
  element.submit
end

Then(/^the page title should start with "([^"]*)"$/) do
  wait = Selenium::WebDriver::Wait.new(timeout: 10)
  wait.until { driver.title.downcase.start_with? "cheese!" }
  puts "Page title is #{driver.title}"
    browser.close
end

More information on Selenium Webdriver.

Browser Automation Tools for JVM 🔗︎

Serenity BDD 🔗︎

Browser Automation Tools for Ruby 🔗︎

Watir 🔗︎

Capybara 🔗︎

Tips and Tricks 🔗︎

Screenshot on failure 🔗︎

Taking a screenshot when a scenario fails, might help you to figure out what went wrong. To take a screenshot on failure, you can configure an after hook.

if (scenario.isFailed()) {
    byte[] screenshot = webDriver.getScreenshotAs(OutputType.BYTES);
    scenario.embed(screenshot, "image/png");
}
if (scenario.isFailed()) {
    val screenshot = webDriver.getScreenshotAs(OutputType.BYTES)
    scenario.embed(screenshot, "image/png")
}
After(function (scenario) {
    if (scenario.result.status === Status.FAILED) {
        var world = this;
        return webDriver.takeScreenshot().then(function(screenShot, error) {
            if (!error) {
                world.attach(screenShot, "image/png");
            }
        });
    }
});
# Available scenario methods: #failed?, #passed?, and #exception
if scenario.failed?
  path = "html-report/#{scenario.__id__}.html"
  page.driver.browser.save_screenshot(path)
  embed(path, "image/png")
end

Multiple Browsers 🔗︎

Cucumber can run your scenarios with different browsers, based on a configuration property loaded at runtime:

Capybara.register_driver :selenium do |app|
  browser = (ENV['browser'] || 'firefox').to_sym
  Capybara::Selenium::Driver.new(app, browser: browser)
end
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebDriverFactory {
    public static WebDriver createWebDriver() {
        String webdriver = System.getProperty("browser", "firefox");
        switch(webdriver) {
            case "firefox":
                return new FirefoxDriver();
            case "chrome":
                return new ChromeDriver();
            default:
                throw new RuntimeException("Unsupported webdriver: " + webdriver);
        }
    }
}
// TODO: Convert Java example to Kotlin

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebDriverFactory {
    public static WebDriver createWebDriver() {
        String webdriver = System.getProperty("browser", "firefox");
        switch(webdriver) {
            case "firefox":
                return new FirefoxDriver();
            case "chrome":
                return new ChromeDriver();
            default:
                throw new RuntimeException("Unsupported webdriver: " + webdriver);
        }
    }
}
// TODO

Then, define the browser property when you run Cucumber:

browser=chrome cucumber

Example Projects 🔗︎


You can help us improve this documentation. Edit this page.