Protractor页面对象定义异常:随机选择元素功能失效求助
解决Protractor页面对象中随机选择下拉选项的同步问题
首先咱们拆解下你遇到的报错:这个同步错误的核心原因,是你直接在页面对象的构造函数里执行了randomFacility的逻辑——而这时候页面可能还没完成Angular初始化,Protractor还没和页面建立好同步连接,就触发了元素计数和选择的操作。
而facilityList能正常工作,是因为它是一个惰性求值的元素定位器(比如element.all(by.xxx)),它不会立即去查找元素,只有当你在测试用例里实际调用它的方法(比如count()、get())时,才会和浏览器通信,这时候页面已经加载完成,同步也没问题了。
你完全可以在页面对象里做这类逻辑处理!不需要放到conf.js里
问题出在实现方式上,不能把randomFacility写成直接求值的属性,要把它改成异步方法或者异步getter,确保逻辑在页面同步完成后执行。给你两个可行的写法:
写法1:用异步方法封装
class YourPageObject { constructor() { // 保持原来的facilityList定位器 this.facilityList = element.all(by.css('select#facility option')); } // 封装成async方法,调用时用await等待 async getRandomFacility() { // 先等待获取选项总数(这一步会自动触发Protractor的同步) const optionCount = await this.facilityList.count(); // 生成随机索引 const randomIdx = Math.floor(Math.random() * optionCount); // 返回随机选中的选项 return await this.facilityList.get(randomIdx); } }
在测试用例里这样调用:
const page = new YourPageObject(); const randomFacility = await page.getRandomFacility(); await randomFacility.click(); // 或者其他操作
写法2:用异步getter属性
如果你更习惯用属性的方式访问,也可以写一个异步getter:
class YourPageObject { constructor() { this.facilityList = element.all(by.css('select#facility option')); } get randomFacility() { // 用自执行异步函数返回Promise return (async () => { const optionCount = await this.facilityList.count(); const randomIdx = Math.floor(Math.random() * optionCount); return await this.facilityList.get(randomIdx); })(); } }
测试用例里调用:
const page = new YourPageObject(); const randomFacility = await page.randomFacility; await randomFacility.click();
额外提醒
如果你的页面里有非Angular的部分(比如跳转后的页面),可以在需要的时候临时关闭Angular同步:
await browser.waitForAngularEnabled(false); // 执行非Angular页面的操作 await browser.waitForAngularEnabled(true); // 操作完再打开
但从你的facilityList能正常工作来看,页面本身是Angular的,所以主要问题还是randomFacility的执行时机不对,改成异步方法/getter就能解决啦。
内容的提问来源于stack exchange,提问作者Reverend Bubbles
相关产品推荐
相关产品推荐

