If you’re looking to run your tests on different browser and operating system combinations but you’re unable to justify using a third-party solution like Sauce Labs then what do you do?
With Selenium Grid you can stand up a simple infrastructure of various browsers on different operating systems to not only distribute test load but also give you a diversity of browsers to work with.
Selenium Grid is part of the Selenium project. It lets you distribute test execution across several machines. You can connect to it with Selenium Remote by specifying the browser, browser version, and operating system you want. You specify these values through Selenium Remote’s Capabilities
.
There are two main elements to Selenium Grid — a hub, and nodes. First, you need to stand up a hub. Then you can connect (or “register”) nodes to that hub. Nodes are where your tests will run, and the hub is responsible for making sure your tests end up on the right one (e.g., the machine with the operating system and browser you specified in your test).
Let’s go through an example.
An Example
Part 1: Grid Setup
Selenium Grid comes built into the Selenium Standalone Server. So to get started we’ll need to download the latest version of it from here.
Then we need to start the hub.
> java -jar selenium-server-standalone.jar -role hub 19:05:12.718 INFO - Launching Selenium Grid hub ...
After that, we can register nodes to it.
> java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444/grid/register 19:05:57.880 INFO - Launching a Selenium Grid node ...
NOTE: This example only demonstrates a single node on the same machine as the hub. To span nodes across multiple machines, you will need to place the standalone server on each machine and launch it with the same registration command (replacing http://localhost
with the location of your hub, and specifying additional parameters as needed).
Now that the grid is running we can view the available browsers by visiting our Grid’s console at http://localhost:4444/grid/console
.

To refine the list of available browsers, we can specify an additional -browser
parameter when registering the node. For instance, if we wanted to only offer Safari on a node, we could specify it with -browser browserName=safari
, which would look like this:
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444/grid/register -browser browserName=safari
We could also repeat this parameter again if we wanted to explicitly specify more than one browser.
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444/grid/register -browser browserName=safari -browser browserName=chrome -browser browserName=firefox
There are numerous parameters that we can use at run time. You can see a full list here.
Part 2: Test Setup
Now let’s wire up a simple test script to use our new Grid.
Java
// filename: Grid.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
public class Grid {
WebDriver driver;
@Before
public void setUp() throws Exception {
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
String url = "http://localhost:4444/wd/hub";
driver = new RemoteWebDriver(new URL(url), capabilities);
}
@After
public void tearDown() throws Exception {
driver.quit();
}
@Test
public void gridTest() {
driver.get("http://the-internet.herokuapp.com/");
assertThat(driver.getTitle(), is(equalTo("The Internet")));
}
}
Python
# filename: grid.py
import unittest
from selenium import webdriver
class Grid(unittest.TestCase):
def setUp(self):
url = 'http://localhost:4444/wd/hub'
desired_caps = {}
desired_caps['browserName'] = 'firefox'
self.driver = webdriver.Remote(url, desired_caps)
def tearDown(self):
self.driver.quit()
def test_page_loaded(self):
driver = self.driver
driver.get('http://the-internet.herokuapp.com')
assert driver.title == 'The Internet'
if __name__ == "__main__":
unittest.main()
Ruby
# filename: grid.rb
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
def setup
@driver = Selenium::WebDriver.for(
:remote,
url: 'http://localhost:4444/wd/hub',
desired_capabilities: :firefox) # you can also use :chrome, :safari, etc.
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
run do
@driver.get 'http://the-internet.herokuapp.com'
expect(@driver.title).to eq('The Internet')
end
C#
// filename: Grid.cs
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using System;
public class Grid
{
IWebDriver Driver;
[SetUp]
public void SetUp()
{
DesiredCapabilities Capabilities = new DesiredCapabilities();
Capabilities.SetCapability(CapabilityType.BrowserName, "firefox");
string GridURL = "http://localhost:4444/wd/hub";
Driver = new RemoteWebDriver(new Uri(GridURL), Capabilities);
}
[TearDown]
public void TearDown()
{
Driver.Quit();
}
[Test]
public void BrowserLaunchesOnGrid()
{
Driver.Navigate().GoToUrl("http://the-internet.herokuapp.com");
Assert.That(Driver.Title.Equals("The Internet"));
}
}
You can see a full list of the available Selenium Capabilities
options here.
Expected Behavior
When we save this file and run it here is what will happen:
- test connects to the grid hub
- hub determines which node has the necessary browser/platform combination
- hub opens an instance of the browser on the found node
- test runs on the new browser instance
- the test completes and the browser closes on the node