134 votes

Comment éviter "StaleElementReferenceException" dans Selenium ?

J'implémente beaucoup de tests Selenium en utilisant Java. Parfois, mes tests échouent à cause d'un problème de sécurité. StaleElementReferenceException .

Pourriez-vous suggérer quelques approches pour rendre les tests plus stables ?

-1voto

Shivam Bharadwaj Points 353

Cela fonctionne pour moi en utilisant 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;
    }

-1voto

pguardiario Points 19925

Le problème est qu'au moment où vous faites passer l'élément de Javascript à Java puis à Javascript, il peut avoir quitté le DOM.
Essayez de faire tout ça en Javascript :

driver.executeScript("document.querySelector('#my_id')?.click()")

-1voto

CodingGirl1 Points 13

Essayez ceci

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
    }
}

-1voto

Alpha Points 551

Il pourrait y avoir un problème potentiel qui conduit à l'exception StaleElementReferenceException que personne n'a mentionné jusqu'à présent (en ce qui concerne les actions).

Je l'explique en Javascript, mais c'est la même chose en Java.

Ça ne marchera pas :

let actions = driver.actions({ bridge: true })
let a = await driver.findElement(By.css('#a'))
await actions.click(a).perform() // this leads to a DOM change, #b will be removed and added again to the DOM.
let b = await driver.findElement(By.css('#b'))
await actions.click(b).perform()

Mais le fait d'instancier à nouveau les actions résoudra le problème :

let actions = driver.actions({ bridge: true })
let a = await driver.findElement(By.css('#a'))
await actions.click(a).perform()  // this leads to a DOM change, #b will be removed and added again to the DOM.
actions = driver.actions({ bridge: true }) // new
let b = await driver.findElement(By.css('#b'))
await actions.click(b).perform()

-1voto

Habituellement, l'exception StaleElementReferenceException se produit lorsque l'élément auquel nous essayons d'accéder est apparu, mais d'autres éléments peuvent affecter la position de l'élément qui nous intéresse. Ainsi, lorsque nous essayons de cliquer ou d'obtenir du texte ou d'effectuer une action sur un WebElement, nous obtenons une exception qui indique généralement que l'élément n'est pas attaché au DOM.

La solution que j'ai essayée est la suivante :

 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));
    }

Dans le code ci-dessus, j'essaie d'abord d'attendre puis de cliquer sur l'élément. Si une exception se produit, je l'attrape et j'essaie de la boucler car il est possible que tous les éléments ne soient pas encore chargés et qu'une nouvelle exception se produise.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X