Watir implicit_wait似乎不起作用

时间:2013-06-21 18:53:27

标签: watir watir-webdriver

我们目前正在使用带有firefox的watir-webdriver(0.6.2)来运行验收测试。 我们的测试需要很长时间才能运行,并且通常会因超时错误而失败。 我们希望减少超时时间,以便它们更快地失败。

我们尝试过:

browser = Watir::Browser.new("firefox")
browser.driver.manage.timeouts.implicit_wait=3 

但是,我们仍然会遇到30秒的超时。

我们无法找到有关此问题的任何文档或问题。有谁知道如何正确配置Watir等待超时?

3 个答案:

答案 0 :(得分:6)

这完全取决于'超时'的含义。在讨论Watir-Webdriver时,AFAIK有三种不同的超时定义:

  1. 浏览器等待页面加载多长时间?
  2. Watir-Webdriver 明确等待多长时间,然后在被告知等待“.when_present”函数时,将元素“不存在”或“不可见”等待
  3. 在考虑元素“不存在”或“不可见”之前,Watir-Webdriver 隐式等待对象出现多长时间(当不等待显式调用时请参阅#2)
  4. #1:页面加载

    Justin Ko是正确的,你可以设置页面加载超时,如果你的目标是修改它,虽然看起来这样做的规范方法是在创建浏览器并将其传递给浏览器之前设置客户端超时在创作:

    client = Selenium::WebDriver::Remote::Http::Default.new
    client.timeout = 180 # seconds – default is 60
    
    b = Watir::Browser.new :firefox, :http_client => client
    

    - Alistair Scott, 'How do I change the page load Timeouts in Watir-Webdriver'

    #2:显式超时

    但我认为@ p0deje说你正在经历明确的超时是正确的,尽管如果没有看到你的代码就无法肯定地说。在下面我经历了明确的声明覆盖了隐含的(我不确定这是否是故意的):

    b = Watir::Browser.new :firefox
    b.driver.manage.timeouts.implicit_wait = 3 
    puts Time.now #=> 2013-11-14 16:24:12 +0000
    begin
      browser.link(:id => 'someIdThatIsNotThere').when_present.click
    rescue => e
      puts e #=> timed out after 30 seconds, waiting for {:id=>"someIdThatIsNotThere", :tag_name=>"a"} to become present
    end
    puts Time.now #=> 2013-11-14 16:24:43 +0000
    

    由于'when_present',默认情况下Watir-Webdriver会在失败前等待30秒。或者,您可以说'when_present(10)'来更改默认值并等待10秒。 (Watir-Webdriver > Watir::Wait#when_present。)我无法以任何方式在全球范围内做到这一点。除非你找到这样的东西 - 如果你这样做,请告诉我 - 必须在每次通话时完成。 :( 编辑Fellow answerer Justin Ko gave me the answer as to how to do what I described above编辑2 :@jarib将这个添加到Watir,每个@justinko链接的答案:“更新:这个猴子补丁已经合并到watir-webdriver中,因此在watir-webdriver v0.6.5中将不再需要。您可以使用以下命令设置超时:Watir.default_timeout = 90“

    #3隐式超时

    您提供的代码设置了Watir-Webdriver等待任何元素出现的时间,而您没有明确说明:

    b = Watir::Browser.new :firefox
    b.driver.manage.timeouts.implicit_wait = 3 
    puts Time.now #=> 2013-11-14 16:28:33 +0000
    begin
      browser.link(:id => 'someIdThatIsNotThere').when_present.click
    rescue => e
      puts e #=> unable to locate element, using {:id=>"someIdThatIsNotThere", :tag_name=>"a"}
    end
    puts Time.now #=> 2013-11-14 16:28:39 +0000
    

答案 1 :(得分:3)

implicit_wait是selenium-webdriver在超时前尝试查找元素的时间。默认值为0秒。通过将其更改为“3”,您实际上增加等待的时间。

我猜你实际上想要更改等待页面加载的超时(而不是查找元素)。这可以通过以下方式完成:

browser.driver.manage.timeouts.page_load = 3

例如,我们可以说加载Google只需等待0秒:

require 'watir-webdriver'
browser = Watir::Browser.new :firefox
browser.driver.manage.timeouts.page_load = 0
browser.goto 'www.google.ca'
#=> Timed out waiting for page load. (Selenium::WebDriver::Error::TimeOutError)

答案 2 :(得分:0)

更新:自Watir 6.5起,默认超时可使用

进行配置
Watir.default_timeout = 3

我们遇到了同样的问题,并选择覆盖涉及超时的Watir方法,即

  • Watir::Wait.until { ... }
  • Watir::Wait.while { ... }
  • object.when_present.set
  • object.wait_until_present
  • object.wait_while_present

以下是代码,如果使用spec_helper.rb

,您可以将其放入rspec
# method wrapping technique adapted from https://stackoverflow.com/a/4471202/177665
def override_timeout(method_name, new_timeout = 3)
  if singleton_methods.include?(method_name)
    old_method = singleton_class.instance_method(method_name)

    define_singleton_method(method_name) do |timeout = new_timeout, *args, &block|
      old_method.bind(self).(timeout, *args, &block)
    end
  else
    old_method = instance_method(method_name)

    define_method(method_name) do |timeout = new_timeout, *args, &block|
      old_method.bind(self).(timeout, *args, &block)
    end
  end
end

# override default Watir timeout from 30 seconds to 3 seconds
module Watir
  module Wait
    override_timeout(:until)
    override_timeout(:while)
  end

  module EventuallyPresent
    override_timeout(:when_present, 5) # 5 secs here
    override_timeout(:wait_until_present)
    override_timeout(:wait_while_present)
  end
end

我们使用https://stackoverflow.com/a/4471202/177665的答案让它发挥作用。