• +43 660 1453541
  • contact@germaniumhq.com

Writing Simple Selectors


Writing Simple Selectors

We all got tired at some point of finding element by XPath, since it’s error prone and hard to maintain. A naive approach might be using string constants, but is there another way?

If you’re serious into testing, you might have heard about page objects, and using string constants in order to minimize code duplication for the selectors, that will find the elements. Nonetheless it doesn’t seem much easier.

Having in the code:

class LoginPage(object):
    @static
    LOGIN_INPUT='//input[@placeholder="Name"]'

    @static
    PASSWORD_INPUT='//input[@type="password"]'

    #...

    def login(self, username, password):
        login_input = self.driver.find_elment_by_xpath(
                LoginPage.LOGIN_INPUT)
        password_element = self.driver.find_elment_by_xpath(
                LoginPage.PASSWORD_INPUT)

        login_input.send_keys(username)
        password_element.send_keys(password)

Still doesn’t shields us that much from the complexities of writing the selectors themselves.

What’s worse, if we need to change the selector type to let’s say CSS, we also need to start changing all the calls to the driver find_element_by_xpath(..).

This is why Germanium offers the concept of selectors.

In Germanium the same code is much easier, and it would be:

class LoginPage(object):
    @static
    LOGIN_INPUT=InputText('Name')

    @static
    PASSWORD_INPUT=Element('input',
                           exact_attributes=[type: 'password'])

    #...

    def login(self, username, password):
        type_keys(username, LOGIN_INPUT)
        type_keys(password, PASSWORD_INPUT)

Goodbye XPath hell!

The advantage remains that the login() code remains the same, regardless of what selector we have.

Of course, if really needed we can still use the same old XPath selectors:

@static
LOGIN_INPUT=XPath('//input[@placeholder="Name"]')

@static
PASSWORD_INPUT=XPath('//input[@type="password"]')

Also I could change the PASSWORD_INPUT to Css:

@static
PASSWORD_INPUT=Css('input[type="password"].some-class')

But we wouldn’t need to change anywhere else the code except the selectors.

Read more about selectors in our extensive documentation: