How to avoid StaleElementReferenceException in Selenium - Python
<p>I am stuck in writing a Python Selenium script and can't seem to satisfactorily resolve this StaleElementReferenceException I am getting.  </p>

<p>I have my page loaded and click a button which opens a form that allows the user to add a new credit card to the order.  At this point I do a WebDriverWait to pause the script until the Save button on this form becomes visible.  At that point, recreate the page object since it has changed, and my intent is to populate the fields and save the card.  </p>

<p>The problem is that after refreshing the page object the script fails with the StaleElementReferenceException.  My understanding is that the WebDriverWait will pause the the execution giving the page time to load all the elements that need to load, but that doesn't appear to be happening.  Instead something in that refresh of the page object is stale and causes the error (different part of the object creation each time).  </p>

<p>If I just uncomment the line 'time.sleep(2)' then this script runs fine and it will pass.  So I know I just need to give the page time to reload correctly before I refresh the object. The WebDriverWait just doesn't seem to be doing that effectively for me.</p>

<p>Is there a more correct way I can do this without the sleep command?</p>

<pre><code>checkout = CheckoutProcess(self.driver)

# Add Credit Card
checkout.add_credit_card()

# Wait for form to display
WebDriverWait(self.driver,30).until(expected_conditions.presence_of_element_located((By.CLASS_NAME, 'total')))

# time.sleep(2)

# Refresh the page object so form can be filled in
checkout = CheckoutProcess(self.driver)  # Script Fails Here
checkout.populate_credit_card_data(credit_card_name, credit_card_number, credit_card_expiration_date, credit_card_cvc)
checkout.click_credit_card_save_button()
</code></pre>

<p>A StaleElementReferenceException is thrown when the element you were interacting is destroyed and then recreated. Most complex web pages these days will move things about on the fly as the user interacts with it and this requires elements in the DOM to be destroyed and recreated.</p>

<p>Try doing</p>

<pre><code>wait.until(ExpectedConditions.stalenessOf(whatever element));
</code></pre>

<p>or</p>

<pre><code>wait.until(ExpectedConditions.presenceOfElementLocated(By.id("whatever elemnt")))
</code></pre>

<p>Hope it will help you</p>

python selenium