pythonseleniumselenium-webdriverstaleelementreferenceexception

Can't access input field in POP UP UI selenium. StaleElementReferenceException after element found clickable


I am trying to access an input field in a pop up UI(Aantal KvK uittreksels). Right now I am trying this code:

element = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[contains(.,'custom_field_387439')]")))
element.send_keys("testing")

That results in this error:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

This is the webview + Google Elements: enter image description here

Please let me know.


Solution

  • StaleElementReferenceException appearing after applying WebDriverWait element_to_be_clickable expected_conditions means that the page you are working on is built with not Selenium friendly dynamic DOM technique. The page rendering is performed so that on some step the desired physical element is already exists and even appears clickable i.e. defined as fully rendered, but after that the page rendering is still continues so the previously collected by Selenium web element (actually a pointer to the physical element on the DOM) reference no more pointing to that physical element, since previously created physical element no more exists, new physical element is now created.
    To overcome this we can create special method attempting to click element in a loop. Something like this:

    def click_element(locator):
        for i in range(5):
            try:
                wait.until(EC.element_to_be_clickable(locator)).click()
                break
            except:
                pass
    

    Send keys can be done in exactly the same way:

    def send_keys_in_loop(locator, value):
        for i in range(5):
            try:
                wait.until(EC.element_to_be_clickable(locator)).send_keys(value)
                break
            except:
                pass
    

    You can use these methods in the following way:

    click_element((By.XPATH, "//input[contains(.,'custom_field_387439')]"))
    send_keys_in_loop((By.XPATH, "//input[contains(.,'custom_field_387439')]"),"testing")
    

    Please pay attention on the fact that the locator parameter here is a tuple so that I use double parenthesis when calling click_element and click_element methods while inside those methods implementation you can see only single parenthesis inside the element_to_be_clickable(locator) expression.