Skip to content

#151: Create Videos With Selenium Grid

If you need to find out what went wrong during an end-to-end test, a recorded video of the browser with all its interactions can be a time saver. Let's look at how we can create these videos with a dynamic Selenium Grid.

Ask for a video

In our browser definition we need to ask for the capability se:recordVideo to tell our grid that it should create a video:

1
2
3
4
5
6
    firefox_options = webdriver.FirefoxOptions()
    firefox_options.set_capability("se:recordVideo","True")
    driver = webdriver.Remote(
        command_executor='http://localhost:4444',
        options=firefox_options        
    )

As soon as we get the driver, we should ask for the session_id:

    session_id = driver.session_id

Inside the assets folder (next to the docker-compose file) you will find a folder named after the session_id that contains the video.

For every session you get a folder with a video if you asked for it

Create a video fixture

We can create a new fixture for pytest to create a video for our Selenium based test:

@pytest.fixture()
def video_grid(request):
    firefox_options = webdriver.FirefoxOptions()
    firefox_options.set_capability("se:recordVideo","True")
    driver = webdriver.Remote(
        command_executor='http://localhost:4444',
        options=firefox_options        
    )

    testname = request.node.name
    session_id = driver.session_id
    print(f"{testname}->./assets/{session_id}/video.mp4")

    yield driver

    #driver.close() -> keeps session open for 5 minutes!
    driver.quit()

Attention: If you close the browser with driver.close() the session in Selenium Grid will continue for 5 minutes. Therefore, always use driver.quit()!

Use the video fixture

We can use our video fixture in our tests:

import pytest
from selenium_pytest_fixture import video_grid


@pytest.mark.usefixtures("video_grid")
def test_duckduckgo_video(video_grid):
    video_grid.get("https://duckduckgo.com/?t=ha&va=j")
    assert "DuckDuckGo — Privacy, simplified." == video_grid.title


@pytest.mark.usefixtures("video_grid")
def test_blog_video(video_grid):
    video_grid.get("https://improveandrepeat.com/")
    assert "Improve & Repeat" == video_grid.title

If we run pytest with the -s option, we should see the test name and the session id:

... collected 2 items

test_duckduckgo_video->./assets/12d1855f-***/video.mp4 test_blog_video->./assets/a0c34ebd-***/video.mp4 ...

(The session id changes with every run)

We now can take that session id and watch the matching video. So far, I have not found a nice test report that already integrates the video into the report. Please post a comment if you know about a solution for that.

Create screenshots

We can take screenshots with the method get_screenshot_as_file() on the driver:

driver.get_screenshot_as_file(f"./my/path/image.png")

That works inside a (dynamic) Selenium Grid and when you run the browser directly on your machine.

Parting thoughts

We now have everything in place to use Selenium to automate a web browser. If we want to run a single browser to scrap data from JavaScript-heavy pages (like WordPress) or check that our application keeps working with end-to-end tests, Selenium covers it. Tools like Selenium Grid are a great help, but it takes a lot of time to figure out all the necessary details.

I hope you can skip the errors I made and quickly reach a running solution. Please let me know if you miss something or have ideas to create test reports that include the videos.