首页 > 解决方案 > 遍历 WebElement 列表时获取 StaleElementReferenceException

问题描述

我试图自动化以下场景:

我为这个场景编写脚本所遵循的步骤:

所有畅销书都有相同的 xpath:

//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span

所以我实现了一个 WebElements 列表,如下所示:

List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));

我已经通过 3 种方式实现了点击链接并使用循环添加到购物车,如下所示:

for(WebElement product: bestsellers) {
    product.click();
    clickOnAddToCartButton();
    driver.navigate().back();
}



for(int i=0; i<bestsellers.size(); i++) {
        System.out.println(bestsellers.size());
        bestsellers.get(i).click();
        clickOnAddToCartButton();
        driver.navigate().back();

    }



Iterator<WebElement> i = bestsellers.iterator();
    while(i.hasNext()) {
        WebElement product = i.next();
        wait.until(ExpectedConditions.elementToBeClickable(product));

        product.click();
        clickOnAddToCartButton();
        driver.navigate().back();
    }

当我运行脚本时,“畅销书”列表中有 3 个元素。当循环执行时,第一个元素被点击并添加到购物车中,驱动程序导航回结果页面。然后我使用上述 3 种方式得到 staleElementReferenceException 。

更新:我已经实现了如下场景:

for(int i=0; i<bestsellers.size(); i++) {

        System.out.println("Current :" + i);
        wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")));
        driver.findElements(By.xpath(".//span[.='Best Seller']/../../../../../../../../following-sibling::div/div/following-sibling::div/div/div/div/div/div/h2/a/span")).get(i).click();
        clickOnAddToCartButton();
        //clickOnViewCart();
        try {
            wait.until(ExpectedConditions.elementToBeClickable(cartButton));
        }catch(TimeoutException e) {
            wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));
        }
        if(i==(bestsellers.size()-1)) {
            try {
                wait.until(ExpectedConditions.elementToBeClickable(cartButton));    
                cartButton.click();
                break;
            }catch(TimeoutException e) {
                wait.until(ExpectedConditions.elementToBeClickable(viewCartButton));    
                viewCartButton.click();
                break;
            }
        }

        driver.navigate().back();

标签: seleniumselenium-webdriverstaleelementreferenceexception

解决方案


当您在浏览器中单击元素或 back() 时,元素引用将在 selenium 中更新,因此您不能指向具有旧引用的元素并导致StatleElementException.

当您必须遍历多个元素交互时,请考虑这种方法。

List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
for(int i=0; i<bestsellers.size(); i++) {
    System.out.println("Current Seller " + i);
    // here you are getting the elements each time you iterate, which will get the
    // latest element references
    driver.findElements(By.xpath("xpath of bestsellers")).get(i).click();
    clickOnAddToCartButton();
    driver.navigate().back();

}

推荐阅读