Skip to content

#148: Selenium Grid With Docker

Sometimes it would be great to have a web browser in a specific version. Installing that on your machine may not be possible, but that is exactly the problem we can use dev containers for. Let’s look how Selenium and Docker can help us to get more flexibility (and additional features).

Preparation

Make sure that you have a working installation of Docker. If you run Docker on Windows, make sure that you install Docker as administrator - otherwise it may not work correctly.

Selenium Grid and Docker

Selenium Grid is a solution to run multiple browsers in parallel. That allows us to shorten the test runs and get more flexibility on the browser versions. We can install everything on our machine, but it is much faster to use an image for Docker that is ready to use.

We can tell Docker to fetch the image and run it in the deamon mode with this command:

docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-firefox:4.6.0-20221104

This gives us an image with Firefox for Selenium 4.6 that we can access on port 4444 on our machine.

Use the remote driver

In our Python code, we need to use the remote driver and point it to our running Docker container:

1
2
3
4
5
6
7
8
9
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

firefox_options = webdriver.FirefoxOptions()
driver = webdriver.Remote(
    command_executor='http://localhost:4444',
    options=firefox_options
)

The rest of our code looks as before:

# time.sleep(15)

driver.get("https://duckduckgo.com/?t=ha&va=j")

search_box = driver.find_element(
    by=By.ID, 
    value="search_form_input_homepage")
search_box.send_keys("Selenium web")

search_button = driver.find_element(
    by=By.ID, 
    value="search_button_homepage")
search_button.click()

title = driver.title
print(title)

results_div = driver.find_element(
    by=By.CLASS_NAME, 
    value="results")
results = results_div.find_elements(
    by=By.TAG_NAME, 
    value="h2")

for result in results:
    print(f"* {result.text}")

time.sleep(15)

driver.quit() 

Run the code

We can run our code and it will connect to Selenium Grid, run a Firefox browser, and interact with the DuckDuckGo.com site. If everything works, we should get an output like this:

Selenium web at DuckDuckGo
* Selenium
* WebDriver | Selenium
* Selenium WebDriver Tutorial  javatpoint
* Selenium Webdriver Tutorial with Examples | BrowserStack
* Selenium (software)  Wikipedia
* Complete Selenium WebDriver Tutorial with Examples  LambdaTest
* How Selenium WebDriver Works  c-sharpcorner.com
* Introduction to Web Scraping using Selenium  Medium
* Web Scraping with Selenium and Python  ScrapFly Blog
* Selenium IDE · Open source record and playback test automation for the web

See the browser in action

If you add a delay of 15 seconds before the driver navigates to DuckDuckGo, you have enough time to watch the Browser in the Docker container:

1
2
3
4
5
time.sleep(15)

driver.get("https://duckduckgo.com/?t=ha&va=j")

...

Go to http://localhost:4444/ui#/sessions to see your current session (if it is not there yet, refresh the page until it appears):

There should be a session for the Selenium driver you run in your code

Click on the video icon, enter "secret" as the password and you can watch the browser while it gets automated by Selenium:

When the sleep() time is over, we can watch how the browser clicks through our site.

Next

We now have the first part of Selenium Grid in working order. Next week we explore how we can add multiple browsers and run our tests in parallel.