Thursday, August 24, 2017

Selenium Python Object Repository - Using decorator

In the series of posts I will try to explain how to create the object repository when you are writing selenium tests using python. There are different ways, few more simple than others but finally it's upto you which to use and how to use it.

Java has PageFactory which allows a nicer, cleaner way to create WebElement object repository.  It doesn't actually creates the object it's just do the lazy initialization. which means the first time you do some action on this object and it's actually created.

I wanted to something like this Python, I searched it but didn't find any satisfactory answer. and So I write my own code.  It look similar to how you initialize the object in Java, however, it's different in few aspects. For one it doesn't actually do the lazy initialization, however it creates the new object every time you do some action on it.  However, it has advantages as well.

Remember,  StaleElemementReferenceException, it's very less likely you will get this as it creates new object every time.

For this I am using Decorator, if don't know what is decorator, it's simply a function which takes a function as a input and returns you a brand new function. However, I would advice you to read more about this.

Now let's just to code.


Without Object Repository


class TestGoogle(object):

    def test_search(self):
        self.driver = webdriver.Firefox()
        self.driver.get("https://google.com")
        self.driver.find_element_by_name("q").send_keys("selenium")

And now, with Object Repository
class TestGoogle(object):

    @FindBy(By.NAME, "q")
    def search_input(self): pass

    def test_search(self):
        self.driver = webdriver.Firefox()
        self.driver.get("https://google.com")
        self.search_input().send_keys("selenium python")

If you have noticed, search_input is a function and not a variable. The reason for this is, Python don't have a decorator for variable, at least yet.  And so you need to call the function which will give you a WebElement object on which you can do multiple actions.