配置 Capybara + Selenium 以通过 SSL 进行测试

Posted

技术标签:

【中文标题】配置 Capybara + Selenium 以通过 SSL 进行测试【英文标题】:Configuring Capybara + Selenium to test over SSL 【发布时间】:2018-10-24 09:42:53 【问题描述】:

我的应用程序的核心部分调用 Etsy API。 我正在尝试使用 Rspec、Capybara 和 Selenium 编写测试来测试该 API。 在我打了一个成功的电话后,我想把它们排除在外。

我的问题是 Etsy 身份验证过程仅适用于 SSL。因此,当我尝试使用 http 进行测试时,出现错误 400。

我使用此tutorial 设置 SSL,但我不断收到此错误:

  1) New connection authenticates with Etsy
     Failure/Error: res = http.get('/__identify__')

     OpenSSL::SSL::SSLError:
       SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol
     # ./spec/spec_helper.rb:68:in `responsive?'

这是我的 spec_helper.rb:

require 'webmock/rspec'
require 'capybara/rspec'
include WebMock::API
require 'etsy'
WebMock.disable_net_connect!(allow_localhost: true)
#Capybara.current_driver = :selenium
Capybara.default_max_wait_time = 20

require 'webrick/https'
require 'rack/handler/webrick'

def run_ssl_server(app, port)

  opts = 
    :Port => port,
    :SSLEnable => true,
    :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
    :SSLPrivateKey => OpenSSL::PKey::RSA.new("./spec/support/server.key"),
    :SSLCertificate => OpenSSL::X509::Certificate.new(File.read "./spec/support/server.crt"),
    :SSLCertName => [["US", 'localhost.key']],
    :AccessLog => [],
    :Logger => WEBrick::Log::new(Rails.root.join("./log/capybara_test.log").to_s)
  
  profile = Selenium::WebDriver::Firefox::Profile.new
  profile.assume_untrusted_certificate_issuer = false

   Capybara::Driver::Selenium.new(app, :browser=> :firefox, :profile => profile)
  Rack::Handler::WEBrick.run(app, opts)
end

Capybara.server do |app, port|
  run_ssl_server(app, port)
end

Capybara.server_port = 3001
Capybara.app_host = "https://localhost:%d" % Capybara.server_port

  Capybara.register_driver :selenium do |app|
    profile = Selenium::WebDriver::Firefox::Profile.new
    profile.assume_untrusted_certificate_issuer = false
    Capybara::Selenium::Driver.new(app, :profile => profile)
  end

module Capybara
  class Server
    def responsive?
      return false if @server_thread && @server_thread.join(0)

      http = Net::HTTP.new(host, @port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      res = http.get('/__identify__')

      if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
        return res.body == @app.object_id.to_s
      end
    rescue SystemCallError
      return false
    end
  end
end

提前致谢!

【问题讨论】:

【参考方案1】:

您的run_ssl_server 中似乎有多余的东西,这没有任何意义

profile = Selenium::WebDriver::Firefox::Profile.new
profile.assume_untrusted_certificate_issuer = false

Capybara::Driver::Selenium.new(app, :browser=> :firefox, :profile => profile)

所以我认为这只是一个复制/粘贴错误?

继续处理您遇到的错误似乎是在告诉您连接不知道/不支持 SSLv2/SSLv3 协议。您可以通过指定 SSLOptions、SSLCiphers 和 SSLVersion 选项在 WEBRick 选项中禁用它们,如 How to harden rails+webrick+https with insecure ciphers removed on Ruby 2.2 中所示

一个更简单的选择可能是不注册自己的服务器、修补 Capybara、修复服务器端口或设置app_host,而是切换到使用 Capybara >= 3.1.0 并配置 Puma 以运行 SSL

Capybara.server = :puma,  Host: "ssl://#Capybara.server_host?key=#key_file_path&cert=#cert_file_path" 

然后您可以使用 Selenium 注册您使用的任何浏览器以允许自签名证书(如果需要)

Capybara.register_driver :insecure_selenium do |app|
  Capybara::Selenium::Driver.new(
    app,
    browser: :firefox,
    desired_capabilities:  accept_insecure_certs: true 
  )
end

Capybara.javascript_driver = :insecure_selenium # https://github.com/teamcapybara/capybara#drivers

【讨论】:

非常感谢@Thomas!这绝对是对我所做工作的巨大改进,但在我看来,服务器仍然以常规 http 而非 https 启动:Capybara 启动 Puma... * 版本 3.11.4,代号:Love Song * 最小线程:0,最大线程数:4 * 正在侦听 tcp://127.0.0.1:44047 并且打开的浏览器正在使用 http。非常感谢您的帮助,谢谢! @MaayanNaveh 听起来你有一些东西覆盖了你的Capybara.server 设置。您是否有机会在 Rails 5.1 上使用系统测试? Rails 5.1 中有一个错误,它会覆盖用户设置的任何服务器。它已在 github.com/rails/rails/commit/… 中修复。如果你不能升级到 Rails 5.2,你可以猴子补丁 ActionDispatch::SystemTestings::Server#set_server 什么都不做 - github.com/rails/rails/blob/5-1-stable/actionpack/lib/… 感谢您的建议!这是 rspec 中的功能测试。 @MaayanNaveh 你确定这是一个“功能”测试,而不是现在在 RSpec 中使用“系统”测试?如果它是“功能”测试,那么寻找其他任何地方 Capybara.server 正在设置,并确保您的设置在加载顺序之后发生。另外,我假设您正在运行 Capybara 3.1,并且您将密钥和证书文件的位置添加到我在答案中显示的服务器声明中。 它肯定在 features 文件夹中,我已经根据位置推断出类型。我搜索了所有项目文件,没有找到其他 Capybara 服务器。我正在使用您建议的解决方案,是的。我尝试从 master 分支降级到正式版本,它使用 ssl 启动服务器:但是当我升级到 master 分支时,同样的事情发生了,它以 http 开头。当我“降级”时,它以 ssl 开始,然后 selenium 被拒绝,因为它是自签名的,所以我被困在第 1 格:(

以上是关于配置 Capybara + Selenium 以通过 SSL 进行测试的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Capybara + Selenium 测试响应代码

在 Rails 中使用 Capybara 和 Selenium 测试 Google 地图标记

如何以较低的速度运行 Selenium(通过 Capybara 使用)?

Cucumber, capybara and selenium - 无需按钮即可提交表单

使用 selenium ruby​​ capybara 拖放

Cucumber / Capybara 错误:参数 [0] 未定义(Selenium::WebDriver::Error::JavascriptError)