使用firefox v57的Webdriver的StaleElementReference异常

时间:2018-01-08 13:06:29

标签: java selenium firefox

使用以下代码在firefox v57上运行我的Webdriver脚本时,我不断收到StaleElementReference异常。我尝试了各种各样的东西,但除了thread.sleep或捕获异常并重试我无法让它工作。

public List<String> readCoIData (String column) throws StaleElementReferenceException 
    {
        int colNumber 0; 
        WebTable searchResuIts = getTable(); 
        FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        wait.pollingEvery(250, TimeLinit.MILLISECONDS); 
        wait.with Timeout (30, TimeLlnit.SECONDS); 
        wait.ignoring (NoSuchElementException.class) ; 

        CustomLogger.addInfo(Logger, "Ensure that that the first column row contains text: " column ) ; 
        int colcount = searchResults.getColumnCount(); 
        CustomLogger. addlnfoLog4jOnly (logger , "colcount= " colcount )
        for (int col =1; col <= colcount; col++)
        { 
            CustomLogger.addInfoLogJOnly(Logger, "Get the cell data for col. Use a string as this does not go stale unlike a reference.' 
            String locator = String.format("pf_table_t2 > tbody:nthchild(1) > tr:nth-child(1) > td:nth-child(%d)", col); 
            wait.until(ExpectedConditions.presenceOfElementLocated(By. cssSelector (locator))) ; 

            if (driver.FindElement(By.cssSelector(locator)).getText().contains (column)) 
            {
                colNumber = Col; 
            }
        }

        CustomLogger.addInfoLogJOnly(Logger, "Assert that there is not 0 columns"); 
        assertThat (column + " not found' , colNumber !=0, is (true));
        List<String> colvalues = new ArrayList<String>();
        CustomLogger.addInfoLogJOnly(Logger, "Get the object .pf_paging a"); 
        List<WebElement) paging = driver.findElements(By.cssSelector(.pf_paging a)); 
        if (paging.size() !=0) 
        {
        CustomLogger.addlnfoLogJOnly ( logger , "If more than one result page, wait..." );
        wait.until(ExpectedConditions.visibilityOf((WebElement driver.findElement(By.cssSelector(".pf_paging_next_active"))));
        CustomLogger.addInfoLogJOnly(Logger, "Span with '>>' is found so loop through all pages and get the data"); 
        while (driver.findElements(By.cssSelector(".pf_paging_next_active")). size()  == 1)
        {
          for (int i=2; i<=searchResults.getRowCount(); i++)
          {
            String locator = String.format("pf_table_t2 > tbody:nthchild(1) > tr:nth-child(%d) > td:nth-child(%d)", I, colNumber); col);
            String cell Text = driver.findElement(By.cssSelector(locator)).getText();
            colvalues.add(cellText);
          }
         CustomLogger.addInfoLogJOnLy(Logger, "Click the Next Page Button ' to move onto next page and wait for the page to be visible.' 
         driver.findElements(By.cssSelector(.pf_paging_next_active a").click(); 
         CustomLogger.addInfoLogJ0nly(Logger, "Get & Wait for table after clicking next"); 
         // Get the element table again as we have clicked 'filter' and the DOM would have changed. 
         searchResults.getTable();}

    public WebTable getTable() 
{
    CustomLogger.addInfoLog450nLy(Iogger, "Wait and get the element table again as we have previously clicked 'filter' and the DOM would have changed"); 
    new WebDriverWait(driver, 30).until((ExpectedConditions<Boolean> driver -> ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));

    FluentWait(WebDriver» wait new 
    wait.pollingEvery(250, TimeLinit.MILLISECONDSS); 
    wait.with Timeout(30, TimeLlnit.SECONDS); 
    wait.ignoring (NoSuchEIementException.class) ; 

    CustomLogger.addInfo(Logger, "Wait until the results table is present.. 
    wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("pf_table_t2"))));
    CustomLogger.addInfo(Logger, "Get the results table");
    SearchResuItsTable = driver.FindElement(By.cssSelector("pf_table_t2"));
    WebTabIe searchResuIts = new WebTable(SearchResultsTabIe); 
    return searchResuIts; 
}

本质上,该页面有一些过滤条件和一个结果表,其中包含10行的结果,以获得您必须单击的每个新集合&gt;。即页面改变。 我在两个地方得到StaleElement异常,第一个是在定位器上获取文本(然后设置colNumber = Col)。第二次发生将celltext添加到colValues数组。 在这两个地方,我只是再次得到了元素。任何帮助,将不胜感激。提前谢谢。
请注意,我无法通过Chrome浏览器获取此功能。

1 个答案:

答案 0 :(得分:0)

只是给你一个简要介绍(如果你不知道的话)  发生StaleElementReferenceException因为网页上的webelement位置(更多地在DOM上)由于某些ajax或类似原因而发生了变化。巧合的是,这恰好发生在捕获webelement和对webelement执行操作之间。

例如:

//Getting the webelement
WebElement element = driver.findElement(By.id("id_value"));

//Location of the webelement changes between these two steps.

//Click on the webelement
element.click();

处理StaleElementReferenceException的方法之一是在发生异常的位置捕获异常并通过重新初始化webelement来处理异常。

例如:

try {
WebElement element = driver.findElement(By.id("id_value"));
element.click();
} catch (StaleElementReferenceException e) {
Thread.sleep(3000);
WebElement element = driver.findElement(By.id("id_value"));
element.click();
}

还有其他方法可以处理StaleElementReferenceException。您可以参考此link

处理StaleElementReferenceException的更好,更清晰的方法是为您尝试执行的操作创建方法。 例如: 如果你想点击一个webelement。

public static void click(By by) throws Exception {
    try {
        driver.findElement(by).click();
    } catch(StaleElementReferenceException staleElement) {
        Thread.sleep(3000);
        driver.findElement(by).click();
    } catch (Exception e) {
        e.printStacktrace();
    }
}

同样,您可以创建其他方法。