Search code examples
pythonseleniumselenium-webdriversafariwebdriver

Selenium WebDriver.wait does not wait Python


I want to have Selenium wait until a webpage is loaded. I use Safari 14.1.2 on macOS 10.15.7

So I tried as below:

// login process and it successes and the following page shows up
login_submit.click() 

// the page after the authorization, make selenium wait until ```hoge``` is clickable
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, 'hoge')))

This code does not work as expected. It fails with an error selenium.common.exceptions.NoSuchFrameException:. The error comes immediately, which seems there is no 10 s wait.

The stack trace is as below: (Paths are modified.)

Traceback (most recent call last):
  File "/login.py", line 99, in <module>
    login_schedule().quit()
  File "/login.py", line 67, in login_schedule
    wait.until(EC.presence_of_element_located((By.ID, 'HOGEHOGE')))
  File "/selenium/webdriver/support/wait.py", line 71, in until
    value = method(self._driver)
  File "/selenium/webdriver/support/expected_conditions.py", line 64, in __call__
    return _find_element(driver, self.locator)
  File "/selenium/webdriver/support/expected_conditions.py", line 415, in _find_element
    raise e
  File "/selenium/webdriver/support/expected_conditions.py", line 411, in _find_element
    return driver.find_element(*by)
  File "/selenium/webdriver/remote/webdriver.py", line 976, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchFrameException: Message: 

When I put time.sleep(10) instead as below,

import time
// login process and it successes and the following page shows up
login_submit.click() 

time.sleep(10)
// the page after the authorization, make selenium wait until ```hoge``` is clickable
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, 'hoge')))

it works as expected. Note that the last part can even be replaced

browser.find_element_by_xpath("//select[@id='hoge']")

What is wrong with my Python code?


Solution

  • try to use this function to wait until the element or something appears:

    def wait_for(xpath):
      while True:
        try:
          driver.find_element_by_xpath(xpath) 
          return True
        except NoSuchElementException:
          continue
    

    do not forget

    from selenium.common.exceptions import NoSuchElementException
    

    you can use anything it is not important to be XPATH as a method.