TransWikia.com

Selenium: dealing with intermittent cases of element not found

Software Quality Assurance & Testing Asked by yob-v-u on September 29, 2020

Sometimes it works and sometimes it doesn’t.

I’ve tried implicit wait:

    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

I’ve tried explicit wait:

    wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(ElementNames.CITYSEARCH_FIELD))).sendKeys(city);

Both don’t seem to guarantee that my tests work 10/10 times. Is there a way to actually deal with something like this?

I’ve also tried something like this:

    ...
    while(attempts < 2) {
        try {
            selector.selectByVisibleText(choice);
            result = true;
            break;
        } catch(StaleElementReferenceException e) {
            
        }
        attempts++;
    }
    return result;

This method works on a more consistent basis compared to implicit/explicit wait. But still fails maybe once or twice depending on how long the tests are (e.g going through files with 200,000 lines and performing actions for each line)

Does anyone have any possible suggestion/solution?

3 Answers

Try writing a method that you can reuse whenever you want to find a new web element, but that will timeout after a specific time.

You want to try/catch all the WebDriver exceptions, not just Stale Element. Make sure to include a sleep time in the catch, or else the test will retry like crazy whenever a try fails.

Here is an example:

public static WebElement getElementByLocator(final String elementName, final By locator, final int waitTime)
{
    final long startTime = System.currentTimeMillis();
    boolean found = false;
    WebElement we = null;
    while( (System.currentTimeMillis() - startTime) < 20000 )
    {
        try {
            we = wait.until(ExpectedConditions.presenceOfElementLocated(locator));
            found = true;
            break;
        } catch ( WebDriverException e) {
            log.error("Exception when trying to find element: " + elementName + "n", e);
            Thread.sleep(waitTime);
        }
    }
    long endTime = System.currentTimeMillis();
    long totalTime = endTime - startTime;
    if (found) {
        log.info("Successfully found the element: " + elementName + " - waited for: " + totalTime + " ms");
        Thread.sleep(waitTime);
    } else {
        log.error("COULD NOT FIND THE ELEMENT: " + elementName + " - after waiting for: " + totalTime + " ms");
        fail("TEST CASE FAILED ON: " + elementName);
    }
    return we;
}

Answered by JamesWillett on September 29, 2020

Poll for the maximum acceptable response time. Decide the longest response time you are willing to accept. Then poll for that long.

Set your poll timeout such that:

  • You cannot accept a longer response time, even if the element were to appear on the next poll cycle.
  • You can accept a shorter response time, no matter how grudgingly.

I like to be generous with polling timeouts. Say 90 seconds. The drawback of long poll times is that if the system is broken in such a way that the element never appears, that failure will chew up 90 seconds of test execution time. The advantage is that the long poll timeout absorbs "normal" variation in network delays, garbage collection, CPU-contention, and other stuff that affects response time.

Are you willing to wait 90 seconds for an element to appear? Or is 90 seconds a clear failure in your system?

WebDriver's explicit waits allow you to specify how long and how often to poll.

Sprinkling while loops through your code will drive you crazy. Use WebDriver's explicit waits.

Or if you can tolerate lots of parentheses in your code, check out my 'expression' library:

Answered by Dale Emery on September 29, 2020

Your solution where you retry the sendKeys operation is the right idea. I do the same thing. You should have a sort of "retry" fallback.

I also suggest running all failed tests twice after they fail and if they succeed at any point, they should pass.

You can also try different Expected Conditions. I prefer to use "displayed and clickable" for most of my GUI automation.

Answered by Jess on September 29, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP