2013-08-14 19 views
29

Her bölümün altında birden çok bağlantı bulunan listeye sahibim. Her bölümün aynı bağlantıları var, her bölümün altındaki belirli bir bağlantıyı tıklamam gerekiyor. Aşağıdaki kodu yazdım ama çalıştırdığında bana stale element reference: element is not attached to the page document hatası veriyor. ana eleman başvurusu: öğe sayfa belgesine eklenmemiş

Bu

benim kodudur:

<div id="ucAdminMenu_divMenu"> 
    <ul id="sliding-navigation"> 
    <li class="sliding-element"> 
     <a href=" ">Claims Status</a> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Eligibility Status</a> 
    </li> 
    <li class="sliding-element"> 
     <h3>Section-1</h3> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Forms and Documents</a> 
    </li> 
    <li class="sliding-element"> 
     <a href=" HourBank.aspx?id=002">Hour Bank</a> 
    </li> 
    <li class="sliding-element"> 
     <h3>Section-2</h3> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Benefit Status</a> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Forms and Documents</a> 
    </li> 
    <li class="sliding-element"> 
     <h3>Section-3</h3> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Forms and Documents</a> 
    </li> 
    <li class="sliding-element"> 
     <h3>Testing Fund</h3> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Benefit Status</a> 
    </li> 
    <li class="sliding-element"> 
     <a href=" ">Order ID Card</a> 
    </li> 
    </ul> 
</div> 

aşağıda gibidir

public static void main(String[] args) throws InterruptedException 
{ 
    WebDriver driver = new ChromeDriver(); 
    driver.navigate().to("url......"); 
     driver.findElement(By.id("Login1_txtEmailID")).sendKeys("[email protected]"); 
    driver.findElement(By.id("Login1_txtPassword")).sendKeys("Testing1*"); 
    driver.findElement(By.id("Login1_btnLogin")).click(); 
    List<WebElement> LeftNavLinks=driver.findElements(By.xpath("//*[@id='sliding-navigation']//a")); 
    Thread.sleep(1000); 
    String ben="Benefit Status"; 
    String[] linkTexts = new String[LeftNavLinks.size()]; 
    int i = 0; 
    for (WebElement e : LeftNavLinks) 
    { 
     linkTexts[i] = e.getText(); 
     System.out.print(i+" " + linkTexts[i]+"\n"); 
     if(linkTexts[i].equals(ben)) 
     { 
      String BenefitStatLi="//*[@id='sliding-navigation']/li[%s]/a"; 
      System.out.print(i+" " + linkTexts[i]+"\n"); 
       driver.findElement(By.xpath(String.format(BenefitStatLi,i))).click(); 
      driver.findElement(By.xpath("//* [@id='divContentHolder']/div[1]/a[1]")).click(); 
     } 
     i++; 
    } 
} 

} 

Bu, HTML yapıdır Hata İz geçerli: istisna veren çizgi nedir

Exception in thread "main" 
org.openqa.selenium.StaleElementReferenceException: stale element 
reference: element is not attached to the page document 

cevap

31

?? IEDriver ile çalışırken sevk etmiş eleman DOM yapısında Aynı sorun bakıyordu

kaldırılır çünkü

Bunun nedeni. Bunun nedeni, javascript'in, referans verildikten sonra öğeyi bir kez daha yüklemesiydi, bu yüzden tarih referansım, UI'de doğru olsa bile, varolan bir nesneye işaret etti. Aşağıdaki geçici çözümü kullandım. Aynı size yardımcı olabilir eğer

try { 
    WebElement date = driver.findElement(By.linkText(Utility.getSheetData(path, 7, 1, 2))); 
    date.click(); 
} 
catch(org.openqa.selenium.StaleElementReferenceException ex) 
{ 
    WebElement date = driver.findElement(By.linkText(Utility.getSheetData(path, 7, 1, 2))); 
    date.click(); 
} 

