2015-02-11 48 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

相關問題