Make Watir Support Jquery event
I have been in use watir(1.8.0) and ruby(1.8.7) for Regression test recently. I've got a problem yesterday. Look the demonstration page below:
<html> <head> <script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script> </head> <body> <select id ="s1"> <option value="1">123</option> <option value="2">456</option> <option value="3">789</option> </select> <script> $('#s1').change(function(){ alert('fired'); }); </script> </body> </html>
when I use the code below to hope fire the change event of select element,but it can't work.
require "watir" @browser = Watir::Browser.new @browser.goto('a.html') @browser.select_list(:id, 's1').set('456')
I deep in to the source code of watir(1.8.0),and found the code that:
def select_item_in_select_list(attribute, value) #:nodoc: assert_exists highlight(:set) found = false value = value.to_s unless [Regexp, String].any? { |e| value.kind_of? e } @container.log "Setting box #{@o.name} to #{attribute.inspect} => #{value.inspect}" @o.each do |option| # items in the list if value.matches(option.invoke(attribute.to_s)) if option.selected found = true break else option.selected = true @o.fireEvent("onChange") @container.wait found = true break end end end unless found raise NoValueFoundException, "No option with #{attribute.inspect} of #{value.inspect} in this select element" end highlight(:clear) end
As the code show,Watir calling API of win32ole object,and raise the native event "onChange".but this couldn't fire "change" event which jquery support. It's so tricky!
After a research in google.i got this answer from StackOverFlow.
@browser = Watir::Browser.new @browser.goto("http://someurl") @browser.select_list(:id, element_id).select(item_to_select) @browser.ie.Document.parentWindow.execScript('$("##{element_id}").change();')
it's really cool method and seems resolved my problem(Let's say WATIR SUCKS loudly ). I couldn't use this directly because this is just a demonstration.In production environment,there are a lot of same invoke.To avoid duplication code,i have to extend watir to support our requirement.
...................... ............ option.selected = true @o.fireEvent("onChange") script = %Q{$("##{self.id}").change();} @o.Document.parentWindow.execScript(script) @container.wait found = true break ............. ................
It works well now!