Is it possible to return value like this?

I have a question about Python syntax, didnt found on the google :/
I trying to write universal function, for locators search on Selenium.

I have locators in locators.py, they looks like this:

class LoginForm:
    email    = {'css': '#email'}
    password = {'css': ' #password'}
    login_button = {'css': '#submitLoginForm'}

and in base_page.py I have this:

def __unify_locator(self,selector: dict):
    elif 'css' in selector.keys():
        return (By.CSS_SELECTOR,selector['css'])

def __element(self, selector: dict, index: int):
    return self.driver.find_elements((self.__unify_locator(selector)))[index]

As you can see, I trying to return from __unify_locator something like (By.CSS_SELECTOR,selector['css']). I want to make it agile, because in the future I can use XPath or Link Text or e.t.c

Is it possible to return values like this ? case I got errors on execute that part of code

2 answers

  • answered 2020-07-29 17:31 Baked Potato

    You problem is likely simply that you are using elif instead of if. I don't know the rest of your setup, but it may work if you just do

    if 'css' in selector.keys():
    

    instead of using elif.

    elif is short for else if. It goes after a different if statement, and will only be checked if the previous if condition evaluates to false. Since here you are only testing one condition, you should use if.

    Since you say you want flexibility in the future, your next conditions could use elif, and would be entered if their condition is true and the if above them is false.

  • answered 2020-07-29 17:33 Code-Apprentice

    Is it possible to return values like this ? case I got errors on execute that part of code

    Yes, you can return a tuple like this. The error isn't because of the return, but because of how you use it. To separate the values in the tuple as parameters to another function, use the splat operator *:

    self.driver.find_elements(*self.__unify_locator(selector))
                              ^ here
    

    One suggestion: You can write your selectors directly as such a pair:

    email = (By.CSS_SELECTOR, '#email')
    

    Then you don't need __unify_locator() at all:

    self.driver.find_elements(*selector)
    

    Alternatively, your selector can be a dict to provide context to the meaning of each value:

    email = {
        'by': By.CSS_SELECTOR,
        'value': '#email',
    }
    

    Then use ** instead of *:

    self.driver.find_elements(**selector)
    

    Finally, you cannot have elif without an if, but I think you just didn't post some of your code in __unify_locator().