The Appium code base is a literal mess, so I'm going to give examples based on the Sauce Client gem I'm writing.
What I want to do is take actions before & after driver initialization, add a #sauce method for interacting with our API and annotations, and take additional actions before the #quit method.
Let's start with what works before selenium-webdriver-3.4.1.gem:
Subclassing the Bridge
This no longer works because Selenium::WebDriver::Remote::Bridge can't be initialized with a :desired_capabilities parameter. (ArgumentError: unknown option: {:desired_capabilities=> ...)
I get that with the handshake this implementation probably doesn't work. It also has the disadvantage of requiring duplication of event listener handling if present.
So I tried implementing this with composition. This mostly works except that I have to add the #method_missing and the #respond_to?, as well as needing to do @driver.driver to get the instance of the Remote::Driver instead of just @driver. Additionally, I can't do Watir::Browser.new(@driver), because Watir is looking for @driver to be an instance of Selenium::WebDriver::Driver, and it isn't.
(The other sticking point here is that while the above code worked in selenium-webdriver-3.4.2.gem it is broken in selenium-webdriver-3.4.3.gem).
So this brings us to what I really want. A subclass of Selenium::WebDriver::Driver.
This is the classic use case of inheritance. The Sauce driver *is a driver with a couple extra behaviors. Ideally, this is what I think it should look like to the user. #super in the right spots, with the extra method that doesn't require monkey patching, or duplicating code for handshake or listeners.
Hopefully this clarifies what I'm looking for. I have a couple ideas for what might work as far as an implementation, but I haven't had a chance to dig into it yet.
The Appium code base is a literal mess, so I'm going to give examples based on the Sauce Client gem I'm writing.
What I want to do is take actions before & after driver initialization, add a
#saucemethod for interacting with our API and annotations, and take additional actions before the#quitmethod.Let's start with what works before
selenium-webdriver-3.4.1.gem:Subclassing the Bridge
This no longer works because
Selenium::WebDriver::Remote::Bridgecan't be initialized with a:desired_capabilitiesparameter. (ArgumentError: unknown option: {:desired_capabilities=> ...)I get that with the handshake this implementation probably doesn't work. It also has the disadvantage of requiring duplication of event listener handling if present.
So I tried implementing this with composition. This mostly works except that I have to add the
#method_missingand the#respond_to?, as well as needing to do@driver.driverto get the instance of theRemote::Driverinstead of just@driver. Additionally, I can't doWatir::Browser.new(@driver), because Watir is looking for@driverto be an instance ofSelenium::WebDriver::Driver, and it isn't.(The other sticking point here is that while the above code worked in
selenium-webdriver-3.4.2.gemit is broken inselenium-webdriver-3.4.3.gem).So this brings us to what I really want. A subclass of
Selenium::WebDriver::Driver.This is the classic use case of inheritance. The Sauce driver *is a driver with a couple extra behaviors. Ideally, this is what I think it should look like to the user.
#superin the right spots, with the extra method that doesn't require monkey patching, or duplicating code for handshake or listeners.Hopefully this clarifies what I'm looking for. I have a couple ideas for what might work as far as an implementation, but I haven't had a chance to dig into it yet.