Watir Wait

http://vaderpi.com/blog/?p=630

I have been working with over the last couple of days. I quickly became frustrated with numerous errors claiming that the element I wanted to perform an operation on did not exist. I found the Watir::Waiter class and started using it extensively. So extensively, that I decided to write a little monkey patch to make my life easier.

The application that I am working with performs a lot of client-side DOM manipulation. This can create instances where my script was asking Watir to perform operations on DOM objects that didn’t exist. To defend against that, every time that I called click or set or select on various DOM objects, I wrote two additional statements. One to make sure the browser had finished whatever it was working on, and one to make sure that the element I was about to interact with actually existed.

The code looked something like this.

@browser = Watir::Browser.new
@browser.goto("http://localhost")
@browser.wait
Watir::Waiter.wait_until { @browser.text_field(:name, /UserName/).exists? }
@browser.text_field(:name, /UserName/).set("Admin")
@browser.wait
Watir::Waiter.wait_until { @browser.text_field(:name, /Password/).exists? }
@browser.text_field(:name, /Password/).set("Password")
@browser.wait
Watir::Waiter.wait_until { @browser.button(:name, /Submit/).exists? }
@browser.button(:name, /Submit/).click

While that works, I got really sick of having to re-type the selector for the DOM element that I wanted to muck with. What I wanted to do was write code that looked something like this.

@browser = Watir::Browser.new
@browser.goto("http://localhost")
@browser.text_field(:name, /UserName/).wait_to_set("Admin")
@browser.text_field(:name, /Password/).wait_to_set("Password")
@browser.button(:name, /Submit/).wait_to_click

Wow. That is much more concise and easier to understand. Even a non-programmer can understand what is happening now.

To make this code actually work, I decided to write a quick monkey patch that adds a “wait_to_” alternative for every method that can be called on input elements and links. These methods call @browser.wait, ask Watir::Waiter to wait for the element to exist, and then call the requested method.

I called my monkey patch Watir Wait. (Get it? I crack myself up! :)) Take a peek and let me know what you think. If I get enough positive feedback, I’ll rework this into a proper patch and submit it to the Watir team for inclusion.

require 'watir'
require 'watir/container'
require 'watir/element'
require 'watir/input_elements'
require 'watir/link'
def support_wait_to_methods
timeout_in_seconds = 30
original_method_missing = self.instance_method(:method_missing)
define_method(:method_missing) do |symbol, *args|
name = symbol.id2name
if name =~ /^wait_to_/
new_symbol = name.gsub("wait_to_", "").to_sym
self.wait
Watir::Waiter.wait_until(timeout_in_seconds) do 
exists_and_contains_option_if_select?(new_symbol, args)
end
self.send(new_symbol, *args)
else
original_method_missing.bind(self).call(symbol, args)
end    
end  
def exists_and_contains_option_if_select?(symbol, args)
result = false
if self.exist?
result = true
# I really don't like sticking this here. It violates my
# desgin sense, but I am going to leave it here for now
# because I am lazy. This will get reworked if I roll this
# into a proper patch.  
if symbol == :select
self.locate
result = self.include?(args[0])
end
end
result
end
end
class Watir::InputElement 
support_wait_to_methods
end
class Watir::Link
support_wait_to_methods
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值