[RUBY] Use selenium docker for CircleCI system specs

This is my first post, so please take a look at any mistakes or confusing things.

environment

・ Ruby 2.7.1 ・ Rails 6.0.2.1

Thing you want to do

-Run system tests on CircleCI using selnium docker -Make system js: true available on CircleCI

docker-compose.yml Get the image of selenium used in the system specifications, and don't forget to specify the port and cooperation with depens_on.

docker-compose.yml


version: "3"
services:
  web:
    build: .
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    tty: true
    stdin_open: true
    depends_on:
      - db
      - chrome
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABE: db
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password
  chrome:
    image: selenium/standalone-chrome-debug:latest
    ports:
      - "4444:4444"
volumes:
  mysql-data:
    driver: local

Modify database.yml

Since the database does not use the db container as it is, modify database.yml.

database.yml


default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myappp_production
  username: myapp
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
$ docker-compose build
$ docker-compose up
$ docker-compose run web rake db:create

spec/rails_helper Add the gems needed for testing

Gemfile


group :test do
  gem 'capybara'
  gem 'selenium-webdriver'
  gem 'rspec-rails'
end

system test modifies rails_spec to use selenium docker

rails_spec.rb


Capybara.register_driver :remote_chrome do |app|
  url = 'http://chrome:4444/wd/hub'
  caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
    'goog:chromeOptions' => {
      'args' => [
        'no-sandbox',
        'headless',
        'disable-gpu',
        'window-size=1680,1050'
      ]
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps)
end

RSpec.configure do |config|
  #abridgement

  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 4444
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end
end

The local system specs should now work fine

.circleci/config.yml CircleCI settings --run: mv ./config/database.yml.ci ./config/database.yml in CI environment changing database settings. You have to set name: chrome ʻErrno :: EADDRINUSE: Address already in use --bind (2) for "172.27.0.3" port 4444` error occurs

config.yml


version: 2.1
jobs:
  build:
    docker:
      - image: circleci/ruby:2.7.1-node-browsers
          RAILS_ENV: test
          DB_HOST: 127.0.0.1
      - image: mysql:8.0
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: "true"
          MYSQL_ROOT_HOST: "127.0.0.1"
          MYSQL_DATABE: db
        command: --default-authentication-plugin=mysql_native_password
      - image: selenium/standalone-chrome-debug:latest
        name: chrome
    working_directory: ~/coffee
    steps:
      - checkout
      - run:
          name:install bundle
          command: bundle check || bundle install --jobs=4
      - run:
          name:Add yarn
          command: yarn install
      - run:
          name:add webpack
          command: bundle exec bin/webpack
      - run:
          name: rubocop
          command: bundle exec rubocop
      - run: mv ./config/database.yml.ci ./config/database.yml
      - run:
          name:Create database
          command: bundle exec rails db:create || bundle exec rails db:migrate
      - run:
          name: rspec test
          command: |
            mkdir /tmp/test-results
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
              circleci tests split --split-by=timings)"
            bundle exec rspec \
              --format RspecJunitFormatter \
              --out /tmp/test-results/rspec.xml \
              --format progress \
              $TEST_FILES
      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results

This should work fine for the rspec system test on CircleCI

reference

-I tried RSpec System test with Rails on Docker using Selenium Docker. -Create an environment that can execute system specifications with CircleCI while converting an existing Rails 6 application to Docker

Recommended Posts

Use selenium docker for CircleCI system specs
[WIP] Use NFS for Docker Volume
Why use Docker? Docker recommendations for small cis tubes
How to use nginx-ingress-controller with Docker for Mac
Why we use Docker
Use Puphpeteer with Docker
Use ngrok with Docker