在watir中自动执行超时处理(等待和刷新)

时间:2013-08-13 09:06:39

标签: ruby timeout wait watir-webdriver rescue

我一直都知道良好的编码意味着:不要重复自己。但是这些天我不断重复自己,试图让我的刮刀处理超时错误。

对于我点击的每个链接或按钮,我添加了一个救援Exception => e并刷新页面。

例如

browser.link(:xpath, "//tr[@class='pager'][1]/td/a").when_present.click

变成

begin
  browser.link(:xpath, "//tr[@class='pager'][1]/td/a").wait_until_present
  browser.link(:xpath, "//tr[@class='pager'][1]/td/a").click
rescue Exception => e
  sleep (10)
  puts "timed out, let's refresh"
  browser.refresh
end

也许有一个更清洁,不重复的解决方案。我已经尝试过操纵Watir :: wait但我无法让它工作..

class Watir::Wait
  alias_method :__do_wait, :wait_until
  def wait_until
    begin
      __do_wait{ yield }
    rescue Exception => e
      puts "timed out. let's refresh"
      $browser.refresh
    end
  end
end

2 个答案:

答案 0 :(得分:2)

如果我正确理解您的要求,我认为您想要覆盖对WhenPresentDecorator的method_missing处理。

require 'watir-webdriver'

module Watir
  class WhenPresentDecorator
    def method_missing(m, *args, &block)
      unless @element.respond_to?(m)
        raise NoMethodError, "undefined method `#{m}' for #{@element.inspect}:#{@element.class}"
      end

      begin
        Watir::Wait.until(@timeout, @message) { @element.present? }
      rescue
        sleep(10)
        puts "timed out, let's refresh"
        @element.browser.refresh
      else
        @element.__send__(m, *args, &block)
      end
    end
  end # WhenPresentDecorator  
end

使用这个猴子补丁,when_present将等待元素出现。如果元素存在,它将执行操作(即在您的示例中单击)。如果元素不存在,它将捕获异常,忽略它,刷新页面并继续下一个语句。

例如,给定以下页面,其中包含显示页面加载时间的div标记:

<html>
  <head>
    <script>
      function startTime()
      {
        var today=new Date();
        var h=today.getHours();
        var m=today.getMinutes();
        var s=today.getSeconds();
        document.getElementById('txt').innerHTML=h+":"+m+":"+s;
      }
    </script>
  </head>
  <body onload="startTime()">
    <div id="txt"></div>
  </body>
</html>

您可以看到访问确实存在的元素(链接)时不会发生异常。同样,在尝试查找该元素后,页面会刷新。

puts browser.div(:id => 'txt').text  
#=> "22:48:25"

browser.link(:id => 'asdf').when_present.click
#=> "timed out, let's refresh"

puts browser.div(:id => 'txt').text
#=> "22:48:36"

答案 1 :(得分:1)

抱歉我的英语,我是法国人....大声笑这个脚本允许刷新浏览器而不跳过一步,例如当你必须登录时,你不能跳过一步......如果你的网站链接太多而且带宽太低......

我认为seeb会这样做:

module Watir

class WhenPresentDecorator
def method_missing(m, *args, &block)
  unless @element.respond_to?(m)
    raise NoMethodError, "undefined method `#{m}' for #{@element.inspect}:#   {@element.class}"
  end

  begin
    while !@element.present? 
     sleep(10)
    puts "timed out, let's refresh"
    @element.browser.refresh
    end
   rescue

   else
     @element.__send__(m, *args, &block)
   end
      end
     end # WhenPresentDecorator  
   end