bakın!

+0

linkTexts [i] = e.getText(); satırlar ikinci kez döngü yaparken hata veriyor –

+0

Çözüldü, sayfa yenileme 1 nedeniyle hata oldu. İlk önce tüm bağlantı metinlerini bir String dizi değişkenine kopyaladım ve daha sonra her bölümün altında gerekli bağlantıları tıklatmak için döngü için kullanıldı. (WebElement e: LeftNavLinks) için \t \t \t \t linkTexts [i] = e.GetText(); \t \t i ++; için } (int j = 0; j

+0

Yani aynı nedenden ötürü. Elemanlar önceki nedeniyle sayfa yenileme için DOM çıkarıldı belirlenen :) –

3

kullanın bu kod:

public class LinkTest 
{ 
    public static void main(String[] args) 
    { 
     WebDriver driver = new FirefoxDriver(); 
     driver.navigate().to("file:///C:/Users/vkiran/Desktop/xyz.html"); 
     List<WebElement> alllinks =driver.findElements(By.xpath("//*[@id='sliding-navigation']//a")); 
     String a[]=new String[alllinks.size()]; 
     for(int i=0;i<alllinks.size();i++) 
     { 
      a[i]=alllinks.get(i).getText(); 
      if(a[i].startsWith("B")) 
      { 
       System.out.println("clicking on this link::"+driver.findElement(By.linkText(a[i])).getText()); 
       driver.findElement(By.linkText(a[i])).click(); 

      } 
      else 
      { 
       System.out.println("does not starts with B so not clicking"); 
      } 
     } 
} 
} 
5

kullanımı bu kod elemanı takılır kadar beklemek:

boolean breakIt = true; 
     while (true) { 
     breakIt = true; 
     try { 
      // write your code here 
     } catch (Exception e) { 
      if (e.getMessage().contains("element is not attached")) { 
       breakIt = false; 
      } 
     } 
     if (breakIt) { 
      break; 
     } 

    } 
+1

benim için işe yaramadı ama yine de ilginç bir yaklaşım – Yar

+9

Bu hiç bir şey ifade etmiyor. – Sam

+0

Bu mantıklı, değişken adı "breakIt" açısından en açık değil. Bu, "eleman eklenmediği" anda, kesinti (gerçek) döngüsünden kopar, hata artık atılmaz. – emery

2

burada bir şey size koşullu ifadenin dışında döngü için kullandığınız olmasıdır .

IF deyiminizdeki koşulların karşılanmasından sonra, muhtemelen başka bir sayfaya gidersiniz, bu nedenle for döngüsü bir kez daha yineleme girişiminde bulunduğunda, farklı bir sayfada olduğunuz için eski öğe hatasını alırsınız.

aralığındaki kopyasını, if ifadenizin sonunda ekleyebilirsiniz, bu benim için çalıştı.

1

Sadece, tıklamak istediğiniz öğeyi bulduğunuzda döngüden kurtulun. örneğin :

List<WebElement> buttons = getButtonElements(); 
    for (WebElement b : buttons) { 
     if (b.getText().equals("Next"){ 
      b.click(); 
      break; 
     } 
3

idare için, ben şu tıklama yöntemini kullanın. Bu, öğeyi bulmayı ve tıklamayı deneyecektir. DOM bulmak ve tıkla arasında değişirse, tekrar deneyecek. Fikir şu ki başarısız olursa ve hemen tekrar denediğimde ikinci girişim başarılı olacaktır. Eğer DOM değişiklikleri çok hızlı olursa, bu işe yaramayacaktır.

public boolean retryingFindClick(By by) { 
    boolean result = false; 
    int attempts = 0; 
    while(attempts < 2) { 
     try { 
      driver.findElement(by).click(); 
      result = true; 
      break; 
     } catch(StaleElementException e) { 
     } 
     attempts++; 
    } 
    return result; 
} 
İlgili konular