陈旧元素引用:元素未附加到页面文档

Pat*_*nth 55 java list selenium-webdriver

我有列表,每个部分下有多个链接.每个部分都有相同的链接,我需要点击每个部分下的特定链接.我写了下面的代码但是当它执行时它给了我stale element reference: element is not attached to the page document错误.

这是我的代码:

public static void main(String[] args) throws InterruptedException 
{
    WebDriver driver = new ChromeDriver();
    driver.navigate().to("url......");
        driver.findElement(By.id("Login1_txtEmailID")).sendKeys("hourbank5@....com");
    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++;
    }
}

}
Run Code Online (Sandbox Code Playgroud)

这是HTML结构如下

<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>
Run Code Online (Sandbox Code Playgroud)

错误跟踪是:

    Exception in thread "main" 
org.openqa.selenium.StaleElementReferenceException: stale element 
reference: element is not attached to the page document
Run Code Online (Sandbox Code Playgroud)

Abh*_*ngh 62

什么是给出异常的线?

原因是因为您引用的元素已从DOM结构中删除

我在使用IEDriver时遇到了同样的问题.原因是因为javascript在我引用之后再次加载元素所以我的日期引用指向一个未存在的对象,即使它在UI上是正确的.我使用了以下解决方法.

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();
}
Run Code Online (Sandbox Code Playgroud)

看看是否可以帮助你!


小智 14

此错误有两个常见原因:该元素已被完全删除,或该元素不再附加到 DOM。

如果您已经检查过这是否不是您的情况,那么您可能面临与我相同的问题。

未找到 DOM 中的元素,因为 Selenium 搜索元素时您的页面未完全加载。为了解决这个问题,你可以设置一个明确的等待条件,告诉 Selenium 等待元素可以被点击。

from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
Run Code Online (Sandbox Code Playgroud)

请参阅:https : //selenium-python.readthedocs.io/waits.html

在 Java 中

import org.openqa.selenium.support.ui.ExpectedConditions;

WebDriverWait wait = new WebDriverWait(driver, 10);
element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
Run Code Online (Sandbox Code Playgroud)

请参阅:https : //www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html


小智 12

每当遇到此问题时,只需在出现错误的行上方再次定义Web元素

例:

WebElement button = driver.findElement(By.xpath("xpath"));
button.click();

//here you do something like update or save 

//then you try to use the button WebElement again to click 
button.click();
Run Code Online (Sandbox Code Playgroud)

由于DOM已更改,例如通过更新操作,因此您收到StaleElementReference错误。

解:

WebElement button = driver.findElement(By.xpath("xpath"));
button.click();

//here you do something like update or save 

//then you define the button element again before you use it
WebElement button1 = driver.findElement(By.xpath("xpath"));
//that new element will point to the same element in the new DOM
button1.click();

Run Code Online (Sandbox Code Playgroud)

  • 这解决了我的问题,如果您使用 Actions 类 Click() 方法来单击该元素,则您不能为每次单击使用相同的操作类对象,每次单击特定时都必须从操作类重新创建对象元素,否则将返回 StaleElementReference 错误 (2认同)

小智 6

当您找到要单击的元素时,只需打破循环即可。例如:

  List<WebElement> buttons = getButtonElements();
    for (WebElement b : buttons) {
        if (b.getText().equals("Next"){
            b.click();
            break;
        }
Run Code Online (Sandbox Code Playgroud)


小智 5

这里的问题是您在条件语句之外使用了 for 循环。

满足 IF 语句中的条件后,您可能会导航到另一个页面,因此当 for 循环尝试再次迭代时,您会收到陈旧元素错误,因为您位于不同的页面上。

您可以在 if 语句末尾添加一个中断,这对我有用。


小智 5

要处理它,我使用以下单击方法.这将尝试查找并单击该元素.如果DOM在查找和单击之间发生变化,它将再次尝试.这个想法是,如果它失败了,我立即再次尝试,第二次尝试将成功.如果DOM变化非常快,那么这将不起作用.

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;
}
Run Code Online (Sandbox Code Playgroud)