2

I hope this question is unique and will help also other testers.
I need the solution for python selenium.
I need to replace several time.sleep() lines of code, by time explicit waits. When Chrome sleeps for few seconds before every element which is expected to be clicked, the test runs successfully, without, it fails.

So it goes like this:

driver.find_element_by_xpath("x").click()  
time.sleep(5)
driver.find_element_by_xpath("y").click()  
time.sleep(5)
driver.find_element_by_xpath("z").click()  
time.sleep(5)

...

Implicity wait is not enough, for sure.

Here is the recommended code:

from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))

I look at this example code, but it seems that I must refer to every single ID, in my case several times.

So the question is:
Is there any global solution to use explicit wait for every element in script, without multiplying lines of code?

GalAbra
  • 5,048
  • 4
  • 23
  • 42
ann
  • 113
  • 2
  • 3
  • 9

1 Answers1

1

I don't know if this is what you need. But if you want, you could use a function which tries to click until it succeeds or a timeout is reached. That way, you only need to call it and wait.

import timeit
from selenium import webdriver

def safe_click(wd_elem, max_time=10):
    """
    wd_elem should be a WebElement object, so it has the .click() method
    max_time defaults to 10 [seconds], and it's how long will the script try to click before it stops
    """

    start = timeit.default_timer()
    while timeit.default_timer() - start <= max_time:
        try:
            wd_elem.click()
            return
        except:
            pass
    print 'Max time reached; stopped trying'

wd = webdriver.Chrome()
wd.get('https://stackoverflow.com/questions/48624119/general-explicit-wait-selenium-python')
elem_to_click = wd.find_element_by_xpath('//*[@id="question-header"]/h1/a')
safe_click(elem_to_click)  # Clicks it
safe_click(None)  # After 10 seconds, it gives up

If you applied it, your code would be:

safe_click(driver.find_element_by_xpath("x")  # Leaving max_time equal to 10 seconds
safe_click(driver.find_element_by_xpath("y", max_time=5)  # Explicitly setting max_time to 5 seconds
safe_click(driver.find_element_by_xpath("z", max_time=9999)  # Explicitly setting max_time to 9999 seconds
francisco sollima
  • 7,952
  • 4
  • 22
  • 38