循环执行Selenium代码触发StaleElementReferenceException异常求助
解决Selenium的StaleElementReferenceException问题
问题原因
你碰到的StaleElementReferenceException,本质是页面导航后,之前获取的WebElement已经和当前页面的DOM树完全脱离了。具体来说:
- 初始循环依赖的
listofItems是第一次加载商品页时获取的元素列表 - 当你调用
driver.navigate().to("https://www.saucedemo.com/inventory.html")回到商品页后,页面DOM已经重新渲染,之前的product元素早已失效,再调用product.click()必然触发错误 - 你在循环里重新获取了
listofItems,但循环迭代的还是最初的旧列表,新获取的元素根本没被用到,等于做了无用功
修复方案
别直接循环WebElement列表,改成先收集所有商品按钮的唯一标识(比如id),存储成字符串列表,再循环这个字符串列表——每次循环都通过id重新定位元素,确保操作的是当前页面的有效元素。
另外你的代码里每次循环都固定点击sauce-labs-fleece-jacket的加入购物车按钮,这明显是多余操作,建议删掉。
修改后的代码
// 先收集所有商品按钮的id,存成字符串列表 List<String> itemIds = new ArrayList<>(); List<WebElement> initialItems = driver.findElements(By.xpath("//button[starts-with(@id,'add-to-cart-')]")); for (WebElement item : initialItems) { itemIds.add(item.getAttribute("id")); } // 循环id列表,每次重新定位当前页面的元素 for (String itemId : itemIds) { // 回到商品页后,重新定位要操作的按钮 WebElement product = driver.findElement(By.id(itemId)); product.click(); driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); // 进入购物车并发起结算 driver.findElement(By.xpath("//*[contains(@class, 'shopping_cart_container')]")).click(); driver.findElement(By.xpath("//button[@id='checkout']")).click(); CadastraComprador("joao", "costa", "35510"); driver.findElement(By.xpath("//*[contains(@class, 'submit-button btn btn_primary cart_button btn_action')]")).click(); comparaPrecoTotal("Item total: $65.98"); buttonFinish.click(); // 回到商品页,准备下一次循环 driver.navigate().to("https://www.saucedemo.com/inventory.html"); }
额外优化建议
- 隐式等待只需提前设置一次,不用每次循环重复配置
- 优先用id定位元素,比xpath更稳定高效
- 如果结算总价和当前商品挂钩,
comparaPrecoTotal方法要根据商品动态调整预期值,不然固定用$65.98会出现校验错误
内容的提问来源于stack exchange,提问作者joao victor
相关产品推荐
相关产品推荐

