Protractor页面对象模型中处理返回元素数组定位器的后续问题
嘿,很高兴之前Xotabu4的回答帮你搞懂了页面对象!你提到的处理element.all($$)返回的元素数组问题,其实刚好是页面对象模型里“封装页面逻辑”的典型场景,我来给你捋捋具体怎么搞:
处理Protractor页面对象中的元素数组
核心思路就是把元素数组的定位、操作、验证逻辑全部封装在页面对象里,让测试用例只专注于业务场景,不用关心页面元素的细节。
1. 先在页面对象里封装元素数组的定位
首先,把需要的元素数组定义成页面对象的属性,用getter来封装定位逻辑,这样外部调用时完全不用管具体选择器:
class ProductListPage { // 封装商品列表的元素数组 get productItems() { return element.all($$('.product-item')); } // 封装每个商品名称的定位(基于数组项,私有方法避免外部调用) #getProductNameElement(item) { return item.$('.product-name'); } } module.exports = new ProductListPage();
2. 封装数组的操作与验证逻辑
别在测试用例里直接遍历数组做对比!把这些逻辑写成页面对象的方法,让页面对象来承担页面逻辑的处理:
class ProductListPage { // ... 上面的元素定义 // 获取所有商品名称的文本数组 async getAllProductNames() { return this.productItems.map(async item => { return this.#getProductNameElement(item).getText(); }); } // 验证所有商品名称都包含指定关键词 async allProductsContainKeyword(keyword) { const productNames = await this.getAllProductNames(); return productNames.every(name => name.includes(keyword)); } // 对比实际商品列表和预期列表是否完全一致 async matchExpectedProductList(expectedNames) { const actualNames = await this.getAllProductNames(); expect(actualNames).toEqual(expectedNames); } }
这样测试用例里的代码会非常简洁,完全聚焦于业务:
const productListPage = require('./productListPage'); describe('商品列表测试', () => { it('商品名称与预期完全匹配', async () => { await productListPage.matchExpectedProductList(['爆款卫衣', '休闲牛仔裤', '复古板鞋']); }); it('所有商品都带有「限时折扣」标签', async () => { const hasDiscountTag = await productListPage.allProductsContainKeyword('限时折扣'); expect(hasDiscountTag).toBe(true); }); });
3. 单个元素的操作封装
如果需要对数组里的某个元素做操作(比如点击、输入),也把这些逻辑封装到页面对象里:
class ProductListPage { // ... 上面的方法 // 点击指定索引的商品 async clickProductByIndex(index) { await this.productItems.get(index).click(); } // 点击名称匹配的商品 async clickProductByName(targetName) { const targetProduct = await this.productItems.filter(async item => { const itemName = await this.#getProductNameElement(item).getText(); return itemName === targetName; }).first(); await targetProduct.click(); } }
这么做的好处很明显:一旦页面的选择器发生变化(比如类名从.product-item改成.goods-item),你只需要修改页面对象里的一行代码,所有测试用例都不用动,完美符合页面对象模型“封装变化”的核心,同时测试用例的可读性也大大提升。
内容的提问来源于stack exchange,提问作者Monnie_tester
相关产品推荐
相关产品推荐

