diff --git a/testinfra/util.py b/testinfra/util.py
index f5f5bb75bc..310b08c4db 100644
--- a/testinfra/util.py
+++ b/testinfra/util.py
@@ -16,6 +16,7 @@ import socket
 import time
 
 from selenium import webdriver
+from selenium.webdriver.common.by import By
 from selenium.webdriver.support.ui import WebDriverWait
 from selenium.common.exceptions import TimeoutException
 
@@ -30,9 +31,11 @@ def take_screenshots(host, shots):
     * (str) Javascript to execute before shot, None to skip
     * (str) filename.png, will be placed in /var/log/screenshots for collection
     """
+    firefox_options = webdriver.FirefoxOptions()
+
     driver = webdriver.Remote(
-    command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()),
-    desired_capabilities=webdriver.DesiredCapabilities.FIREFOX)
+        command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()),
+        options=firefox_options)
 
     try:
         for url, execute, png in shots:
@@ -52,9 +55,24 @@ def take_screenshots(host, shots):
             # screenshot".  You expand the viewport and take a
             # shot of the <body> element so that you don't also
             # get scrollbars in the shot, with some tweaking
-            # because the window size.  Apparently selinum 4
-            # will have getFullPageScreeshotAs, so we should switch
-            # to that when available.
+            # because of the window size.
+            #
+            # Update 2022-20-09 : The Firefox driver with Selenium 4
+            # has a very simple get_full_page_screenshot_as_png()
+            # which would be perfect -- but -- this only works when
+            # using the local Firefox connection, not the remote
+            # connection we are using here to talk to the docker
+            # container.  I looked at switching this, but to talk to
+            # the local firefox you need geckodriver -- and that
+            # doesn't work with Ubuntu Jammy because Firefox is now
+            # distributed as a snap, not a regular package, and it
+            # doesn't work together [1] (apparently you can get around
+            # it, but it's just other hacks [2]).  So we still have
+            # this ...
+            #
+            # [1] https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/1968266
+            # [2] https://github.com/mozilla/geckodriver/releases/tag/v0.31.0
+
             original_size = driver.get_window_size()
             required_width = driver.execute_script(
                 'return document.body.parentNode.scrollWidth')
@@ -62,7 +80,7 @@ def take_screenshots(host, shots):
                 'return document.body.parentNode.scrollHeight') + 100
             driver.set_window_size(required_width, required_height)
 
-            driver.find_element_by_tag_name('body'). \
+            driver.find_element(By.TAG_NAME, 'body').\
                 screenshot("/var/log/screenshots/%s" % png)
 
             driver.set_window_size(
diff --git a/tox.ini b/tox.ini
index 8819465b20..ecf682940e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -39,7 +39,7 @@ commands = sphinx-build -W -E -b html doc/source doc/build/html
 deps =
   pytest-html # MPL-2.0
   pytest-testinfra[ansible]>=6.0.0
-  selenium==3.141.0
+  selenium
   requests
 
 # This environment assumes a gate-hosts.yaml file has been written.
diff --git a/zuul.d/system-config-run.yaml b/zuul.d/system-config-run.yaml
index faec03b111..4e5b4cf1f5 100644
--- a/zuul.d/system-config-run.yaml
+++ b/zuul.d/system-config-run.yaml
@@ -535,9 +535,11 @@
       - playbooks/roles/install-docker/
       - playbooks/roles/pip3/
       - playbooks/roles/run-selenium/
+      - testinfra/util.py
       - docker/hound/
       - testinfra/test_codesearch.py
 
+
 - job:
     name: system-config-run-etherpad
     parent: system-config-run-containers
@@ -637,6 +639,7 @@
       # to run this job as well.
       - docker/haproxy-statsd/
       - playbooks/roles/run-selenium/
+      - testinfra/util.py
 
 - job:
     name: system-config-run-grafana
@@ -665,6 +668,7 @@
       - playbooks/roles/install-docker/
       - playbooks/roles/pip3/
       - playbooks/roles/run-selenium/
+      - tesinfra/util.py
       - testinfra/test_grafana.py
 
 - job:
@@ -783,6 +787,7 @@
       - playbooks/roles/install-docker/
       - playbooks/roles/pip3/
       - playbooks/roles/run-selenium/
+      - testinfra/util.py
       - playbooks/test-paste.yaml
       - testinfra/test_paste.py
 
@@ -964,6 +969,7 @@
       - inventory/service/group_vars/review.yaml
       - playbooks/roles/pip3/
       - playbooks/roles/run-selenium/
+      - testinfra/util.py
       - playbooks/roles/install-docker/
       - playbooks/roles/letsencrypt
       - playbooks/roles/gerrit/