2015-02-11 14 views
5

我试图从日期选择器。继选择日期代码如何在尝试从日期选择器中选择日期时修复“陈旧的元素引用异常”?

WebDriver d=new FirefoxDriver(); 
Actions a=new Actions(d); 
String date="14"; 
d.get("http://www.eyecon.ro/bootstrap-datepicker/"); 
d.findElement(By.cssSelector("div#dp3>span")).click(); 
List<WebElement> trs=d.findElements(By.cssSelector("div.datepicker-days>table>tbody>tr")); 
     for(WebElement tr:trs) { 
      List<WebElement> tds=tr.findElements(By.tagName("td")); 
      for(WebElement td:tds) { 
       if(date.equals(td.getText())) { 
        a.moveToElement(td).click().build().perform(); 

       } 
      } 

}

与上面的代码我在这行代码得到了陈旧的元素引用异常

"if(date.equals(td.getText())) {" 

所以我改变了这个代码

for(WebElement td:tds) { 
       while(i<4) { 
        try { 
         if(date.equals(td.getText())) { 
          a.moveToElement(td).click().build().perform(); 

         } 
         break; 
        }catch(Exception ex) { 

        } 
        System.out.println(i); 
        i++; 
       } 
      } 

现在我能够选择date.But脚本仍然抛出过时的元素引用exception.The脚本示值误差在这条线现在

List<WebElement> tds=tr.findElements(By.tagName("td")); 

我工作的这对过去3天内有关如何解决此问题的任何建议。 在此先感谢

+1

的可能的复制[硒的webdriver如何解决陈旧元素参考例外?](http://stackoverflow.com/questions/16166261/selenium-webdriver-how-to-resolve-stale-element-reference-例外) – NarendraC 2016-07-15 11:10:15

回答

4

在你的第一个代码,你点击的元素后,在DOM改变,如日期成为“14”,由于两者的for循环仍然迭代,因此它抛出StaleElementReferenceException

同样,在第二个代码,你没有打破“里面的for循环”这是迭代TD元素,但你没有打破“外”一个,那继续重复元素,因此它又扔了StaleElementReferenceException

分辨率: -你应该已经出来的两个for循环使用突破被点击的元素之后,因此避免了StaleElementReferenceException,在这个过程中。

下面的代码演示了如何能已经打破了这两个for循环中没有任何异常:

WebDriver d=new FirefoxDriver(); 
    d.manage().window().maximize(); //Maximizing window 
    d.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); //Implicit wait for 20 seconds 

    Actions a=new Actions(d); 
    String date="14"; 
    int flag=0; 

    d.get("http://www.eyecon.ro/bootstrap-datepicker/"); 
    d.findElement(By.cssSelector("div#dp3>span")).click(); 
    List<WebElement> trs=d.findElements(By.cssSelector("div.datepicker-days>table>tbody>tr")); 
    for(WebElement tr:trs) { 
     List<WebElement> tds=tr.findElements(By.tagName("td")); 
     for(WebElement td:tds) { 
      if(date.equals(td.getText())) { 
       a.moveToElement(td).click().build().perform(); 
       flag=1; // Set to 1 when the required element was found and clicked. 
       break; //To come out of the first for-loop 
      } 
     } 
     if(flag==1) 
      break; //Since the element was found, come out of the second for-loop. 
    } 

注: -我添加的代码为最大化窗口,太含蓄提供等待实际上,在编写硒脚本时建议这样做。

+0

谢谢你这么多。我通过解决这个问题给我很大的帮助。它的工作 – 2015-02-12 05:51:34

+0

很高兴为你解决..干杯.. :) – Subh 2015-02-12 05:54:09

0

根据我的理解,当你执行element.click()for循环DOM重载,这就是为什么它显示陈旧的元素异常。 使用下面的CSS选择器[它只会从预期的日期选择器中选择元素,因为在页面上有多个日期选择器] &在下面的匹配日期中应用break for循环。它会选择日期14 &中断循环无一例外 -

String date="14"; 
d.get("http://www.eyecon.ro/bootstrap-datepicker/"); 
d.findElement(By.cssSelector("div#dp3>span")).click(); 
List<WebElement> trs=d.findElements(By.cssSelector(".datepicker.dropdown-menu:nth-of-type(4)>div.datepicker-days>table>tbody>tr>td")); 
    for(WebElement td:trs) { 
     if(date.equals(td.getText())) { 
      td.click(); 
      break; 
     } 
    } 
+0

感谢您的建议 – 2015-02-12 05:52:01

0

您应该使用WebDriverWaitExpectedConditions来解决元素陈旧问题。下面是我测试过的代码的修改块,它可以工作。

driver.findElement(By.cssSelector("div#dp3>span")).click(); 
WebDriverWait wait = new WebDriverWait(driver, 30); 
List<WebElement> trs = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("div.datepicker-days>table>tbody>tr"))); 
datePicker: 
{ 
    for (WebElement tr : trs) { 
     List<WebElement> tds = tr.findElements(By.tagName("td")); 
     for (WebElement td : tds) { 
       wait.until(ExpectedConditions.not(ExpectedConditions.stalenessOf(td))); 
       if (date.equals(td.getText())) { 
         td.click(); 
         break datePicker; 
       } 
     } 
    } 
} 

有关更多信息,请WebDriverWaitExpectedConditions这里

+0

感谢您的建议 – 2015-02-12 05:52:39

+0

Np。我无耻地说,我仍然相信我的解决方案比接受的方式更优雅:) – nilesh 2015-02-12 14:15:23

+1

好吧,它很优雅。但在我接受的答案中,他给出了问题的明确解释。所以这就是我接受其他答案的原因 – 2015-02-16 07:56:06

0

找到解决我的陈旧元素引用异常的简单方法。

在Java与Selenium2尝试以下代码:

public WebElement cleanAndRebuildElement(final WebElement ee){ 
     WebElement e2; 
     try{ 
      e2=ee; 
      e2.isDisplayed(); 
      logger.info("Element is cleaned : Not Stale Anymore !"); 
     }catch (StaleElementReferenceException e){ 
       e2=null; 

cleanAndrebuildElement(EE);

 }catch(NoSuchElementException nse){ 
nse.printstacktrace(); 
      } 
     return e2; 
    } 
} 
+0

这解决了我们为什么会得到陈旧的元素引用异常的原因。使用Page Factory Web元素的用户很难找到并重建元素,因此无法刷新元素。页面工厂在调用时总是重新获取元素。通过重新分配参考,我们迫使Page Factory再次获取元素。这种方法有递归,请使用一些超时来打破循环。毕竟我们不想要一个无限循环的情况。 – 2017-10-17 09:23:43

相关问题