如何使用 GitLab-CI 中的 docker 镜像设置 Selenium Grid?

dar*_*all 6 django selenium gitlab docker gitlab-ci

有谁知道如何将 Selenium Docker 镜像配置为 GitLab-CI 中的服务,以便将集成测试作为 CI 管道的一部分运行?

我正在测试 Django 应用程序,并且我已经设置了连接到 Selenium 的测试。

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,
        )
Run Code Online (Sandbox Code Playgroud)

我已经使用本地配置了 Selenium Docker 镜像docker-compose,效果很好。

docker-compose.yml
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
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用 Docker 执行器为 GitLab-CI 创建类似的配置时,我得到了一个WebDriverException.

.gitlab-ci.yml
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
Run Code Online (Sandbox Code Playgroud)

$LIVE_TEST_CASE_HOST变量只是我使 CI 中容器的 IP 地址可用作测试用例中使用的 URL 中的主机的一种方式。我发现它$HOSTNAME可以在 Docker 本地运行,但由于某种原因不能在 CI 中运行。如果我删除selenium/hub并使用此配置,则该配置有效selenium/standalone-firefox。但上述配置会导致以下异常。

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)
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这在本地有效,但在 GitLab-CI 中却无效。