Does anyone know how to configure the Selenium Docker images as services in GitLab-CI for running integration tests as part of a CI pipeline?
I'm testing a Django application, and I've set up the tests to connect to Selenium thus.
class SeleniumTestCase(LiveServerTestCase):
host = os.environ.get('LIVE_TEST_CASE_HOST', os.environ('HOSTNAME'))
@classmethod
def setUpClass(cls):
super().setUpClass()
options = webdriver.FirefoxOptions()
options.headless = True
cls.browser = webdriver.Remote(
'http://selenium:4444/wd/hub',
webdriver.DesiredCapabilities.FIREFOX,
options=options,
)
I've configured the Selenium Docker images locally using docker-compose
and it works great.
selenium:
image: selenium/hub:3.141.59-titanium
firefox:
image: selenium/node-firefox:3.141.59-titanium
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium
environment:
- HUB_HOST=selenium
- HUB_PORT=4444
- START_XVFB=false
But when I try to create a similar configuration for GitLab-CI using a Docker executor, I get a WebDriverException
.
test:
stage: test
image: $CMS_IMAGE_NAME
variables:
HUB_HOST: selenium
HUB_PORT: 4444
START_XVFB: 'false'
services:
- name: $DB_IMAGE_NAME
alias: db
- name: selenium/hub:3.141.59-titanium
alias: selenium
- name: selenium/node-firefox:3.141.59-titanium
script:
- export LIVE_TEST_CASE_HOST=$(ip addr show eth0 | grep inet | awk '{ print $2 }' | sed -En 's/^([^/]+)\/.*/\1/p'
- cd /code
- coverage run manage.py test
The $LIVE_TEST_CASE_HOST
variable is just a way for me to make the IP address of the container in CI available for use as the host in the URLs used in my test cases. I've found that $HOSTNAME
works locally in Docker, but not in CI for some reason. This configuration works if I drop selenium/hub
and use selenium/standalone-firefox
. But the above configuration causes the following exception.
selenium.common.exceptions.WebDriverException: Message: Error forwarding the new session Empty pool of VM for setup Capabilities {acceptInsecureCerts: true, browserName: firefox, marionette: true, moz:firefoxOptions: {args: [-headless]}}
Stacktrace:
at org.openqa.grid.web.servlet.handler.RequestHandler.process (RequestHandler.java:118)
at org.openqa.grid.web.servlet.DriverServlet.process (DriverServlet.java:85)
at org.openqa.grid.web.servlet.DriverServlet.doPost (DriverServlet.java:69)
at javax.servlet.http.HttpServlet.service (HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service (HttpServlet.java:790)
at org.seleniumhq.jetty9.servlet.ServletHolder.handle (ServletHolder.java:865)
at org.seleniumhq.jetty9.servlet.ServletHandler.doHandle (ServletHandler.java:535)
at org.seleniumhq.jetty9.server.handler.ScopedHandler.handle (ScopedHandler.java:146)
at org.seleniumhq.jetty9.security.SecurityHandler.handle (SecurityHandler.java:548)
at org.seleniumhq.jetty9.server.handler.HandlerWrapper.handle (HandlerWrapper.java:132)
at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextHandle (ScopedHandler.java:257)
at org.seleniumhq.jetty9.server.session.SessionHandler.doHandle (SessionHandler.java:1595)
at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextHandle (ScopedHandler.java:255)
at org.seleniumhq.jetty9.server.handler.ContextHandler.doHandle (ContextHandler.java:1340)
at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextScope (ScopedHandler.java:203)
at org.seleniumhq.jetty9.servlet.ServletHandler.doScope (ServletHandler.java:473)
at org.seleniumhq.jetty9.server.session.SessionHandler.doScope (SessionHandler.java:1564)
at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextScope (ScopedHandler.java:201)
at org.seleniumhq.jetty9.server.handler.ContextHandler.doScope (ContextHandler.java:1242)
at org.seleniumhq.jetty9.server.handler.ScopedHandler.handle (ScopedHandler.java:144)
at org.seleniumhq.jetty9.server.handler.HandlerWrapper.handle (HandlerWrapper.java:132)
at org.seleniumhq.jetty9.server.Server.handle (Server.java:503)
at org.seleniumhq.jetty9.server.HttpChannel.handle (HttpChannel.java:364)
at org.seleniumhq.jetty9.server.HttpConnection.onFillable (HttpConnection.java:260)
at org.seleniumhq.jetty9.io.AbstractConnection$ReadCallback.succeeded (AbstractConnection.java:305)
at org.seleniumhq.jetty9.io.FillInterest.fillable (FillInterest.java:103)
at org.seleniumhq.jetty9.io.ChannelEndPoint$2.run (ChannelEndPoint.java:118)
at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.runTask (EatWhatYouKill.java:333)
at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.doProduce (EatWhatYouKill.java:310)
at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.tryProduce (EatWhatYouKill.java:168)
at org.seleniumhq.jetty9.util.thread.strategy.EatWhatYouKill.run (EatWhatYouKill.java:126)
at org.seleniumhq.jetty9.util.thread.ReservedThreadExecutor$ReservedThread.run (ReservedThreadExecutor.java:366)
at org.seleniumhq.jetty9.util.thread.QueuedThreadPool.runJob (QueuedThreadPool.java:765)
at org.seleniumhq.jetty9.util.thread.QueuedThreadPool$2.run (QueuedThreadPool.java:683)
at java.lang.Thread.run (Thread.java:748)
I can't figure out why this works locally, but not in GitLab-CI.