我一直都知道良好的编码意味着:不要重复自己。但是这些天我不断重复自己,试图让我的刮刀处理超时错误。
对于我点击的每个链接或按钮,我添加了一个救援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
答案 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