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.

Prab
  • 464
  • 3
  • 13

2 Answers2

4

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()
Dharman
  • 30,962
  • 25
  • 85
  • 135
pauloalust
  • 41
  • 3
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)
webb
  • 567
  • 3
  • 8
  • 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. – Prab May 15 '20 at 18:42