Driving Web Behaviour

Selenium is a powerful open-source framework for automated web testing. From 2.x, it offers two APIs: the Selenium API (backwards compatible with Selenium 1.x) and the new WebDriver API. Both APIs are available from the same 2.x dependencies, so JBehave Web Selenium module supports both. When we talk about Selenium, we usually intend the framework, while if we need to distinguish between the APIs we'll specifically refer to the Selenium API and WebDriver API.

Let's see how we can easily use Selenium to run web-based stories. The objective in creating a DSL is to represent the business-domain functionality whilst abstracting away the details of the implementation, in this case the access to the web layer via a specific testing tool, such as Selenium. The same DSL should be re-usable with different testing tools.

As usual, examples speak louder than words:

Scenario: User searches for a single step

Given user is on Home page
When user opens Find Steps page
Then Find Steps page is shown
When user searches for "Given a threshold of 10.0"
Then search returns: "Given a threshold of $threshold"
When user views with methods
Then search returns: "Given a threshold of $threshold,
    [org.jbehave.web.examples.trader.steps.TraderSteps.aThreshold(double)]"
And steps instances include: "TraderSteps,StockExchangeSteps"

The TraderWebSteps class is just like any other JBehave steps class:

The new element here is that we are using Page Objects to abstract the Selenium behaviour behind pages that specify the user interaction in more meaningful ways. The page objects is where the Selenium magic happens. Note that the use of pages have so far enabled us not to commit to a specific API, either Selenium API or WebDriver API.

Configuring JBehave to use Selenium

As always, we configure JBehave to several different ways. One is to have an embeddable runnable class, e.g.the JUnit-runnable TraderWebStories. This is where the choice of API comes into play.

Using Selenium API

Using WebDriver API

Lifecycle Steps

JBehave integration with Selenium and WebDriver APIs aims to facilitate common tasks. Amongst these, one of the most common is the management of the lifecycle, e.g. starting and stopping the browser.

JBehave provides three type of lifecycle management:

  1. per-stories: via the PerStoriesSeleniumSteps or PerStoriesWebDriverSteps.
  2. per-story: via the PerStorySeleniumSteps or PerStoryWebDriverSteps.
  3. per-scenario: via the PerScenarioSeleniumSteps or PerScenarioWebDriverSteps.
If you are using per-stories lifecycle, you must ensure that you are using a same-thread executor. C.f. the trader-webdriver example on how to configure the use of a same-thread executor.

Running Selenium-based tests in an automated way

NOTE: To get the Selenium based tests running in an automated way, you need to run both a webapp server, e.g. Jetty, and the Selenium server (only for the Selenium API, as the WebDriver API does not need it). See the trader runner selenium example and trader runner webdriver example for a way to do this using Maven.