当前位置: 首页 > 知识库问答 >
问题:

Selenium WebDriver如何解决过时元素引用异常?

符国安
2023-03-14
import static org.junit.Assert.assertEquals;

 import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;


public class EnterActiveSubmissionIntegrationTest {
Map<String, Map<String, String>> tableData = new HashMap<String, Map<String, String>>();

@Test
public void testEnterActiveSubmission() throws Exception {
    // Create a new instance of the Firefox driver
    // Notice that the remainder of the code relies on the interface, 
    // not the implementation.
    System.setProperty("webdriver.chrome.driver", "C:/apps/chromedriver.exe");
    WebDriver driver = new ChromeDriver();

    // And now use this to visit Google
    driver.get("http://localhost:8080/strfingerprinting");
    // Alternatively the same thing can be done like this
    // driver.navigate().to("http://www.google.com");

    // Find the text input element by its name
    WebElement element = driver.findElement(By.linkText("Manage Submissions"));
    element.click();
    parseTableData(driver, "form:submissionDataTable_data", 1);
    assertEquals(tableData.get("form:submissionDataTable_data").get("12"), "Archived");

    WebElement newElement = driver.findElement(By.linkText("Add new"));
    newElement.click();

    WebDriverWait wait = new WebDriverWait(driver,10);
    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            WebElement button = driver.findElement(By
                    .name("createForm:dateInput_input"));

            if (button.isDisplayed())
                return true;
            else
                return false;

        }
    });

    WebElement textElement = driver.findElement(By.name("createForm:dateInput_input"));
    textElement.sendKeys("24/04/2013");
    WebElement saveElement = driver.findElement(By.name("createForm:saveButton"));
    saveElement.click();

    driver.navigate().refresh();

    parseTableData(driver, "form:submissionDataTable_data", 2);

    //Close the browser
    driver.quit();
}



private void parseTableData(WebDriver driver, String id, int expectedRows) {
    // Check the title of the page or expected element on page
    WebElement subTableElement = driver.findElement(By.id(id));
    List<WebElement> tr_collection=subTableElement.findElements(By.xpath("id('"+ id + "')/tr"));

    assertEquals("incorrect number of rows returned", expectedRows, tr_collection.size());
    int row_num,col_num;
    row_num=1;

    if(tableData.get(id) == null) {
        tableData.put(id, new HashMap<String, String>());
    }
    Map<String, String> subTable = tableData.get(id);
    for(WebElement trElement : tr_collection)
    {
        List<WebElement> td_collection=trElement.findElements(By.xpath("td"));
        col_num=1;
        for(WebElement tdElement : td_collection)
        {
            subTable.put(row_num + "" + col_num, tdElement.getText());
            col_num++;
        }
        row_num++;
    }
}
}
WebElement textElement = driver.findElement(By.name("createForm:dateInput_input")); 

if (button.isDisplayed())

异常跟踪

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
(Session info: chrome=26.0.1410.64)
  (Driver info: chromedriver=0.8,platform=Windows NT 6.0 SP2 x86) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 56 milliseconds
For documentation on this error, please visit:        http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.32.0', revision: '6c40c187d01409a5dc3b7f8251859150c8af0bcb', time: '2013-04-09 10:39:28'
System info: os.name: 'Windows Vista', os.arch: 'x86', os.version: '6.0', java.version: '1.6.0_10'
Session ID: 784c53b99ad83c44d089fd04e9a42904
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{platform=XP, acceptSslCerts=true, javascriptEnabled=true,   browserName=chrome, rotatable=false, driverVersion=0.8, locationContextEnabled=true,  version=26.0.1410.64, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true,  browserConnectionEnabled=false, nativeEvents=true, webStorageEnabled=true,   applicationCacheEnabled=false, takesScreenshot=true}]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at  sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at  sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:554)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:268)
at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:320)
at com.integration.web.EnterActiveSubmissionIntegrationTest$1.apply(EnterActiveSubmissionIntegrationTest.java:58)
at com.integration.web.EnterActiveSubmissionIntegrationTest$1.apply(EnterActiveSubmissionIntegrationTest.java:1)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208)
at com.integration.web.EnterActiveSubmissionIntegrationTest.testEnterActiveSubmission(EnterActiveSubmissionIntegrationTest.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

共有1个答案

符修杰
2023-03-14

首先,让我们弄清楚什么是WebElement。

WebElement是对DOM中元素的引用。

当您正在交互的元素被销毁然后重新创建时,会引发StaleElementException。现在大多数复杂的web页面会在用户与它交互时移动内容,这就需要销毁和重新创建DOM中的元素。

 类似资料:
  • 我正在使用for循环来处理表元素。在第一次迭代中,它将在页面上搜索所需的元素。如果该元素在该页面上不可用,那么它将在第二个页面上搜索。如果元素在第一个页面上可用,Webdriver会成功地找到该元素,但如果元素在第一个页面上不可用,则它会在第二个页面上查找该元素。但在这里,for循环失败,出现称为“stale Element exception”的异常。 错误消息: 线程“main”org.ope

  • 问题内容: 我在Selenium 2 Web驱动程序测试中具有以下代码,该代码在调试时有效,但是在构建中运行它时,大多数情况下会失败。我知道这一定与未刷新页面的方式有关,但不知道如何解决它,因此,任何有关我做错事情的指针都应该受到赞赏。我正在使用JSF primefaces作为我的Web应用程序框架。当我单击添加新链接时,会出现一个弹出对话框,其中包含一个输入框,我可以在其中输入日期,然后单击“保

  • 好的,我阅读了所有其他的链接,我尝试了上述不同解决方案的变体,但是它们都不适合我。 我的问题是,我有以下代码: 然而,我得到了以下错误: 这是篮子图标的css路径,它在菜单上。 网站是GWT,步骤如下:1。点击物品添加到购物篮2。增加到第三篮。点击篮子进入篮子。 然而,我似乎无法做到这一点。

  • 下面是我正在努力工作的代码。 我从一个站点地图页面获取所有锚元素,然后将所有这些元素放入一个列表中。然后,我使用从所有这些元素获取URL。在这里之前,代码运行良好。 然而,之后我将这些URL作为参数,并将其传递到方法,以使用。代码一直工作到第一个链接,但一旦加载了第一个页面,就会出现stale元素异常。

  • 问题内容: 我的网站上有一个选择控件。我正在使用页面对象与页面进行交互。如果我这样做(在我的课程下的前两行和我的方法中) 它以空指针失败。我也尝试了没有。 现在,如果我在我的方法中执行此操作,则一切正常,然后选择正确的项目 这是该控件的实际网页摘要(已编辑以保护无辜者) 让我说我可以解决我的问题, 但是 我不明白为什么“ 正常 ”路径无法正常工作。 问题答案: 那是因为该类具有以下构造函数: 见J

  • 我正在使用以下代码检索我的链接: 接下来,我呼吁: 然后 并且抛出过时的元素异常。 现在,考虑到,我本以为可以避免这个问题,但它仍然存在。 我很想在加载页面源代码后,将其放入lxml中,以完全避免这个问题。 建立和迭代链接之间的时间最多为一秒钟。 有没有其他人遇到过这样的问题,并找到了解决方案? 感谢您的指导。