Protractor+Selenium测试Polymer/Angular应用:虚拟滚动DOM元素获取问题
解决Protractor中获取原生DOM元素属性的问题
首先,你遇到的核心问题是:Protractor会自动把executeScript返回的DOM元素包装成WebElement对象,所以直接返回元素后,在then回调里拿到的是WebElement,没法直接访问它的原生DOM属性(比如baseList)。
直接在脚本中返回目标属性
解决方法很简单:不要返回整个DOM元素,而是在executeScript里直接返回你需要的baseList属性。这样Protractor会把属性值(而不是WebElement)传递到then回调中。
修改后的代码如下:
browser.executeScript('return document.querySelector("virtual-scroll").baseList;') .then(function(baseList) { console.log(baseList); // 这里拿到的就是原生DOM中的baseList属性值了 });
针对虚拟滚动和Shadow DOM的额外优化建议
考虑到你的测试场景(Polymer/Angular应用、Shadow DOM、虚拟滚动),还有几个小技巧能提升测试稳定性:
等待虚拟滚动加载完成:虚拟滚动会动态加载内容,测试时可以通过监听
baseList的变化,或者等待特定条目出现来确保内容加载完毕。比如:// 等待baseList中的条目数量达到预期 browser.wait(function() { return browser.executeScript('return document.querySelector("virtual-scroll").baseList.items.length;') .then(function(length) { return length >= 10; // 假设需要至少10条数据 }); }, 5000); // 超时时间5秒直接通过原生DOM操作Shadow DOM元素:如果自定义CSS定位器因为DOM变动不稳定,可以在
executeScript里直接用原生JS操作Shadow DOM,比如:// 获取Shadow DOM内的元素 browser.executeScript(` const scrollElement = document.querySelector("virtual-scroll"); return scrollElement.shadowRoot.querySelector('.list-item'); `).then(function(itemElement) { // 这里拿到的是WebElement,但可以用Protractor的方法操作它 itemElement.click(); });利用Web组件的公开API:既然开发人员已经暴露了
baseList这样的公开属性,完全可以基于这些API来编写测试,比依赖DOM结构更稳定——毕竟API的变动频率远低于DOM结构。比如直接通过baseList来获取条目、判断加载状态等。
内容的提问来源于stack exchange,提问作者JiggyJinjo
相关产品推荐
相关产品推荐

