Web application acceptance tests in gitlab-ci using codeception and selenium installed as docker container

Let’s assume we are running acceptance tests of our application during the testing stage in gitlab-ci. The runner starts the container with our web app, and then executes codeception acceptance tests using the selenium server using the google chrome browser. We are using a local gitlab server with a registered runner to execute our tests.
.gitlab-ci.yml looks like this:

job:
  services:
  - name: postgres:alpine
    alias: postgres
  - name: redis:alpine
    alias: redis
  - name: selenium/standalone-chrome
    alias: chrome
  - name: tophfr/mailcatcher
    alias: smtp

 
What could possibly go wrong? Actually, everything could go wrong. The problem is that selenium is a service in gitlab-ci.yml and it does not know the runner’s executor container IP address and cannot reach it by host name.

Indeed, if you check the executor’s host file you will see something like this:

$ cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.8	chrome 9a7c560fcc81 
172.17.0.9	tophfr__mailcatcher 47ca8ed9a04a 
172.17.0.9	tophfr-mailcatcher 47ca8ed9a04a 
172.17.0.9	smtp 47ca8ed9a04a 
172.17.0.8	selenium__standalone-chrome 9a7c560fcc81 
172.17.0.8	selenium-standalone-chrome 9a7c560fcc81 
172.17.0.10	runner-fc308d01-project-17-concurrent-0

 
But, if we look in the host file of the selenium container you won’t see any information about our web app container (runner-fc308d01-project-17-concurrent-0 with IP address 172.17.0.10)

127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.8	564756c8670d

 

This problem is something unexpected but, is not new. I have found a 2-year old issue on gitlab https://gitlab.com/gitlab-org/gitlab-runner/issues/1042

However, container linking (including containers in the same network) is still not implementing in gitlab. So, the main container is able to call the service container, but the service container cannot call the main container.

One possible workaround can be the usage of environmental variables to deliver the container’s IP address into the codeception config and test files.

We can grab the container’s IP address from the main container’s host file. It can be done directly in .gitlab-ci.yml

script:
- export WEB_APP_IP="$(ifconfig | grep -A 1 'eth0' | tail -1 | cut -d ':' -f 2 | cut -d ' ' -f 1)"
# will set WEB_APP_IP environment variable to 172.17.0.10
- export SMTP_IP=$(grep 'smtp' /etc/hosts | awk '{print $1}')
# will set SMTP_IP environment variable to 172.17.0.9

 
Now we can use the WEP_APP_IP variable to set the page URL in the acceptance.suite.yml

class_name: AcceptanceTester

modules:
    enabled:
      - WebDriver:
          host: chrome
          port: 4444
          browser: chrome
          window_size: 1024x768
          url: 'http://%WEB_APP_IP%'
          capabilities:
            unexpectedAlertBehaviour: 'accept'
      - Asserts

 
don’t forget to specify params: env in codeception.yml

namespace: frontend\tests
actor: Tester
paths:
    tests: tests
    log: tests/_output
    data: tests/_data
    helpers: tests/_support
settings:
    bootstrap: _bootstrap.php
    colors: true
    memory_limit: 1024M
modules:
    config:
        Yii2:
            configFile: 'config/test-local.php'
params: env

 
If you need to call one service container from another service container during your codeception test script MyCest.php, you can obtain the service container IP address from PHP

$this->mailClientURL = 'http://'.getenv('SMTP_IP');