java 过期要素参考异常:如何解决?

bq3bfh9z  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(203)

**Problem Statement:**第二次执行for循环时,出现Stale Element Exception。
说明:

我使用for循环来处理表元素。在第一次迭代中,它将在页面上搜索所需的元素。如果该元素在该页面上不可用,则它将在第二个页面上搜索。如果该元素在第一个页面上可用,则Webdriver会成功找到该元素,但如果该元素在第一个页面上不可用,则它将在第二个页面上查找该元素。但是这里for循环失败,出现了名为“Stale Element Exception”的异常。
错误信息:
线程“main”org.openqa.selenium.StaleElementReferenceException异常:过时的元素引用:元素未附加到页面文档

代码:

List <WebElement> allAmountValues = driver.findElements(By.xpath("(//table[@width=760][@cellspacing=1])[2]/tbody/tr/td[8]/div"));

     for(int i =0;i<allAmountValues.size();i++){
       System.out.println("Value are : "+allAmountValues.get(i).getText().replaceAll("\\s+", " "));
     }


String testValue = "100000";
 System.out.println("No.of Rows in the Table : "+allAmountValues.size());                

               for (int i1 =1; i1<allAmountValues.size();i1++) {

                    String amount = allAmountValues.get(i1+1).getText().replaceAll("\\s+","");
                    //System.out.println("amount Values : "+amount);
                    System.out.println("Value are : " + allAmountValues.get(i1).getText() + "== Corresponding link is : " + clicklinks.get(i1).getText());

                    if (amount.equalsIgnoreCase(testValue)) {
                        System.out.println("Found:" +testValue);

                        clicklinks.get(i1).click();
                        waitDriver();
                        driver.navigate().back();

                      break;
                    }
                    else
                    {
                        WebElement clickNext = driver.findElement(By.xpath("//a[contains(text(), 'Next')]"));
                        clickNext.click();

                    }

               }

                for(int rw=2;rw<allAmountValues.size();rw++)
                {
                    WebElement a1 = driver.findElement(By.xpath("(//table[@width=760][@cellspacing=1])[2]/tbody/tr["+rw+"]/td[8]/div/span"));
                     String amm = a1.getText().replaceAll("\\s+", "");
                     System.out.println("Current value is:" +amm);
                     if(amm.equalsIgnoreCase("100000"))
                     {
                         WebElement a2 = driver.findElement(By.xpath("/html/body/form/div/table/tbody/tr/td/table/tbody/tr[5]/td/table/tbody/tr["+rw+"]/td[1]/div/input[6]"));
                         a2.click();
                         break;
                     }
                }
                   WebElement authoriseButton = driver.findElement(By.xpath("//input[@name='btnAuthorise']"));
                  if(authoriseButton.isEnabled())
                  {
                      authoriseButton.click();
                  }
                  else
                  {
                      System.out.println("Authorise Button is not enabled");
                  }

         }

我在以下位置遇到过时元素错误异常:String amount = allAmountValues.get(i1+1).getText().replaceAll("\\s+","");这行。任何帮助将不胜感激。

yquaqz18

yquaqz181#

原因:

allAmountValues是最初存储的,所以当你在页面之间移动时,你会尝试使用之前存储的相同元素;给你造成的伤害StaleElementException

解决方案:

您必须在每次离开页面并返回原始页面后再次识别allAmountValues

zqdjd7g9

zqdjd7g92#

当使用findElement/findElements时,Selenium以引用的形式跟踪所有元素。当重用元素时,Selenium使用该引用,而不是在DOM中再次查找元素。但有时由于 AJAX 请求和响应,该引用不再新鲜,因此会抛出StaleElementReferenceException。
我们将创建一个单独的click方法,并将要单击的元素作为参数传递给它。我们的想法是重新初始化元素并再次找到它。

public void clickElement(WebElement element) {
try {
    element.click();
} catch (StaleElementReferenceException stale) {
    System.out.println("Element is stale. Clicking again");
    element = reInitializeStaleElement(element);
    element.click();
}
}
// method to re-initialize the stale element
public WebElement reInitializeStaleElement(WebElement ) {
// lets convert element to string, so we can get it's locator
String elementStr = element.toString();
elementStr = elementStr.split("->")[1];
String byType = elementStr.split(":")[0].trim();
String locator = elementStr.split(":")[1].trim();
locator = locator.substring(0, locator.length() - 1);
switch (byType) {
    case "xpath":
        return DRIVER.findElement(By.xpath(locator));
    case "css":
        return DRIVER.findElement(By.cssSelector(locator));
    case "id":
        return DRIVER.findElement(By.id(locator));
    case "name":
        return DRIVER.findElement(By.name(locator));
}
}

相关问题