Selenium:如何判断RemoteWebDriver.findElements(By)是否可以引发StaleElementReferenceException? [英] Selenium: How to tell if RemoteWebDriver.findElements(By) can throw StaleElementReferenceException at all?

查看:453
本文介绍了Selenium:如何判断RemoteWebDriver.findElements(By)是否可以引发StaleElementReferenceException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,可以抛出此类异常仅当代码在WebElement实例上运行时,才在相应的DOM元素已重新加载或删除之后在其上调用方法.

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.

因此,为了找出RemoteWebDriver.findElements(By)是否可以引发该异常,我在WebDriver接口(在selenium-remote-driver-3.8.1.jar中)的RemoteWebDriver实现的源代码中寻找了这种代码.但是,将调用堆栈深入到RemoteWebDriver的代码中对于我来说最终变得太困难了.

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.

所以我的问题是:除了试图通过检查硒源来弄清楚这一点之外,还有更好的方法来判断一般WebDriver方法(或者特别是findElements(By))是否可以抛出StaleElementReferenceException吗?这是RuntimeException,而Selenium JavaDoc没有它..

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.

推荐答案

您已查明有关"StaleElementReferenceException"的问题,这与webElement实例更改,由于页面上的某些活动而DOM更改有关.

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

这与WebDriver在内部处理对webElement的引用有关,当在运行时更改对对象的引用时,就会发生此问题.

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

现在,让我们假设当您获取元素时,在对该元素执行任何操作之前,页面上会刷新一些内容.可能是整个页面正在刷新,也可能是某个调用仅刷新了元素所属的DOM部分.

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.

在这种情况下,WebDriver正在使用的内部ID以及存储在缓存中的内部ID已过时(不再引用),因此,对于此WebElement上的每个操作,现在我们将得到StaleElementReferenceException.

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

通常情况下,刷新页面,pageObject或仅刷新此特定元素将在90%的情况下有所帮助.

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

刷新页面/元素后,WebDriver会为此元素分配一个不同的内部ID,并且可以再次使用它而没有任何问题.

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.

此问题是使用PageObject/PageFactory设计模式进行求解的.

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

希望这会有所帮助,

这篇关于Selenium:如何判断RemoteWebDriver.findElements(By)是否可以引发StaleElementReferenceException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