1
wait = (driver, 10)
wait.until(EC.presence_of_element_located((By.XPATH, '//td[@class="blah blah blah"]')))
wait.until(EC.visibility_of_element_located((By.XPATH, '//h1[text() = "yo yo"]')))

Is there a way to combine these two conditions into one line or any way that says if both of these conditions are true then only click() in Selenium, Python.

2 Answers 2

7

I was having the same problem and found an answer! You can use EC.all_of(*expected_conditions) to check for multiple Expected Conditions, just like logical AND, or EC.any_of(*expected_conditions) to check for logical OR.

So the code would be something like this:

WebDriverWait(driver, 5).until(
    EC.all_of(
        EC.presence_of_element_located((By.ID, "Example")),
        EC.visibility_of_element_located((By.ID, "Example"))
    )
)

It returns a list of webdriver elements, so if you want to click an element, you'll have to select it by index, adding [i].click() to the end.

That also means if you want to click a third element outside the ones that you are checking for, you also have to add it to the check, and select it as well. At the end it would be like this:

WebDriverWait(driver, 5).until(
    EC.all_of(
        EC.presence_of_element_located((By.ID, "Example")),
        EC.visibility_of_element_located((By.ID, "Example")),
        EC.presence_of_element_located((By.ID, "Clickable"))
    )
)[2].click()
Sign up to request clarification or add additional context in comments.

Comments

2

Here's an example of making a function for Selenium's WebDriverWait:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

# Open the website
driver.get('https://ocrdata.ed.gov/flex/Reports.aspx?type=school')

... more code ...

# Custom function for Explicit Wait
# The Export button is available before it is "clickable", need to wait
def find(driver):
    export_button = driver.find_element_by_name('ctl00$div$ucReportViewer$btnExport')
    if export_button:
        try: 
            export_button.click()
            return True
        except:
            return False
    else:
        return False

secs = 120
export_button = WebDriverWait(driver, secs).until(find)

I would suggest recording the presence and visibility of both elements as separate variables and creating an if statement in the function like so:

# Custom function for Explicit Wait
# The Export button is available before it is "clickable", need to wait
def find(driver):
    presence = EC.presence_of_element_located((By.XPATH, '//td[@class="blah blah blah"]'))
    visibility = EC.visibility_of_element_located((By.XPATH, '//h1[text() = "yo yo"]'))
    if presence and visibility:
        try: 
            # action
            return True
        except:
            return False
    else:
        return False

secs = 120
export_button = WebDriverWait(driver, secs).until(find)

1 Comment

Hi @webb. Thank you very much for your reply. This method makes complete sense, and I should have probably said this in the question, that I am aware of this method, however, I was wondering if there was a much more condensed version as it takes a lot of lines for one click!!! But I do appreciate your answer.

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.