ruby-on-rails - 带有 Rails 测试的 Dockerized Selenium

标签 ruby-on-rails selenium docker selenium-webdriver capybara

我正在尝试在 docker 中使用 Selenium chrome 运行 rspec 测试,但发现了许多错误。最后我将 capybara 连接到远程 capybara ,但现在我得到了这些错误:

有 0 个失败和 2 个其他错误:

 1.1) Failure/Error: visit new_user_session_path

      Selenium::WebDriver::Error::WebDriverError:
        unexpected response, code=404, content-type="text/html"
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="utf-8" />
          <title>Action Controller: Exception caught</title> 

.....................
      Failure/Error: raise Error::WebDriverError, msg

      Selenium::WebDriver::Error::WebDriverError:
        unexpected response, code=404, content-type="text/html"
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="utf-8" />
          <title>Action Controller: Exception caught</title>
          <style>
            body {
              background-color: #FAFAFA;

…………………………………………………………………………

所以这是我的 rails_helper.rb .这真的很乱,因为我尝试了几十次不同的配置
require 'simplecov'
SimpleCov.start
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'turnip/capybara'
require "selenium/webdriver"
require 'capybara-screenshot/rspec'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end
# Checks for pending migration and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
Capybara::Screenshot.register_driver(:headless_chrome) do |driver, path|
  driver.browser.manage.window.resize_to(1600, 1200)
  driver.browser.save_screenshot("tmp/capybara/chrom_#{Time.now}.png")
end
url = 'http://test.prs.com:3001/'



Capybara.javascript_driver = :remote_browser

Capybara.register_driver :headless_chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOqptions: { args: %w(headless disable-gpu no-sandbox) }
  )
end
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOqptions: { args: %w(headless disable-gpu no-sandbox) }
  )
Capybara.default_driver = :remote_browser
Capybara.register_driver :remote_browser do |app|
Capybara::Selenium::Driver.new(app, :browser => :remote, url: url,
  desired_capabilities: capabilities)
end
#   Capybara::Selenium::Driver.new app,
#     browser: :chrome,
#     desired_capabilities: capabilities
# end
Capybara.app_host = "http://#{ENV['APP_HOST']}:#{3001}"
Capybara.run_server = false

Capybara.configure do |config|
  config.always_include_port = true
end
Chromedriver.set_version '2.32'
# Capybara.javascript_driver = :headless_chrome
# Capybara.server_host= '0.0.0.0'
# Capybara.default_host = "http://test.prs.com"
# Capybara.app_host = "#{Capybara.default_host}:#{Capybara.server_port}"

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
  config.include RequestSpecHelper
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.before(:each) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean
 end

  config.before(:all, type: :request) do
    host! 'test.prs.com'
  end

  config.use_transactional_fixtures = true

  config.infer_spec_type_from_file_location!

  config.filter_rails_from_backtrace!

end

这是我的 docker-compose.yml:
   version: '3'
    services:
      db:
        image: postgres
      web:
        build: .
        command: bundle exec rails s -p 3001 -b '0.0.0.0'
        volumes:
          - .:/prs
        ports: ['3000:3000', '3001:3001']
          # - "3001:3001"
        depends_on:
          - db
          - selenium
        extra_hosts:
          - "test.prs.com:127.0.0.1"
        environment:
          - APP_HOST=test.prs.com
        links: 
         - selenium
      selenium:
        image: selenium/standalone-chrome-debug:3.6.0-bromine
          # Debug version enables VNC ability
        ports: ['4444:4444', '5900:5900']
          # Bind selenium port & VNC port
        volumes:
          - /dev/shm:/dev/shm
        shm_size: 1024m
        privileged: true
        container_name: selenium

我对这一切都很陌生,所以任何帮助都将不胜感激。

最佳答案

根据您已澄清的评论,您正在尝试运行 web 中的测试。在 selenium docker 实例中使用 selenium 驱动的浏览器时的 docker 实例。此外,由于您的测试在本地工作,我假设您使用的是 Rails 5.1+,因此功能测试的事务测试将起作用。基于这些参数,需要做一些事情才能使一切正常工作。

  • Capybara 需要启动自己的应用程序副本来运行测试。这是事务测试工作和请求完成检测所必需的。你启用它
    Capybara.run_server = true # You currently have this set to false for some reason
    
  • Capybara 需要在可以从 selenium 访问的界面上运行其应用程序副本 docker 实例。最简单的方法是指定绑定(bind)到 0.0.0.0
    Capybara.server_host = `0.0.0.0`
    Capybara.server_port = 3001 # I'm assuming this is what you want, change to another port and make sure it's reachable from `selenium` instance if desired
    
  • capybara 正在使用的驱动程序需要配置为使用 selenium 实例
    Capybara.register_driver :remote_browser do |app|
      capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
        chromeOptions: { args: %w(headless disable-gpu no-sandbox) }
      )
    
      Capybara::Selenium::Driver.new(app, 
        :browser => :remote, 
        url: "http://selenium:4444",
        desired_capabilities: capabilities
      )
    end
    
    Capybara.javascript_driver = :remote_browser
    # Capybara.default_driver = :remote_browser # only needed if you want all tests to use selenium rather than just JS tagged tests.
    
  • 配置 Capybara 以在访问相对 URL 时使用正确的主机
    Capybara.app_host = "http://web:3001" # a URL that represents the `web` docker instance from the perspective of the `selenium` docker instance
    

  • 注意:如果您希望测试在端口 3001 上运行,如我所料,那么您希望停止 docker 实例启动 rails s在该端口上,因为您希望针对 Capybara 本身启动的应用程序实例运行测试 # command: bundle exec rails s -p 3001 -b '0.0.0.0' .如果您当前在 3001 上运行的实例用于其他用途,那么您将需要一个不同的端口进行测试。

    此外,如果您没有运行 Rails 5.1+,那么您需要设置 config.use_transactional_fixtures = false并完全配置database_cleaner - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example .如果您使用的是 Rails 5.1+,那么您可能可以删除所有 database_cleaner 内容。

    关于ruby-on-rails - 带有 Rails 测试的 Dockerized Selenium,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46847118/

    相关文章:

    ruby-on-rails - 更改 Simple_Form 提交按钮操作?

    ruby-on-rails - 使用 rspec 测试链接?

    java - 如何检查 URL 中的视频加载情况?

    docker - 如何配置 NGINX 以从 UNIX 套接字服务 ASGI?

    ruby-on-rails - Rails PgBouncer client_idle_timeout

    ruby-on-rails - Rails 3.1 每当 gem 在开发中工作但不在生产中工作时。为什么?

    java - 无法使用 Selenium WebDriver 定位现有元素

    c# - 我如何定义单元测试的不同顺序?

    windows - 每月在 Windows 上安排 Docker RUN 命令

    docker - 如何通过 dotnet sdk 将 .dcproj 添加到解决方案中