Gbru
Gbru

Reputation: 1087

Waiting for Element to become stale, why doesn't 'ExpectedConditions.stalenessOf' work?

I have created the following method:

public void waitAndClickElement(WebElement element) throws InterruptedException {
    try {
        Boolean elementPresent = this.wait.until(ExpectedConditions.elementToBeClickable(element)).isEnabled();
        if (elementPresent == true && element.isDisplayed()) {
            element.click();
            System.out.println("Clicked on the element: " + element.getText());
        }
    } catch (StaleElementReferenceException elementUpdated) {
        Boolean elementPresent = wait.until(ExpectedConditions.stalenessOf(element));
        if (elementPresent == true) {
            WebElement staleElement = element;
            staleElement.click();
            System.out.println("Clicked on the 'Stale' element: " + element.getText());
        }
    } catch (NoSuchElementException e) {
        System.out.println("Exception! - Could not click on the element: " + element.getText() + ", Exception: "+ e.toString());
        throw (e);
    } finally {
    }
}

But I Still seem to get the following exception below:

Expected condition failed: waiting for element (Proxy element for: DefaultElementLocator 'By.xpath: //a[text()='Exchange Now »']') to become stale (tried for 20 second(s) with 500 MILLISECONDS interval) enter image description here

But the same method will work on let's say 18 out of 20 builds, any ideas?

thanks for you help

Upvotes: 3

Views: 16647

Answers (2)

JeffC
JeffC

Reputation: 25542

The direct answer to your question is that you are waiting for an already stale element to become stale. I'm not sure what your intent was there.

Your function is overly complex and won't work as you think it might.

If an element is clickable it's also enabled and displayed, so you don't need to check all three. If the element is throwing a StaleElementReferenceException, it's not going to become "unstale."

I would recommend you replace your current function with the below.

public void waitAndClickElement(By locator)
{
    try
    {
        this.wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
    }
    catch (TimeoutException e)
    {
        System.out.println("Count not click element <" + locator.toString() + ">");
    }
}

Pass the locator instead of the element instead of the element itself, that will simplify a lot of things. If the element exists and is clickable, it will be clicked. If it does not exist or never becomes clickable, it will throw a TimeoutException which you can catch.

Also, writing element.toString() is going to write some ID for the element which is not going to be human readable or meaningful. You're better off to write locator.toString() which will return the type of locator, e.g. By.cssSelector: #hplogo.

Upvotes: 1

Grzegorz G&#243;rkiewicz
Grzegorz G&#243;rkiewicz

Reputation: 4586

If you change site with another driver.get("http://completely.different.site.com/");, this element will be stale (no more in DOM). Staleness means that the element in DOM is not accessible.

Upvotes: 1

Related Questions