如何用Protractor实现Angular5虚拟列表滚动查找指定元素?
Protractor测试Angular5虚拟列表滚动定位元素的解决方案
嘿,我懂你现在的难题——在Angular 5的虚拟列表里用Protractor定位不在当前视图的元素(比如第20条),毕竟这种列表滚动时会动态加载2-3条新数据,同时把顶部旧数据删掉,普通的滚动方法根本不管用。下面给你一套亲测有效的实现思路和代码:
核心思路
虚拟列表的核心特点是每次滚动只会加载少量新数据,同时销毁顶部的旧数据,所以不能直接通过固定位置滚动来定位目标元素。我们需要做的是:循环滚动加载新数据,每次滚动后检查目标元素是否已出现在DOM中并可见,直到找到元素或者达到最大尝试次数(避免无限循环)。
具体实现步骤
1. 编写滚动加载函数
首先写一个触发列表滚动到底部的函数,用来加载新数据。这里用Protractor执行原生JS来实现滚动,同时给一点等待时间让数据加载完成:
async function scrollToBottom() { // 替换成你的虚拟列表容器选择器,比如<div class="virtual-list">...</div> const listContainer = element(by.css('.virtual-list')); // 执行滚动到底部的JS代码 await browser.executeScript( 'arguments[0].scrollTop = arguments[0].scrollHeight', await listContainer.getWebElement() ); // 等待数据加载,时长根据你的应用实际加载速度调整,比如800ms await browser.sleep(800); }
2. 循环滚动+检查目标元素
接下来写一个主函数,循环调用上面的滚动函数,每次滚动后检查目标元素是否可见。这里要注意:不要用位置索引(比如nth-child)定位元素,因为虚拟列表会销毁顶部元素,DOM里的元素位置会动态变化,建议用元素的唯一标识(比如data-id属性)来定位:
async function locateTargetElement(targetId) { // 最大滚动尝试次数,防止无限循环,可根据实际需求调整 const maxAttempts = 10; let currentAttempt = 0; let targetElement = null; while (currentAttempt < maxAttempts) { try { // 用唯一ID定位元素,比如你的列表项是<div class="list-item" data-id="20">...</div> targetElement = element(by.css(`.list-item[data-id="${targetId}"]`)); // 检查元素是否在当前视图中可见 await targetElement.isDisplayed(); // 找到元素,退出循环 break; } catch (error) { // 元素不可见,滚动加载新数据 await scrollToBottom(); currentAttempt++; } } // 如果达到最大次数还没找到,抛出错误 if (currentAttempt >= maxAttempts) { throw new Error(`尝试滚动${maxAttempts}次后仍未找到目标元素(ID: ${targetId})`); } return targetElement; }
3. 调用函数定位并操作元素
最后,在你的测试用例里调用这个函数就可以了,比如要定位第20条元素:
// 测试用例示例 it('should locate the 20th item in virtual list', async () => { // 假设第20条数据的唯一ID是"item-20" const targetItem = await locateTargetElement('item-20'); // 对目标元素执行操作,比如点击 await targetItem.click(); // 后续的断言逻辑... });
关键注意事项
- 唯一标识优先:一定要用数据的唯一属性(比如data-id、data-key)定位元素,绝对不要依赖元素在DOM中的位置索引,否则滚动后索引会混乱。
- 调整等待时长:
browser.sleep()的时间要根据你的应用加载速度来调整,如果数据加载较慢,就适当延长,避免还没加载完就检查元素导致误判。 - 设置最大尝试次数:必须限制滚动的最大次数,防止因为目标元素不存在而陷入无限循环。
内容的提问来源于stack exchange,提问作者Murat Ozcan
相关产品推荐
相关产品推荐

