4

I am trying to create my own Selenium class with custom functions so that test scripting will become a bit more intuitive and more robust in some scenarios, for my taste at least. One of my current tasks is to wrap all Selenium expected conditions (described here) so that eventually I will have a single function that looks something like that:

def waitForElement(self, elementName, expectedCondition, searchBy)

Where:

elementName - the name of the element I am looking for. That could be id, name, xpath, css, etc...

expectedCondition - this is where the Selenium expected condition is set. So that can be: element_to_be_clickable, visibility_of_element_located, etc...

The above function internally implements the standard Selenium WebDriverWait as follows:

try:
    if expectedCondition == "element_to_be_clickable":
        element = WebDriverWait(self.driver, defaultWait).until(EC.element_to_be_clickable((searchBy, elementName)))
    elif expectedCondition == "visibility_of_element_located":
        element = WebDriverWait(self.driver, defaultWait).until(EC.visibility_of_element_located((searchBy, elementName)))

All is good but I have a bit of trouble with passing the searchBy as a parameter. To remind, searchBy can be one of the following:

By.ID
By.NAME
By.CLASS_NAME
...

When I call this wrapper function from the main code, I do it with the below line:

self.waitForElement("elementName", "element_to_be_clickable", "By.NAME", "test")

So all parameters are passed as strings which is fine for everything except of the searchBy part.

So my question is: How can I pass the By.X part as a parameter to my function? Hopefully I was able to describe my situation well. If I wasn't I will be happy to clarify.

3 Answers 3

1

Eventually I was able to solve this problem after asking this question. So in order to obtain the desired functionality, the above-mentioned method will look like this:

def waitForElement(self, elementName, expectedCondition, searchBy):
    try:
        if expectedCondition == "element_to_be_clickable":
            element = WebDriverWait(self.driver, self.defaultWait).until(EC.element_to_be_clickable((getattr(By, searchBy), elementName)))
        elif expectedCondition == "visibility_of_element_located":
            element = WebDriverWait(self.driver, self.defaultWait).until(EC.visibility_of_element_located((getattr(By, searchBy), elementName)))

        . . . 

So it can be called like this:

self.waitForElement("elementName", "element_to_be_clickable", "NAME")
Sign up to request clarification or add additional context in comments.

Comments

0

You can start like this:

Create main findElement method, that accepts By instance:

WebElement findElement(By by) {
        try {
            return driver.findElement(by);
        } catch (NoSuchElementException e) {
            logException("ERROR: Could not find - '" + by + "' on page " + driver.getCurrentUrl());
            throw e;
        }

Then create wait method, that uses the findElement method:

WebElement findElementAndWaitElementToPresent(By by, int timeoutInSeconds) {
        try {
            WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
            wait.until(ExpectedConditions.presenceOfElementLocated(by));
            return findElement(by);
        } catch (TimeoutException e) {
            logException("ERROR: Element is not present: " + by + " on page " + driver.getCurrentUrl());
            throw e;
        }
    }

And pass By instance to the findElementAndWaitElementToPresent method:

findElementAndWaitElementToPresent(By.xpath("//your_xpath"), 10);

or

findElementAndWaitElementToPresent(By.name("name"), 10);

something like this is done in the framework i am working on/with

2 Comments

Hi and thanks for your answer but I was asking for a solution in Python.
oh, sorry :) but Python also has Webelement module you can work with. I advised you a structure how it can be implemented
0

Issue with your code is that you are converting "By" datatype to string.

Simple way would be to pass it without quotes like below:

self.waitForElement("elementName", "element_to_be_clickable", By.NAME, "test")

Only additional thing you need to do is to add import as below for By in python module from where you are calling above method:

from selenium.webdriver.common.by import By

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.