切换至DevTools后WebdriverIO遍历XPath元素报错求助
解决WebdriverIO DevTools模式下遍历XPath元素的DOM突变错误
问题原因
切换到DevTools模式后,$$返回的是实时DOM元素集合,当执行browser.back()时原页面DOM被销毁,之前获取的元素引用失效,导致迭代时抛出Failed to execute 'iterateNext' on 'XPathResult': The document has mutated since the result was returned错误。而Chromedriver模式下默认会预先获取元素快照,所以不会出现这个问题。
解决方案
方案1:循环时重新查询元素
避免一次性保存所有元素引用,每次循环都重新获取当前索引的元素:
// .spec.js file //... // 先获取元素总数 const postCount = await page.allBlogPosts.length; for (let i = 0; i < postCount; i++) { // 每次循环重新查询对应索引的元素 const post = await page.allBlogPosts[i]; await post.scrollIntoView(); // 执行你的操作... await browser.back(); } // ...
方案2:预先提取元素属性(推荐)
如果只是需要访问博客文章链接,可以先提取所有文章的href属性,直接通过URL跳转,完全避开DOM元素引用失效的问题:
// .spec.js file //... // 提取所有博客链接的href属性并保存 const postLinks = await Promise.all( (await page.allBlogPosts).map(post => post.getAttribute('href')) ); for (const link of postLinks) { await browser.url(link); // 执行你的操作... await browser.back(); } // ...
关于snapshotItem(i)的说明
你提到的snapshotItem(i)是原生XPathResult的快照方法,在WebdriverIO中不需要直接调用——上面两种方案已经间接实现了类似快照的效果:要么通过索引重新查询获取最新DOM元素,要么预先保存元素的静态属性,都能避免依赖活的DOM集合导致的突变错误。
内容的提问来源于stack exchange,提问作者chase
相关产品推荐
相关产品推荐

