Home > Back-end >  How selenium access capybara server on Github Actions?
How selenium access capybara server on Github Actions?

Time:07-17

I'm creating a personal project with Ruby on Rails.

I'm trying to create a CI with Github Actions Capybara Selenium Service. Why selenium service? To make it closer to the project's docker-compose.

First, this is my workflow file:

name: CI
on: push
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:14.4
        ports:
          - 5432:5432
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      selenium:
        image: selenium/standalone-chrome:3.141.59
        ports:
          - 4444:4444
    steps:
      -
        name: Check out repository code
        uses: actions/checkout@v3
      -
        name: 'Create web docker image'
        run: docker build -t web . --target new_release
      -
        name: 'Create database'
        run: docker run --env-file .docker/env_files/.env.ci --network="host" web bin/rails db:create db:migrate
      -
        name: 'Run unit tests'
        run: docker run --env-file .docker/env_files/.env.ci --network="host" web bin/rails test
      -
        name: 'Run system tests'
        run: docker run --env-file .docker/env_files/.env.ci --network="host" web bin/rails test:system

On the last step this error happens:

Selenium::WebDriver::Error::UnknownError: unknown error: net::ERR_CONNECTION_REFUSED

My interpretation is that the selenium service is unable to connect with the capybara server. So, let's talk about the capybara configuration of the project:

# frozen_string_literal: true

require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  Capybara.register_driver(:chrome_remote) do |app|
    Capybara::Selenium::Driver.new(
      app,
      browser: :remote,
      url: ENV.fetch("SELENIUM_URL"),
      capabilities: Selenium::WebDriver::Remote::Capabilities.chrome
    )
  end

  Capybara.run_server = true
  Capybara.server = :puma, { Silent: true }
  Capybara.server_host = ENV.fetch("CAPYBARA_SERVER_HOST")
  Capybara.server_port = ENV.fetch("CAPYBARA_SERVER_PORT")

  Capybara.default_driver = :chrome_remote
  Capybara.javascript_driver = :chrome_remote

  Capybara.save_path = Rails.root.join("tmp/capybara")

  driven_by :chrome_remote, using: :chrome, screen_size: [1400, 1400]

  include FactoryBot::Syntax::Methods
end

And finally, the env file used on the ci:

CAPYBARA_SERVER_HOST=localhost
CAPYBARA_SERVER_PORT=4000
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=localhost
RAILS_ENV=test
SELENIUM_URL=http://localhost:4444/wd/hub

I tried not using --network="host", using the name of the services, but using that configuration I was unable to pass "Create database" step. I'm wondering why is not working, I can see the capybara creating the server using my environment variables:

Capybara starting Puma...
* Version 5.6.2 , codename: Birdie's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:4000
* Listening on http://[::1]:4000

But I'm lost, not sure what the connection is being refused. In the local environment, the tests pass perfectly. What do you think?

CodePudding user response:

Instead of using the services docker, I decided to use docker-compose. The file that did the trick:

version: "3.7"

services:
  db:
    image: postgres:14.4
    ports:
      - 5432:5432
    env_file:
      - ./.docker/env_files/.env
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - ./.docker/volumes/postgres_data:/var/lib/postgresql/data

  web:
    image: test
    env_file:
      - ./.docker/env_files/.env
    build:
      context: .
    depends_on:
      db:
        condition: service_healthy
    links:
      - db
    ports:
      - 3000:3000
    volumes:
      - .:/opt/test:cached
    stdin_open: true
    tty: true

  livereload:
    image: test
    depends_on:
      - web
    ports:
      - 35729:35729
    command: ["bundle", "exec", "guard", "-i"]
    env_file:
      - ./.docker/env_files/.env
    volumes:
      - .:/opt/test:cached

  tailwindcsswatcher:
    image: test
    depends_on:
      - web
    ports:
      - 3035:3035
    command: ["bin/rails", "tailwindcss:watch"]
    env_file:
      - ./.docker/env_files/.env
    volumes:
      - .:/opt/test:cached
    tty: true

  selenium:
    image: selenium/standalone-chrome:3.141.59
    ports:
      - 4444:4444

volumes:
  postgres_data:

Now the ci.yml using the docker-compose:

name: CI
on: push
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      -
        name: Check out repository code
        uses: actions/checkout@v3
      -
        name: 'Create docker-compose file'
        run: cp .docker/docker-compose.dev.yml docker-compose.yml
      -
        name: 'Create env file'
        run: cp .docker/env_files/.env.dev .docker/env_files/.env
      -
        name: Build web container
        run: docker-compose build web selenium
      -
        name: 'Create database'
        run: docker-compose run --rm web bin/rails db:create db:migrate
      -
        name: 'Start container'
        run: docker-compose up -d web selenium
      -
        name: 'Run unit tests'
        run: docker-compose exec -T web bin/rails test
      -
        name: 'Run system tests'
        run: docker-compose exec -T web bin/rails test:system
  • Related