如何处理StaleElementReferenceException

时间:2015-01-28 13:18:50

标签: java eclipse selenium webdriver

我有一个场景,我试图在条形图上循环遍历许多元素,直到找到“rect”标签名称。当我点击“rect”标签名称时,从图表中选择单个栏,我将重定向到另一个页面。请参阅下面的我正在使用的条形图的图像: http://imgur.com/xU63X1Z

作为参考,我正在使用的条形图是右上角。我想要执行的测试是点击图表中的第一个栏;这样做会将我重定向到适当的页面。为了做到这一点,我使用Eclipse(Java)在Selenium Webdriver中编写了以下代码:

WebElement deliveredChartDailyFocus = driver.findElement(By.id("delivered-chart-daily"));
deliveredChartDailyFocus.click();

List<WebElement> children = deliveredChartDailyFocus.findElements(By.tagName("rect"));
Iterator<WebElement> iter = children.iterator();

while (iter.hasNext()) {
WebElement we = iter.next();

if(we.isDisplayed()){
we.click();
}

所有内容似乎都运行良好,因为上面的代码点击了“rect”元素并将我重定向到适当的页面。但是,当我点击页面时,我得到一个错误,因为代码仍然在寻找不在新页面上的“rect”值。

你会注意到上面没有“break”行......这是因为,在调试代码时我发现在迭代循环时,click事件直到第3次迭代才开始,我假设因为“rect”元素不可见?因此,如果我输入一个“break”语句,它会在第一次迭代后退出循环,因此我从未进入我执行“click”事件导航到新页面的部分。

基本上,我所追求的是一种能够根据需要循环多次的方法,直到可以找到适当的“rect”元素。单击它后,我被重定向到新页面...。仅在那时我是否希望循环退出,以便不显示“NoSuchElementException错误。

如果需要更多详细信息,请告知我们,我们非常感谢您的任何指导。

2 个答案:

答案 0 :(得分:2)

进入新页面后,所有rect个元素都消失了。对这些rect元素执行任何引用都会触发此StaleElementReferenceException

所以不要在点击后引用这些元素。迭代到第一个显示的rect元素,然后停止迭代。

WebElement deliveredChartDailyFocus = driver.findElement(By.id("delivered-chart-daily"));
deliveredChartDailyFocus.click();

// Get a list of all the <rect> elements under the #delivered-chart-daily element
List<WebElement> children = deliveredChartDailyFocus.findElements(By.tagName("rect"));

WebElement elementToClick = null; // variable for the element we want to click on
for (WebElement we : children)    // loop through all our <rect> elements
{
    if (we.isDisplayed())
    {
        elementToClick = we;      // save the <rect> element to our variable
        break;                    // stop iterating
    }
}

if (elementToClick != null)       // check we have a visible <rect> element
{
    elementToClick.click();
}
else
{
    // Handle case if no displayed rect elements were found
}

答案 1 :(得分:1)

Andy,这里的问题是DOM刷新。您不能简单地获取IWebElements的集合并迭代并来回点击。您可以查找元素的数量,每次进入页面时都会找到要动态点击的元素。有关实施,请参阅this

public void ClickThroughLinks()
{

    _driver.Navigate().GoToUrl("http://www.cnn.com/");
    //Maximize the window so that the list can be gathered successfully.
    _driver.Manage().Window.Maximize();

    //find the list
    By xPath = By.XPath("//h2[.='The Latest']/../li//a");
    var linkCollection = _driver.FindElements(xPath);

    for (int i = 0; i < linkCollection.Count; i++)
    {
        //wait for the elements to be exist
        new WebDriverWait(_driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists(xPath));

        //Click on the elements by index
        if (i<=3)
        {
            _driver.FindElements(xPath)[i].Click();

        }
        else
        {
            break;
        }

        _driver.Navigate().Back();
        _driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(10));
    }

}