PageFactory中的StaleElementReference异常

时间:2017-06-30 04:18:53

标签: selenium selenium-webdriver pageobjects page-factory staleelementreferenceexception

我正在尝试学习PageFactory模型。我理解当我们执行initElements时,WebElements就位于其中。比如说,我点击了一个webelement,因此DOM中的其他一个元素发生了变化。现在,显然我会在这里找到StaleElementReferenceException。我该如何解决这个问题?

我是否应该再次发现特定的WebElement知道DOM中的WebElement属性可能发生了变化?还是有另一种方法来处理这个问题?

3 个答案:

答案 0 :(得分:10)

StaleElementReferenceException

StaleElementReferenceException扩展WebDriverException并指示该元素的先前引用现在陈旧,并且该元素引用不再出现在页面的DOM上。

常见原因

  • 面对 StaleElementReferenceException 背后的常见原因如下:
    • 该元素已被完全删除。
    • 该元素不再附加到DOM。
    • 该元素所属的网页已刷新。
    • (上一个)元素已被 JavaScript AjaxCall 删除,并被具有相同ID的(新)元素替换或其他属性。
  • 解决方案如果(旧)元素已替换为新的相同元素,则简单的策略是使用findElement()findElements来查找元素试。

回答您的疑问

  1. 当我们执行initElements时,WebElements位于:当您调用initElements()方法时,该页面的所有 WebElements 将被初始化。例如,

    LoginPageNew login_page = PageFactory.initElements(driver, LoginPageNew.class);
    

    这行代码将初始化LoginPageNew.class范围内定义的所有静态 WebElements ,无论何时何地从自动化脚本调用它。

  2. 我点击了一个webelement,因为DOM中的其他一个元素发生了变化:这几乎是可能的。

    • 例如,通常在click()代码上调用<input>不会触发HTML DOM上任何 WebElements 的任何更改。
    • click()代码或<button>代码上调用<a>可能会调用 JavaScript Ajax 删除元素或者可以用具有相同ID或其他属性的(新)元素替换(previous)元素。
  3. 结论

    因此,如果 WebDriver 抛出 StaleElementReferenceException ,这意味着即使元素仍然存在,引用也会丢失。我们应该丢弃当前的引用,并在它附加到DOM时再次找到 WebElement 来替换它。这意味着您必须通过initElements()方法重新初始化该类,该方法将重新初始化该页面中定义的所有 WebElements

    解决方案

    如果旧元素已替换为新的相同元素,则简单的策略是调用WebDriverWaitExpectedConditions联系以查找元素。

    您可以在以下网址找到相关的详细讨论:

    参考

    以下是此讨论的参考资料:

答案 1 :(得分:1)

## spaghetti plot p <- ggplot(data = sampleData, aes(x = vis, y = vol, group = id)) + geom_line(alpha = 0.2) + scale_x_continuous(breaks = 1:8) p ## add model prediction q <- p + geom_line(data = pred_dat, aes(x = vis, y = exp(pred), color = factor(caf)), inherit.aes = FALSE) + labs( x = "Years since Baseline", y = "ln(vol), ln(mL/m)", colour = "Caffeine", title = "Spaghetti Plot of vol Over Time by Caffeine Intake" ) q 抛出两种情况

该元素不再附加到db.collection('type').find({"_id":objId}).toArray(function(err, typeInfoResult){ try{ if(err){ res.send(errMsg); } else{ var business_id = typeInfoResult.business_id; db.get().collection('business_info').findOne({"_id":ObjectID(business_id)}, function(err, businessInfoQuery){ if(err){ res.send(errMsg); } else{ var completetypeDetail = {typeDetails:typeInfoResult, BusinessDetails:businessInfoQuery}; res.send(completetypeDetail); } }) } }catch(err){ res.send(errMsg); } }); 。 该元素已被完全删除。

当发生这种情况时,您将代码包装在Stale element exception中,然后您可以根据需要循环并重试多次,直到成功为止。

DOM

答案 2 :(得分:0)

这是PageFactory实现的一个已知问题。

如果不幸的是,在找到的元素与单击的元素之间的瞬间,该元素变得过时,则会出现此错误。不幸的是,如果PageFactory代码变得陈旧并引发异常,则它不会尝试再次查找该元素。

我会将其归类为PageFactory的错误,如果元素变旧,它将自动重新查找元素(除非使用@CacheLookup批注)。

撤回initElements的建议不会解决任何问题,您只需初始化一次元素,因为这会将Java代理类绑定到有问题的元素。页面工厂实现应该消除StaleElementReferenceExceptions的可能性(因此这是一个错误)