ironsand
ironsand

Reputation: 15181

How to override class methods

I want to override the method Selenium::WebDriver.for. This is what I tried:

module SeleniumWebDriverExtension
  def self.for(browser, *args)
    if browser != :phantomjs
      super(browser, *args)
    else
      options = {
          "phantomjs.cli.args" => ["--ssl-protocol=tlsv1"]
      }
      capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs(options)
      super(browser, desired_capabilities: capabilities)
    end
  end
end

Selenium::WebDriver.prepend(SeleniumWebDriverExtension)

But I got error when Selenium::Webdriver.for(:phantomjs) is called.

NoMethodError: super: no superclass method `for' for Selenium::WebDriver::Driver:Class

How can I call the original method from the overriding method?

Upvotes: 7

Views: 3240

Answers (2)

mhaseeb
mhaseeb

Reputation: 1779

When to you use self inside a module like this:

def self.for(browser, *args)

end

it is declared as a module function, not an instance method on the class that will include this module. What this means is that won't appear on included classes when the module is mixed into another class.

It is similar to writing:

 def SeleniumWebDriverExtension::for
 end

So if you want to call super from within the module, declare it as a simple instance method like the accepted answer has suggested. Just wanted to clear you on the reasoning behind this.

Btw SeleniumWebDriverExtension.ancestors to be clear on the inheritance hierarchy.

Upvotes: 4

sawa
sawa

Reputation: 168269

module SeleniumWebDriverExtension
  def for(browser, *args)
    ...
  end
end

Selenium::WebDriver.singleton_class.prepend(SeleniumWebDriverExtension)

Upvotes: 10

Related Questions