In watir-classic gem, we have a method called generate_ruby_code() under Element class. I would like to monkey patch it and modify few things.
What I did is:
require 'watir-classic'
module Watir
class Element
def generate_ruby_code(element, method_name, *args)
puts "Print this"
end
end
end
But instead of calling my monkey patched method, the original generate_ruby_code in the Element class is called everytime which I don't want to happen.
Please help me to solve this issue.
Problem
I assume that you are using watir-classic v3.7.0 or older.
In these versions, doing require 'watir-classic'
does not load all of the classes immediately. Some of the classes, including the Watir::Element, are not loaded until a browser instance is created.
This means that:
# Does not create Watir::Element#generate_ruby_code yet
require 'watir-classic'
# You create a Watir::Element#generate_ruby_code method
module Watir
class Element
def generate_ruby_code(element, method_name, *args)
puts "Print this"
end
end
end
# Watir loads the Watir::Element#generate_ruby_code, which overrides yours
browser = Watir::Browser.new
My understanding is that this is due tp watir-classic previously supporting multiple browsers - ie FireWatir and SafariWatir. Various classes were autoloaded based on the browser being used.
Solution 1 - Upgrade to v4.0 or later
The easiest solution is to upgrade your watir-classic to v4.0 or later (current latest is 4.0.1).
The autoloading was removed in this version, which means your code will now work as is.
Solution 2 - Initialize browser first
If upgrading is not an option, you need to manually force the autoload before monkey patching. You can do this by simply referencing the constant with:
Watir::IE
Simply include this at some point after requiring watir-classic and before monkey patching.
require 'watir-classic'
Watir::IE # this will load the code
module Watir
class Element
def generate_ruby_code(element, method_name, *args)
puts "Print this"
end
end
end
browser = Watir::Browser.new
browser.goto 'www.google.ca'
browser.link.click_no_wait
#=> "Print this"
Look, I do not know what exactly is happening in your case, but you can safely rule out Ruby malfunctioning. Here are a couple of hints what you can do:
# Assuming that your element of class Watir::Element is stored in variable x:
x.method( :generate_ruby_code ).owner # will give you the owning module
x.method( :generate_ruby_code ).source_location # will give you the place where the method is,
# that is going to be used when you send x the message :generate_ruby_code
x.class # will confirm that your object indeed is what you think it is
x.singleton_class.ancestors # will give you the full method lookup chain for x
With this, you shoul be equipped to uncover why your expectations for x's behavior are not met.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.