Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use selenium webdriver as a baseclass python

I searched for a while for this one and was surprised i couldn't find anything, maybe because it's simple. I've been programming in python for about 3 months doing automated testing with selenium webdriver. I was thinking it would be convenient to have a class inherit from my webdriver class to add more functionality to it.

    from selenium import webdriver

    class myPage(webdriver):

          def __init__(self):
                super(myPage, self).__init__()

          def set_up(self):
                #doStuff...

but when i do this i get the error>>>

    File "c:\Users\me\...\myProgram.py", line 6, in <module>
        class myPage(webdriver):
    TypeError: module.__init__() takes at most 2 arguments (3 given)

When I create the myPage object the code is...

    from myProgram import myPage
    class Test():
          def do(self):
                self.browser = myPage.Firefox()

So it goes through and does the self.browser = myPage.Firefox() line and when it runs the .__init__() somehow it gives it three arguments and I'm not sure where they come from. I'm clearly missing something because inheritance isn't hard to do. Thanks for any help

like image 778
ReckerDan Avatar asked Jun 02 '14 18:06

ReckerDan


2 Answers

You'd have to change:

class myPage(webdriver)

To:

class myPage(webdriver.Firefox)

However that would remove the ability to choose the browser you would like to run it on. This is because webdriver isn't actually a class, but a package (I believe). When you call something like: webdriver.Firefox() it is actually an instance of the Firefox class, not the webdriver class. To get what you desire you're probably better off doing something like this:

from selenium import webdriver

class myPage(webdriver.Firefox, webdriver.Chrome, webdriver.Ie):
    def __init__(self, browser):
        if browser.lower() == "ie":
            webdriver.Ie.__init__(self)
        elif browser.lower() == "chrome":
            webdriver.Chrome.__init__(self)
        else:
            webdriver.Firefox.__init__(self)
like image 108
Bob Avatar answered Oct 22 '22 11:10

Bob


The best way to do it is to inherit from webdriver.Remote.

what is selenium remote?

selenium remote is basically a way to run selenium on another server, but it can be used locally (and works like a charm).
The advantage here is that you will have one interface that works for all browsers, and supports both local and remote execution.

In the future, you might want to run tests in multiple servers via some CI tool, so this can come in handy.

implementation

class izWebDriver(webdriver.Remote):
"""
iz implementation for selenium remote web-driver    
"""
def __init__(self, url, capabilities):
    super().__init__(url, capabilities)

## add more custome functions here !

How to use this implementation

new_driver = izWebDriver(driver_url, DesiredCapabilities.CHROME)

I did some more abstractions, to basically be able to do get_driver(browser='chrome').

A reference - my working framework

Take a look at my own selenium wrapper for reference, It has some knit capabilities like

  • sharing a driver between tests\projects (for testing integration between to GUIs for example).
  • Retries before failing, for example - element.click() tries to click using JS event before failing.

and many more

All the code is available in this github repo
the actual selenium wrapper is in Core folder.
Also, here is an example of a project implemented using my framework

like image 28
itay zohar Avatar answered Oct 22 '22 10:10

itay zohar