Dockerized rails rspec system tests not connecting

Viewed 596

I'm trying to setup my Rails application with Docker. I'm having difficulties with the system tests that I'm trying to run in the Docker container.

I've setup a Selenium container which tries to open a website on http://0.0.0.0:3005 but cannot connect. I want Capybara to connect to a remote server by changing the IP address on which it needs to connect but it's not succeeding.

Here's my Docker compose file:

# docker-compose.yml
version: '3'

services:
  postgres:
    image: postgres:10.3-alpine
    volumes:
      - ./tmp/db:/var/lib/postgresql/data

  redis:
    image: redis:4.0.5-alpine
    command: redis-server
    hostname: redis
    volumes:
      - ./tmp/redis:/var/lib/redis/data

  app:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    hostname: bumblebee-web
    depends_on:
      - postgres
      - redis
    ports: 
      - 3000:3000
    volumes:
      - .:/app
    environment:
      - RAILS_LOG_TO_STDOUT=true
    tty: true

  sidekiq:
    depends_on:
      - postgres
      - redis
    build: .
    command: bundle exec sidekiq -C config/sidekiq.yml
    volumes:
      - .:/app
  
  # Test containers
  test:
    build: .
    env_file:
      - .env.test
    ports:
      - 3005:3005 # Capybara listens here
    links:
      - postgres
      - selenium
    volumes:
      - .:/app
    command: bin/spring server
    environment:
      TEST_APP_HOST: test
      TEST_APP_PORT: 3005
      SELENIUM_HOST: selenium
      RAILS_ENV: test
      DOCKER: 'true'
    networks:
      default:
        aliases:
          - test

  selenium:
    image: selenium/standalone-chrome-debug
    ports: 
      - 4444:4444 
      - 5900:5900
    logging:
      driver: none

This is my RSpec Rails helper configuration

# rails_helper.rb
RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
  config.include Devise::Test::ControllerHelpers, type: :controller

  config.before(:each, type: :system, js: true) do
    if YAML.safe_load(ENV["DOCKER"])
      driven_by :selenium_remote
      host! "http://#{Capybara.server_host}:#{Capybara.server_port}"
    else
      driven_by :headless_chrome
    end
  end
end

if YAML.safe_load(ENV["DOCKER"])
  selenium_url = "http://selenium:4444/wd/hub"

  Capybara.register_driver :selenium_remote do |app|
    Capybara::Selenium::Driver.new(
      app,
      url: selenium_url, 
      browser: :remote, 
      desired_capabilities: :chrome
    )
  end
  
  Capybara.run_server = false
  Capybara.server_host = ENV['TEST_APP_HOST']
  Capybara.server_port = ENV['TEST_APP_PORT']
  Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
else
  Capybara.register_driver(:headless_chrome) do |app|
    capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
      chromeOptions: { args: %w[headless disable-gpu window-size=1920,1080] }
    )

    Capybara::Selenium::Driver.new(
      app,
      browser: :chrome,
      desired_capabilities: capabilities,
    )
  end

  Capybara.javascript_driver = :headless_chrome
end

I've connect with VNC to the selenium Docker container and made a screenshot of the page that it's opening. I've attached the screenshot.

I've tried getting the IP address of the test container and entering it manualy but nothing seems to help.

To be sure I have given everything that I use to run the test here is the command that I'm using:

docker-compose run test bin/rspec spec/feature/compositions/composition_multi_delete_spec.rb

And the test RSpec file:

# spec/feature/compositions/composition_multi_delete_spec.rb
require 'rails_helper'

include Warden::Test::Helpers

feature "Multi delete of compositions" do
  let(:group) { FactoryBot.create :private_group }
  let(:user) { FactoryBot.create :user }
  let(:composition) { FactoryBot.create :composition, :filled, user: user, group: group }

  before do
    composition
    login_as user, scope: :user
  end

  scenario "is expected to work and remove the composition", type: :system, js: true do
    composition
    visit compositions_path
    click_on "Edit compositions"
    find("#composition-#{composition.id}").click
    click_on "Delete items"
    page.driver.browser.switch_to.alert.accept

    expect(page).to_not have_content composition.name
    visit compositions_path
    expect(page).to_not have_content composition.name
  end

  scenario "is expected to preserve the search scope after delete", type: :system, js: true do
    visit compositions_path scope: "all"
    click_on "Edit compositions"
    find("#composition-#{composition.id}").click
    click_on "Delete items"
    page.driver.browser.switch_to.alert.accept
    # because of DB deadlock issue added sleep
    sleep 0.2

    expect(page).to have_current_path '/compositions?scope=all'
  end
end

Any help or advice is welcome!

enter image description here

0 Answers
Related