为什么在以下方法中抛出StaleElementReferenceException?

时间:2017-02-03 19:49:14

标签: c# selenium-webdriver selenium-chromedriver

我有以下方法用于点击页面上的某些下拉菜单:

protected void selectIthElementOffAllDropDowns(String selectElement, int entryOfDropdown) {

    ICollection<IWebElement> allElements = driver.FindElements(By.CssSelector(selectElement));

    foreach(IWebElement element in allElements) {
        if(element.IsDisplayed) {
            new SelectElement(element).SelectByIndex(entryOfDropdown);
        } 
    }
}

大约70%的时间代码按预期执行。但是,它偶尔会抛出一个StaleElementReferenceException。抛出它时,它会抛出以下行:

new SelectElement(element).SelectByIndex(entryOfDropdown);

我不明白的是element.IsDisplayed是如何成真的,但根据Selenium文档here,当元素被完全删除或元素不再附加到时,会抛出此错误DOM。有人能够解释这个错误是如何被抛出的吗?另外,如果正确抛出了这个错误,为什么if语句中的条件为真?

注意:我正在使用chromedriver使用OpenQA.Selenium运行这些测试

1 个答案:

答案 0 :(得分:0)

当页面在查找元素和对其执行操作之间重新加载时,通常会发生这种情况。

在执行任何操作之前,请始终确保元素存在。

在这种情况下,您使用foreach对列表/数组/对象集合执行某些操作,如果在任何时候页面已加载,那么这些对象将丢失,它们不会被视为附加到页。

问题是,在您找到object =&gt;后,页面会更改状态或重新加载你有一个没有附加到页面的对象,你不能使用它。如果你有多个对象并且通过它们循环,那么陈旧元素的可能性就会更高。

我不知道以下示例的正确性如何:假设您有一个页面对象/页面实例,您搜索一些元素并且您拥有该元素的对象,页面reloads =&gt;实例丢失并且创建了新实例,现在你有一些对象没有登录到页面对象,它们没有附加到这个页面,类似的元素在那里,但不是你的对象,你将不得不找到并创建新的元素的对象。

它可以随时更改,包括评估if条件后输入if