Dockerized Rails RSpec系统测试未连接

时间:2018-10-24 09:46:59

标签: ruby-on-rails selenium docker rspec capybara

我正在尝试使用Docker设置我的Rails应用程序。我在尝试在Docker容器中运行的系统测试遇到困难。

我已经设置了一个Selenium容器,该容器试图在http://0.0.0.0:3005上打开一个网站,但无法连接。我希望Capybara通过更改它需要连接的IP地址来连接到远程服务器,但它没有成功。

这是我的Docker撰写文件:

# 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

这是我的RSpec Rails助手配置

# 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

我已将VNC连接到硒Docker容器,并对其打开的页面进行了截图。我已经附上了屏幕截图。

我尝试获取测试容器的IP地址并手动输入,但似乎无济于事。

为了确保我已经给出了用于运行测试的所有内容,这是我正在使用的命令:

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

和测试RSpec文件:

# 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

欢迎任何帮助或建议!

enter image description here

0 个答案:

没有答案