StaleElementReferenceException

StaleElementReferenceException

在我的Selenium测试代码中,我有几行内容


单击一个复选框
从选择框中选择一个项目
单击按钮以提交表单


这是代码

WebElement selectAllElement = driver.findElement(By.id("filterForm:selectAll"));
if (selectAllElement.isSelected())
{
    selectAllElement.click();
}

Select selectLocation = new Select(new WebDriverWait(driver, 30)
    .until(ExpectedConditions
    .presenceOfElementLocated(By.id("filterForm:selectLocation"))));

selectLocation.selectByVisibleText(location);

WebElement filterButton = driver.findElement(By.id("filterForm:filterButton"));
filterButton.click();


尝试检索页面上的Select元素时,我收到了StaleElementReferenceException,为避免这种情况,我在此元素上添加了一个明确的等待,如上面的代码所示。

但是我仍然得到一个StaleElementReferenceException

编辑(这些元素的HTML)

<form id="filterForm" name="filterForm" method="post" action="/UsersJSFMavenApplication/faces/index.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="filterForm" value="filterForm" />
<input id="filterForm:selectAll" type="checkbox" name="filterForm:selectAll" checked="checked" title="allUsers" onclick="mojarra.ab(this,event,'valueChange',0,'filterForm:filterGrid usersForm')" />All users<table id="filterForm:filterGrid">
<tbody>
<tr>
<td><input id="filterForm:userName" type="text" name="filterForm:userName" disabled="disabled" /></td>
<td><select id="filterForm:selectLocation" name="filterForm:selectLocation" size="1" disabled="disabled">   <option value="Keynsham">Keynsham</option>
    <option value="London">London</option>
    <option value="Silicon Valley">Silicon Valley</option>
</select></td>
<td><input id="filterForm:filterButton" type="submit" name="filterForm:filterButton" value="Filter" disabled="disabled" /></td>
</tr>
</tbody>
</table>
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-8198231560613594227:-8434387391056535341" autocomplete="off" />
</form>

最佳答案

几周前,我遇到了类似的问题。阅读StaleElementException首先是个好主意。

我的问题是在选择元素和执行某些操作之间进行了异步调用。我的解决方案是将try catch封装在while循环中,并在引发Exception之前尝试多次单击元素。像这样:

     public static void clickElement(By by) throws Exception {
        boolean isClicked = false;
        int attempts = 0;
        while(!isClicked && attempts < 5) {
            try {
                WebElement element = driver().findElement(by);
                element.click();
                isClicked = true;
            } catch(StaleElementReferenceException e) {
                attempts++;
                System.out.println("[DEBUG] StaleElementReference exception caught, trying to locate and click element again");
            }
        }
        if(!isClicked) {
          throw new Exception("Could not click " + by + ", after 5 attempts");
        }
     }

10-06 02:24