Grid Support

semperos edited this page Oct 8, 2012 · 8 revisions

In addition to the core Selenium-WebDriver API, the Selenium project offers the Selenium Grid, which facilitates distributed execution of tests across multiple machines. The "brain" of this operation is called a hub, while the machines on which tests are executed are called nodes.

Overview

If you are not familiar with setting up a Grid hub and its nodes, I suggest you first read the appropriate wiki page on the Selenium-WebDriver Google site. While clj-webdriver provides convenience functions for managing a local hub, you need to read the Selenium-WebDriver wiki to be able to leverage this capability fully.

Using the Selenium-WebDriver Grid only adds two points of complexity to setting up your tests, both of which clj-webdriver provides for:

  • Starting a Grid hub
  • Starting a RemoteWebDriver instance

With clj-webdriver, you can either start up a Grid hub directly from your Clojure code, or you can attach to an existing hub (see below). The RemoteWebDriver is the equivalent of your Firefox or Chrome WebDriver, which is your gateway to controlling the browser. In a Grid setup, it is the job of the hub to allocate job runs to nodes that are configured to support them based on browser type, version, and other system properties.

Setup

You can start up a hub and remote driver in one fell swoop:

(let [[a-server a-driver] (new-remote-session {:port 4444
                                               :host "127.0.0.1"}
                                              {:browser :firefox})]
  (def grid-server a-server)
  (def driver a-driver))

This will (1) start a Grid hub and (2) a RemoteWebDriver instance that are immediately ready to be used. You can use this driver with either the Core API per usual, or with the Taxi API by passing it to set-driver!:

(taxi/set-driver! driver)

Note that the Taxi API's set-driver! function will accept either a browser specification like {:browser :firefox} or an already-running Driver instance as in this example.

Browser Capabilities

Part of the power of a Grid setup lies in the ability to have a single Grid hub to delegate test runs to nodes with diverse platform and browser configurations. In order to make the Grid hub choose an appropriate node, you have to pass in a set of desired configurations when starting a RemoteWebDriver instance. This is accomplished by including a :capabilities entry as part of the browser-spec in the new-remote-session function. For example:

(new-remote-session {:port 3003}
                    {:capabilities {:browser-name "firefox",
                                    :platform "WINDOWS"}})

Once the driver has been started, this entry expands into four entries inside the returned Driver record: :desired, :desired-obj, :actual, and :actual-obj. These correspond to Clojure map and Java object versions of both desired (potential) capabilities and actual (realized) capabilities available in a given browser respectively. Providing both allows you to work with capabilities like first-class Clojure data structures, but also access any lower-level functionality exposed by the DesiredCapabilities class.

Attaching to Running Hub

To use the Selenium-WebDriver Grid to its full potential, you need to start a hub and its nodes manually, providing custom configurations to match your use case. Follow the steps below to download the necessary JAR file and use clj-webdriver's utility scripts for starting Grid hubs and nodes as background processes. You should edit these scripts to include your own custom configuration for your hub and nodes.

First, you need to get the Selenium-WebDriver standalone server. Follow these steps to get started:

  1. Download the latest selenium-server-standalone-xxx.jar from Selenium-WebDriver's download page
  2. Move and rename this JAR to /opt/selenium-server-standalone.jar
  3. Grab copies of clj-webdriver's grid-hub and grid-node Bash scripts (sorry Windows users)
  4. Run the grid-hub script as ./grid-hub start. Wait until you see output that shows that the hub is listening on port 3333.
  5. Run the grid-node script as ./grid-node start. Wait until you see that the node has registered with the hub.

At this point, you have a locally hosted hub and node with a default configuration, ready for testing. You can stop the node and hub by running ./grid-node stop and ./grid-hub stop (in that order).

You can now use the same code as you did for a new remote session from above, but new-remote-session will just use the already-running hub instead of starting one:

(let [[a-server a-driver] (new-remote-session {:port 3333
                                               :host "127.0.0.1"
                                               :existing true}
                                              {:browser :firefox})]
  (def grid-server a-server)
  (def driver a-driver))

If for some reason you can't use clj-webdriver's Bash utility scripts to manage your hub and nodes, you can see what default parameters they pass to the selenium-server-standalone.jar file for starting up a hub and node on your platform.