How to avoid “StaleElementReferenceException” in Selenium?

前端 未结 16 2080
一向
一向 2020-11-22 12:12

I\'m implementing a lot of Selenium tests using Java. Sometimes, my tests fail due to a StaleElementReferenceException. Could you suggest some approaches to mak

相关标签:
16条回答
  • 2020-11-22 12:58

    This works for me (100% working) using C#

    public Boolean RetryingFindClick(IWebElement webElement)
        {
            Boolean result = false;
            int attempts = 0;
            while (attempts < 2)
            {
                try
                {
                    webElement.Click();
                    result = true;
                    break;
                }
                catch (StaleElementReferenceException e)
                {
                    Logging.Text(e.Message);
                }
                attempts++;
            }
            return result;
        }
    
    0 讨论(0)
  • 2020-11-22 13:00

    A solution in C# would be:

    Helper class:

    internal class DriverHelper
    {
    
        private IWebDriver Driver { get; set; }
        private WebDriverWait Wait { get; set; }
    
        public DriverHelper(string driverUrl, int timeoutInSeconds)
        {
            Driver = new ChromeDriver();
            Driver.Url = driverUrl;
            Wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeoutInSeconds));
        }
    
        internal bool ClickElement(string cssSelector)
        {
            //Find the element
            IWebElement element = Wait.Until(d=>ExpectedConditions.ElementIsVisible(By.CssSelector(cssSelector)))(Driver);
            return Wait.Until(c => ClickElement(element, cssSelector));
        }
    
        private bool ClickElement(IWebElement element, string cssSelector)
        {
            try
            {
                //Check if element is still included in the dom
                //If the element has changed a the OpenQA.Selenium.StaleElementReferenceException is thrown.
                bool isDisplayed = element.Displayed;
    
                element.Click();
                return true;
            }
            catch (StaleElementReferenceException)
            {
                //wait until the element is visible again
                element = Wait.Until(d => ExpectedConditions.ElementIsVisible(By.CssSelector(cssSelector)))(Driver);
                return ClickElement(element, cssSelector);
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
    

    Invocation:

            DriverHelper driverHelper = new DriverHelper("http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp", 10);
            driverHelper.ClickElement("input[value='csharp']:first-child");
    

    Similarly can be used for Java.

    0 讨论(0)
  • Try this

    while (true) { // loops forever until break
        try { // checks code for exceptions
            WebElement ele=
            (WebElement)wait.until(ExpectedConditions.elementToBeClickable((By.xpath(Xpath))));  
            break; // if no exceptions breaks out of loop
        } 
        catch (org.openqa.selenium.StaleElementReferenceException e1) { 
            Thread.sleep(3000); // you can set your value here maybe 2 secs
            continue; // continues to loop if exception is found
        }
    }
    
    0 讨论(0)
  • 2020-11-22 13:02

    Usually StaleElementReferenceException when element we try to access has appeared but other elements may affect the position of element we are intrested in hence when we try to click or getText or try to do some action on WebElement we get exception which usually says element not attached with DOM.

    Solution I tried is as follows:

     protected void clickOnElement(By by) {
            try {
                waitForElementToBeClickableBy(by).click();
            } catch (StaleElementReferenceException e) {
                for (int attempts = 1; attempts < 100; attempts++) {
                    try {
                        waitFor(500);
                        logger.info("Stale element found retrying:" + attempts);
                        waitForElementToBeClickableBy(by).click();
                        break;
                    } catch (StaleElementReferenceException e1) {
                        logger.info("Stale element found retrying:" + attempts);
                    }
                }
            }
    
    protected WebElement waitForElementToBeClickableBy(By by) {
            WebDriverWait wait = new WebDriverWait(getDriver(), 10);
            return wait.until(ExpectedConditions.elementToBeClickable(by));
        }
    

    In above code I first try to wait and then click on element if exception occurs then I catch it and try to loop it as there is a possibility that still all elements may not be loaded and again exception can occur.

    0 讨论(0)
提交回复
热议问题