Selenium chromedriver与at_exit不一致

时间:2015-07-05 17:30:53

标签: ruby google-chrome selenium rspec atexit

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

黄瓜测试我写作需要关闭并重新启动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块运行时,第二个chromedriver进程不再运行。这会导致问题,因为导致关机的任何机制都会使Chrome窗口保持打开状态。

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

我使用最新的selenium和rspec软件包在Mac OS 10.9.5上运行Ruby 2.0.0。

1 个答案:

答案 0 :(得分:2)

问题是我的代码中存在错误。需要在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个钩子以与创建它们相反的顺序运行。因此,黄瓜的典型执行方式如下:

  1. env.rb创建新驱动程序
  2. 驱动程序定义at_exit挂钩以自行退出
  3. env.rb定义at_exit挂钩以退出驱动程序
  4. 黄瓜功能运行
  5. 来自at_exit
  6. env.rb挂钩被称为
  7. 驱动程序的at_exit挂钩称为
  8. 就我而言,我在黄瓜功能中创建了一个驱动程序,导致驱动程序的at_exit挂钩在at_exit env.rb挂钩后定义。因此,驱动程序的at_exit挂钩首先运行,导致$driver.quitenv.rb的调用失败。

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

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