Reputation: 980
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
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
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