提交后在表单中重新填充后的Selenium StaleElementException

时间:2017-07-19 16:54:07

标签: javascript java ajax forms selenium

我有一个表单,我正在尝试自动填写我的一个Selenium脚本。有一个表单有大约4个文本字段,HTML看起来像这样

<input class="class" id="id" name="name" value="" autocomplete="off" wtx-context="stuff" type="text">

然后在填写这些表单后,会出现一个带有以下HTML代码的输入提交按钮

<input id="id2" class="class2" value="Add Material" wtx-context="morestuff" type="submit">

我已经使用了以下Java代码,并且成功地填写并提交了表单,但是一旦提交了表单,我假设发生的事情是它们在DOM上刷新然后我得到一个StaleElement异常抛出对我。通过访问主页并使用表单导航回到网页,我有点破解了我的方式,但如果有人知道,我正在寻找更优雅的解决方案。下面是我的Java代码。

Page.WriteToField(Page.Input_number(), "111111111");
Page.WriteToField(Page.Input_number2(), "222222222");
Page.WriteToField(Page.Input_date(), format.format(cal.getTime()));
Page.WriteToField(Page.Input_number3(), "3333");
Page.SubmitIngredient();

WriteToField()函数看起来是

public void WriteToField(WebElement field, String text) {
    field.click();
    field.clear();
    field.sendKeys(text);
}

我使用以下格式从我的页面类访问所有WebElements

public WebElement Input_number() {
        return wait.until(ExpectedConditions.elementToBeClickable(By.id("form1")));
}

1 个答案:

答案 0 :(得分:1)

为什么不在实际检查元素是否可点击之前尝试检查元素是否存在?

public WebElement Input_number() {
      wait.until(ExpectedConditions.presenceOfElementLocated(By.id("form1")));
      return wait.until(ExpectedConditions.elementToBeClickable(By.id("form1")));
}

<强>更新 - 我要求为元素的存在添加预期条件的原因是它确实再次执行查找元素操作。 [请参考下面presenceOfElementLocated方法的实现]所以我希望有人会得到元素作为回报。 [但我可能错了]

public static ExpectedCondition<WebElement> presenceOfElementLocated(final By locator) {
    return new ExpectedCondition<WebElement>() {
        public WebElement apply(WebDriver driver) {
            return ExpectedConditions.findElement(locator, driver);
        }

        public String toString() {
            return "presence of element located by: " + locator;
        }
    };
}

除此之外,如果您检查elementToBeClickable方法[在代码块下面]的实现,它不会执行查找操作,如果元素不可见或启用,则会抛出StaleElementReferenceException异常。

 public static ExpectedCondition<WebElement> elementToBeClickable(final WebElement element) {
    return new ExpectedCondition<WebElement>() {
        public WebElement apply(WebDriver driver) {
            WebElement visibleElement = (WebElement)ExpectedConditions.visibilityOf(element).apply(driver);

            try {
                return visibleElement != null && visibleElement.isEnabled()?visibleElement:null;
            } catch (StaleElementReferenceException var4) {
                return null;
            }
        }

        public String toString() {
            return "element to be clickable: " + element;
        }
    };
}

因此在检查元素是否可见之前检查元素的存在对我有意义[正如我之前所说,我可能错了]