1

I've used selenium a lot but have not had occasion to use WebDriverWait. Now I am in need to click a Back button which, although it seems to be immediately available, it must occasionally not be for a split second. I can put it in a loop with a time.sleep(1) and it will occasionally loop once. I can live with this but I thought this to be the perfect opportunity to implement a WebDriverWait. This works:

browser.find_element_by_xpath('//div[@onclick="backToResults();"]')

except for the occasional NoSuchElementException...

This won't work, it just runs the 3 seconds and times out (regardless of the amount of time I try, it never returns successful):

elem = WebDriverWait(browser, 3).until(ec.presence_of_element_located((By.XPATH, '//div[@onclick="backToResults();')))

...but the same ec call without the wait does returns the element, so the wait should be working:

ec.presence_of_element_located((By.XPATH, '//div[@onclick="backToResults();'))

So, it's not that the element is not there and is accessible, at least within a second or so, but the WebDriverWait isn't returning from the positive EC call?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
reb
  • 23
  • 9

2 Answers2

0

Not sure if it is good practice to assign EC to variables...

Try removing the elem = bit, and see if that helps.

Also, it seems the line - ec.presence_of_element_located((By.XPATH, '//div[@onclick="backToResults();')) - works, so I'm wondering what the issue here is...? :)

Alichino
  • 1,668
  • 2
  • 16
  • 25
  • well, according to the [docs](https://selenium-python.readthedocs.io/waits.html#explicit-waits) `elem =` is correct. Either way though, with or without `elem =`, it doesn't work. It's the `wait` that doesn't seem to be working as expected. – reb Oct 18 '18 at 16:11
  • It could be that you have declared a global wait (of, say, 10 seconds) somewhere. Now, when you don't give it a specific time (like wait 3 s) it takes the global wait and actually finds the element in that time. That is assuming that if you don't put the wait-until before the EC, it puts it there automatically, but I couldn't find anywhere if that is what happens. – Alichino Oct 19 '18 at 07:18
  • nope, that is the only usage of wait in the code. It was the first attempt at using this. Since no one seems to be responding to this and as I said originally, it's accomplished with `time.sleep(1)` so I've gone back to that and moved on. I just thought someone in SO might have ran across this before and had a solution. – reb Oct 19 '18 at 11:05
0

time.sleep() / NoSuchElementException

To suspend the execution of the webdriver for milliseconds you can pass number of seconds or floating point number of seconds as follows:

import time
time.sleep(1) #sleep for 1 sec
time.sleep(0.25) #sleep for 250 milliseconds

However while using Selenium and WebDriver for Automation using time.sleep(secs) without any specific condition to achieve defeats the purpose of Automation and should be avoided at any cost. As per the documentation:

time.sleep(secs) suspends the execution of the current thread for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.

So, at times even after using time.sleep(secs) as well you may see NoSuchElementException

Now, as your objective is to invoke click() on the element so instead of using expected_conditions as presence_of_element_located() you need to use element_to_be_clickable(locator) as follows:

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[starts-with(@onclick,'backToResults')]"))).click()

You can find a related detailed discussion in How to sleep webdriver in python for milliseconds

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • As I said in my OP, `I can put it in a loop with a time.sleep(1) and it will occasionally loop once`, so yes it does work using `time.sleep(1)` within a loop. This is what the `WebDriverWait` is supposed to accomplish and I was curious why THAT didn't work. As to your link reference, I had also stated that the `EC` returned with the element with `presence_of_element_located`, as well as all of those flags within the link you provided. So your answer does nothing to help with why the `WebDriverWait` is not working here? – reb Oct 21 '18 at 15:04