Improving Watir::Browser for my needs I want to:


use Watir::Browser methods without browser. instance prefix
expand abilities of Watir::Browser using own methods and overload existing
since I don't need more than one browser launched at the same time, using Module seems to have more sense than class


Here is my try:

require "watir"

module Session_FF
    class &lt;&lt; self; attr_accessor :browser end
    def self.element *args
        es = browser.elements *args
        raise "found #{es.size} nodes instead of one" if es.size &gt; 1
        es.first
    end
    def self.method_missing m, *args, &amp;block
        browser.send m, *args, &amp;block
    end
end
def session_FF &amp;block
    Session_FF::browser = Watir::Browser.new :ff
    Session_FF.module_eval &amp;block
ensure
    Session_FF::browser.quit if Session_FF::browser
end

session_FF do 
    goto "http://localhost/"
    element(text:"test").click
    #
    #
    #
end


Seems to be more complex, than I expected. How do you think?
I don't know if you can make it less complex in terms of lines of code, but I'd recommend structuring it a bit differently.

You've already got class &lt;&lt; self around the attr_reader, so you might as well wrap the remaining methods in it.

You've also got the session_FF method that's independent of the module it "belongs to", and which messes with the module's static variables. Just for convenience, it'd be nice to keep things more encapsulated.

Here's my take:



module Session_FF
  class &lt;&lt; self
    def element *args
      elements = browser.elements *args
      raise "found #{es.size} nodes instead of one" if elements.size &gt; 1
      elements.first
    end

    def method_missing m, *args, &amp;block
      browser.send m, *args, &amp;block
    end

    # lazily instantiate a browser
    def browser
      @browser ||= Watir::Browser.new :ff
    end

    # quit and nil the browser instance
    def quit
      @browser.quit if @browser
      @browser = nil
    end
  end

  # included method
  def session_FF &amp;block
    Session_FF.module_eval &amp;block
  ensure
    Session_FF.quit
  end
end


which you can then include in your test code:

include Session_FF

session_FF do
  element(text: "test").click
  # ...
end


I'm guessing "FF" means "Firefox", so I'd probably just call the proxy method firefox, and the module FirefoxSession, but that's a different story.