43.52.4D.
43.52.4D.

Reputation: 980

Selenium WebDriver - handle StaleElementReferenceException (Python)

I am writing Python code using Selenium which clicks on a button on a web page. After the button is clicked, the button changes to something else. My code works perfectly fine, but Selenium is misinterpreting this as a problem. I'm attempting to ignore the exception and move on but nothing I've tried has worked.

from selenium.common.exceptions import StaleElementReferenceException

try:
    browser.find_element_by_xpath("//*[contains(text(), 'SomeButtonText')]").click()
except StaleElementReferenceException:
    pass

What can I do to ignore the exception and move on? My code WORKS with what I'm trying to do, but after a couple seconds, the exception is thrown.

Message: Element not found in the cache - perhaps the page has changed since it was looked up

Here is the extremely messy information from the Ubuntu Terminal:

File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 107, in get_attribute
    resp = self._execute(Command.GET_ELEMENT_ATTRIBUTE, {'name': name})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 454, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 181, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up
Stacktrace:
    at fxdriver.cache.getElementAt (resource://fxdriver/modules/web-element-cache.js:9351)
    at Utils.getElementAt (file:///tmp/tmp24d8CK/extensions/[email protected]/components/command-processor.js:8978)
    at WebElement.getElementAttribute (file:///tmp/tmp24d8CK/extensions/[email protected]/components/command-processor.js:12019)
    at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmp24d8CK/extensions/[email protected]/components/command-processor.js:12534)
    at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmp24d8CK/extensions/[email protected]/components/command-processor.js:12539)
    at DelayedCommand.prototype.execute/< (file:///tmp/tmp24d8CK/extensions/[email protected]/components/command-processor.js:12481)

Upvotes: 1

Views: 1811

Answers (2)

fahad
fahad

Reputation: 389

This issue is because Html is loading and client is still receiving updates from server

how ever i made a solution for problem you can simply use my custom wait before clicking . call this function

 public static void waitForElementPresent(final By by, int timeout,WebDriver driver)

After this if you are using browser other then chrome then call Scroll to that object this would fix you problem Code

public static void waitForElementPresent(final By by, int timeout,WebDriver driver) { 

        waitForPageLoad(driver);
        WebDriverWait wait = (WebDriverWait)new WebDriverWait(driver,40).ignoring(StaleElementReferenceException.class); 
        /*  wait.until(new ExpectedCondition<Boolean>(){ 
            @Override 
            public Boolean apply(WebDriver webDriver) { 
              WebElement element = webDriver.findElement(by); 
              return element != null && element.isDisplayed(); 
            } 
          }); */
          try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
           wait.until(ExpectedConditions.presenceOfElementLocated(by));
          wait.until(ExpectedConditions.elementToBeClickable(by));
          WebDriverWait wait2 = new WebDriverWait(driver, 40);
          wait2.until(ExpectedConditions.elementToBeClickable(by));

        }
    //wait for page to laod 
    public static void waitForPageLoad(WebDriver driver) {
        ExpectedCondition<Boolean> pageLoadCondition = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
                }
            };
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(pageLoadCondition);
    }

Upvotes: 1

43.52.4D.
43.52.4D.

Reputation: 980

I found the answer to my problem.

The code here:

try:
    browser.find_element_by_xpath("//*[contains(text(), 'SomeButtonText')]").click()
except StaleElementReferenceException:
    pass

Was executing at the end of a for loop. I completely missed the fact that it returned to the beginning of the loop where I had a separate problem with a Stale reference exception.

Upvotes: 2

Related Questions