使用Protractor循环滚动页面遇异常,求问题排查指导
问题分析与解决方案
你遇到的核心问题是同步while循环和Protractor的异步操作不兼容,导致循环根本没等滚动和文本获取完成就重复执行,所以arr[0]和arr[2]的值一直停留在初始的24和434,无法更新。
为什么原来的代码会无限循环?
Protractor的所有浏览器操作(比如executeScript、sleep、getText)都是异步的,返回Promise对象,但你的while循环是同步执行的:
- 调用
utils.scrollToElement后,函数里的异步滚动和休眠还没完成,循环就直接进入下一轮了; utils.getTextfrom也是异步的,你直接赋值给countTop,拿到的其实是Promise而不是实际文本,导致arrIn拆分的始终是旧值;- 你的
scrollToElement函数没有返回Promise,调用时无法用await等待它执行完毕。
修改后的代码实现
我们可以用async/await来处理异步操作,让循环等待每一步完成后再继续:
1. 修复滚动函数(让它返回Promise)
async scrollToElement(webElement: any) { try { // 等待滚动脚本执行完成 await browser.executeScript('window.scrollTo(0, 400);'); console.log("开始休眠2秒..."); // 等待休眠完成 await browser.sleep(2000); console.log("休眠结束"); } catch (err) { assert.fail("滚动失败: " + err.message); } }
2. 确保文本获取函数是异步的
如果你的getTextfrom还没处理异步,改成这样:
async getTextfrom(elementLocator: ElementFinder) { // 等待元素文本获取完成 return await elementLocator.getText(); }
3. 用异步循环替代同步while
把原来的while循环放到async函数里,用do-while配合await实现等待逻辑:
async waitForMatchingCounts() { let arr = []; let countTop; let arrIn; do { console.log('开始滚动...'); // 等待滚动完成 await utils.scrollToElement(this.scrollUpLink); // 等待获取最新的计数文本 countTop = await utils.getTextfrom(this.getTotalcountOnTop); arrIn = countTop.split(" "); arr[0] = arrIn[0]; arr[2] = arrIn[2]; console.log("当前值: " + arr[0] + " " + arr[2]); } while (arr[0] !== arr[2]); // 直到两个值相等才退出循环 }
4. 调用这个异步函数
在你的测试代码里,用await调用这个函数:
await this.waitForMatchingCounts();
关键注意点
- 所有涉及Protractor浏览器操作的步骤都要加
await,确保等待异步操作完成; - 不要用同步循环(比如普通while)来处理异步任务,必须用异步循环配合
async/await或者Promise链式调用; - 确保你的工具函数(比如
scrollToElement、getTextfrom)都返回Promise,这样才能被await等待。
内容的提问来源于stack exchange,提问作者Sachin Joshi
相关产品推荐
相关产品推荐

