1

Given this code that waits until a loading circle disappears from a webpage :

    def wait_loadingCircle(self):

    try:
        while self.browser.find_element_by_xpath('//div[@class="sk-circle-container"]').is_displayed() is True:
            time.sleep(1)
    except (NoSuchElementException, StaleElementReferenceException, TimeoutException):
        print('Loading circle has expired')

The problem is when the circle disappears (the xpath disappears) .is_displayed() function returns false in 12+ seconds, is there any other way to wait until the circle disappears(xpath is not found on the page anymore) ?

Edit:

This sample of code takes even longer:

    def wait_loadingCircle(self):

    try:
        # while self.browser.find_element_by_xpath('//div[@class="sk-circle-container"]').is_displayed() is True:
        while self.browser.find_element_by_xpath('//div[@class="sk-circle-container"]') != None:
            time.sleep(1)
    except (NoSuchElementException, StaleElementReferenceException, TimeoutException):
        print('Element loading a disparut')

Basically after the xpath disappears from the page the code is sooo slow to identify it when the page is just abit bigger in complexity

Henry-G
  • 131
  • 1
  • 8

2 Answers2

1

Yes you can use WebDriverWait() and use expected conditions invisibility_of_element_located()

Once the element become invisible within 20 seconds (As you mentioned it takes 12 seconds to disappear) this will move to next statement else throw exception after 20 seconds if element still not disappear.

WebDriverWait(driver,20).until(EC.invisibility_of_element_located((By.XPATH,'//div[@class="sk-circle-container"]')))

You need to import following libraries.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
KunduK
  • 32,888
  • 5
  • 17
  • 41
  • Yeah, tried ur solution, same outcome, if the page is abit big, it takes alot after the circle actually disappears from the page to throw the exception, basically i want it as soon as the circle disappear to throw the exception somehow, as fast as possible – Henry-G Jul 31 '20 at 14:31
  • @Henry-G : Have you tried with correct xpath for the element?The expected condition will check element visible false.As you said it takes alot after the circle actually disappears from the page to throw the exception.It means the element you are checking for disappear it is still on the page because if the same element disappear it will move to next statement not to throw exception.Please check the element or you could share your url to investigate? – KunduK Jul 31 '20 at 15:02
  • Its a local host unfortunately, but the xpath disappears, it dosen't disappear on screen only, it also gone from the page's struct – Henry-G Jul 31 '20 at 15:08
  • @Henry-G : Could you just check your xpath how many elements you are getting on DOM using chrome dev tools? or via code `print(len(driver.find_elements_by_xpath('//div[@class="sk-circle-container"]')))` – KunduK Jul 31 '20 at 15:12
0

You need to focus on your usecase and to wait until a loading circle disappears from a webpage isn't your usecase.

Possibly your usecase is to wait for the initial loading circle to disappear from the webpage and then to interact with an element. In that case first you need to induce WebDriverWait for the loader's invisibility_of_element_located() and then WebDriverWait for the desired element_to_be_clickable() as follows:

WebDriverWait(driver, 20).until(EC.invisibility_of_element_located((By.XPATH, "//div[@class='sk-circle-container']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "xpath_desired_element"))).click()

Note : You have to add the following imports :

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Update

The method wait_loadingCircle(self) appears to be complete overhead as waiting for the loading circle isn't your actual usecase. We have discussed this aspect in a couple of discussions. Rather probing is_displayed() is True, inducing WebDriverWait would be best approach. You can find a couple of relevant discussions in:


Reference

You can find a relevant detailed discussion in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Yeah so basically, that's what I'm doing, but instead of ec.invisibility_of_element_located I used the while is_dispalyed() true because it's abit faster, my problem is with the time it takes to go to the next step, ex click on an element after the circle actually disappears. That's my issue, even tho the circle's gone the code takes so much time to see its gone – Henry-G Aug 01 '20 at 07:32
  • @Henry-G Checkout the answer update and let me know your thoughts. – undetected Selenium Aug 01 '20 at 16:23