(StaleElementException:Selenium)我该如何处理?

时间:2017-07-26 15:43:59

标签: java selenium

这是我第一次参与硒工作的第一天,我也没有深入了解Web技术的经验。

当我尝试访问DOM上的特定对象时,我一直面临着StaleElementException。

以下方法处理所有任务:

private void extract(WebDriver driver) {
    try {

        List<WebElement> rows = driver.findElements(By.xpath("//*[@id='gvSearchResults']/tbody/tr"));

        for (WebElement row : rows) {
            WebElement columns = row.findElement(By.xpath("./td[1]/a"));

            if (assertAndVerifyElement(By.xpath("//*[@id='gvSearchResults']/tbody/tr/td[1]/a"))) {
                columns.click();
            }

            List<WebElement> elements = driver
                    .findElements(By.xpath("//*[@id='ctl00_MainContent_pnlDetailsInd']/table/tbody/tr"));

            for (WebElement element : elements) {
                WebElement values = element.findElement(By.xpath("./td[1]"));
                System.out.print(values.getText() + " ");
                WebElement values2 = element.findElement(By.xpath("./td[2]"));
                System.out.println(values2.getText());
            }
            if(assertAndVerifyElement(By.xpath("//*[@id='ctl00_MainContent_btnBack']")))
                driver.findElement(By.xpath("//*[@id='ctl00_MainContent_btnBack']")).click();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

断言逻辑在这里:

public boolean assertAndVerifyElement(By element) throws InterruptedException {
    boolean isPresent = false;

    for (int i = 0; i < 5; i++) {
        try {
            if (driver.findElement(element) != null) {
                isPresent = true;
                break;
            }
        } catch (Exception e) {
            // System.out.println(e.getLocalizedMessage());
            Thread.sleep(1000);
        }
    }
    Assert.assertTrue("\"" + element + "\" is not present.", isPresent);
    return isPresent;
}

我尝试了一些解决方案,要求我使用等到预期的条件,但没有一个工作。

此外,如果您指出我可能在上述示例中使用的任何不良设计实践,我们将不胜感激。

2 个答案:

答案 0 :(得分:0)

我可以给你一个克服陈旧性的想法。

一般来说,如果在启动webelement之后更改了元素属性或某些内容,我们将获得Stale Exception。例如,在某些情况下,如果用户尝试在同一页面上单击同一元素但在页面刷新后,则会获取staleelement异常。

为了解决这个问题,我们可以创建新的webelement,以防页面被更改或刷新。下面的代码可以给你一些想法。

示例:

webElement element = driver.findElement(by.xpath("//*[@id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception

为了解决这个问题,我们可以将xpath存储在某个字符串中,然后使用它创建一个新的webelement。

String xpath = "//*[@id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.findElement(by.xpath(xpath)).click();   //This works

另一个例子:

for(int i = 0; i<5; i++)
{
  String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
  System.out.println(value);
}

希望这会对你有所帮助。感谢

答案 1 :(得分:0)

当在dom上更改了有问题的webelement并且对该webelement的初始引用丢失时,就会发生StaleElementException。

您可以再次搜索webelement

试试这个

try:
 element = self.find_element_by_class('')
 element.click()
except StaleElementReferenceException:
 element = self.find_element_by_class('')
 element.click()