If I understand your requirements correctly, I think you want to override the method_missing
handling of the WhenPresentDecorator.
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
With this monkey patch, when_present
will wait for the element to be present. If the element is present, it will perform the action (ie click in your example). If the element is not present, it will catch the exception, ignore it, refresh the page and continue on to the next statement.
For example, given the following page that has a div tag that shows the time of page load:
<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>
You can see that no exception occurs when accessing an element (link) that does exist. As well, the page refreshes after trying to find that element.
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"