Selenium chromedriver 不适合 at_exit

Selenium chromedriver not playing nice with at_exit

这是我的代码中的错误,还是 Selenium、RSpec 等中的错误?

我正在编写的 Cucumber 测试需要关闭并重新启动 Chrome 驱动程序。但是,我无法让第二个驱动程序正常关闭。下面的精简示例显示了问题:(下面的代码是 RSpec 只是因为它在没有增加 Cucumber 的复杂性的情况下演示了这个问题。)

require 'selenium-webdriver'

RSpec.configure do |config|
       config.before(:suite) do
           $driver = Selenium::WebDriver.for :chrome
         end
     end

describe "A potential rspec/selenium/chrome driver bug" do 
  it "doesn't play nice with at_exit" do    
    # quit the initial driver and start a new one.
    $driver.quit
    $driver = Selenium::WebDriver.for :chrome    
  end # it
end # end describe

at_exit do
  $driver.quit
end

当我 运行 此代码时,出现以下错误:

/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:878:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED)
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:878:in `open'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:878:in `block in connect'
    from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/timeout.rb:52:in `timeout'

我可以看出,当 at_exit 块 运行s 时,第二个 chromedriver 进程不再 运行ning。这会导致问题,因为导致关闭的任何机制都会使 Chrome window 打开。

RSpec 的 after(:suite) 机制按预期工作。 Cucumber 是否有相应的机制(除了 at_exit,在这种情况下不起作用)?或者,有没有办法防止 chomedriver 在 at_exit 块 运行 之前退出(这样我就可以按预期使用 quit 方法将其关闭)?

我正在 运行ning Ruby 2.0.0 on Mac OS 10.9.5 使用最新的 selenium 和 rspec 包。

问题是我的代码中的错误。需要在 env.rb 定义自己的 at_exit 钩子之前创建驱动程序。原因如下:

黄瓜的典型 env.rb 如下所示:

$driver = Selenium::WebDriver.for :chrome, :switches => %w[--disable-cache --ignore-certificate-errors]

at_exit do
  $driver.quit
end

创建驱动程序对象 (Selenium::WebDriver.for :chrome) 的代码还注册了一个 at_exit 挂钩,用于关闭 chromedriver 进程。

at_exit 以相反的创建顺序挂钩 运行。因此,典型的 cucumber 执行如下所示:

  1. env.rb 创建新驱动程序
  2. 驱动程序定义 at_exit 挂钩以退出自身
  3. env.rb 定义 at_exit 挂钩以退出驱动程序
  4. 黄瓜的特点运行
  5. at_exit 来自 env.rb 的钩子被调用
  6. 驱动程序的 at_exit 钩子被调用

在我的例子中,我在 cucumber 功能中创建了一个驱动程序,这导致驱动程序的 at_exit 挂钩在 env.rb 中的 at_exit 挂钩之后定义。结果,驱动程序的 at_exit hook 首先 运行s,导致 env.rb 中对 $driver.quit 的调用失败。

在这种情况下,最好的解决方案是在必要时创建第二个驱动程序,并在场景结束时销毁第二个驱动程序(而不是用新驱动程序替换主驱动程序)。

感谢 Alex Rodionov 指出我的错误。 https://github.com/SeleniumHQ/selenium/issues/742