【问题标题】:Getting StaleElementReferenceException when iterating through a list of WebElements遍历 WebElement 列表时获取 StaleElementReferenceException
【发布时间】:2019-08-02 15:59:39
【问题描述】:

我试图自动化以下场景:

  • 访问 amazon.com
  • 搜索耳机
  • 将第一个结果页面中的所有畅销书添加到购物车

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

  • 访问 amazon.com
  • 在搜索字段中输入文字“耳机”​​li>
  • 点击搜索按钮
  • 点击标记为“畅销书”的链接
  • 点击“加入购物车”按钮
  • 返回结果页面
  • 点击另一个标记为“畅销书”的链接
  • 点击“加入购物车”按钮
  • 返回结果页面

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

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

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

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();

【问题讨论】:

  • driver.navigate().back(); - 这将刷新页面上导致此 staleElementReferenceException 的元素。
  • 好的。谢谢(你的)信息。你能建议我一个解决方法吗?
  • 我应该打开链接新标签并在完成后关闭标签吗?
  • 这样,我可以在不刷新元素的情况下回到结果页面。
  • 您可以考虑将hrefs(单个产品的url)存储在一个列表中,然后导航到hrefs,点击添加到购物车,导航下一个href,等等......

标签: selenium selenium-webdriver staleelementreferenceexception


【解决方案1】:

当您在浏览器中单击元素或 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();

}

【讨论】:

  • 试过上面的代码。当页面中有 4 个畅销书时,仅将 2 个畅销书添加到购物车。它将进入所有 4 个畅销产品页面,但只有 2 个被添加到购物车中。
  • 尝试使用`driver.findElements(By.xpath("xpath of bestsellers")).get(0).click();` 只需将i 替换为0 以便始终将添加第一项。
  • 不,我想在首页添加所有畅销商品。
  • 点击“加入购物车”后,会显示“前往购物车”和“继续结帐”选项。我已经等他们确认点击了“添加到购物车”,否则我就会知道问题所在。有效。我已经更新了问题中的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 2018-11-20
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 2015-09-21
相关资源
最近更新 更多