Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
791 views
in Technique[技术] by (71.8m points)

java - Selenium: How to tell if RemoteWebDriver.findElements(By) can throw StaleElementReferenceException at all?

In my understanding such exception can be thrown only if the code operates on a WebElement instance, calling methods on it after the corresponding DOM element has been reloaded or removed.

So in order to find out if RemoteWebDriver.findElements(By) can throw that exception or not I looked for that kind of code in the source of the RemoteWebDriver implementation of WebDriver interface (in selenium-remote-driver-3.8.1.jar). But following the call stacks deep down into RemoteWebDriver's code eventually became too difficult for me.

So my question is: besides trying to figure that out by inspecting Selenium source, are there better ways to tell if a WebDriver method in general - or just findElements(By) in particular - can throw StaleElementReferenceException ? It's a RuntimeException, and the Selenium JavaDoc doesn't have @throws for it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You pinpointed issue about "StaleElementReferenceException", this is related when webElement instances changes, when DOM is changed due some activity on page.

It is related to how WebDriver internally handles references to webElements, and this issue happens when during runtime references to object(s) are changed.

Now, let’s assume when you have fetched the element and before doing any action on it, something got refreshed on your page. It could be the whole page that is being refreshed or some call which has refreshed only a section of the DOM where your element falls.

In this scenario the internal id which WebDriver was using, and stored somewhere in cache has become stale (not referenced anymore), so now for every operation on this WebElement, we will get StaleElementReferenceException.

So to try to avoid it on critical places try to use this method, for determine if element is stale.

public static boolean isStale(WebElement e){
    try{
        e.isDisplayed();
        return false;
    }catch(StaleElementReferenceException ex){
        return true;
    }
}

Usually refreshing of page, pageObject, or just this particular element would help in 90% of cases.

And after refreshing page/element WebDriver will assign a different internal Id to this element, and will be able to use it again without any problem.

This problem is solver with PageObject / PageFactory design patter.

public class SomePage {
    @FindBy(how = How.NAME, using = "q")
    private WebElement searchBox;


    public SomePage() {
        PageFactory.initElements(driver, this);
    }


    public void searchFor(String text) {
        searchBox.sendKeys(text);
    }
}

Hope this helps,


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...