Nightwatch测试如何将嵌套函数封装为页面自定义命令循环操作元素
问题根源
你遇到的报错核心是this指向丢失,外加2处小的笔误/用法错误:
- 嵌套的普通函数会重置
this指向,导致回调内部的this不再指向页面对象实例,自然找不到elements这类页面对象内置方法 counterOfItemsInList的定位策略属性名写错了,你写的是locatorStrategy,正确属性是locateStrategy- 用@前缀引用已定义的页面元素时,不需要额外指定定位策略,Nightwatch会自动读取你在元素配置里写的定位规则
修正后的productFuntionalityListPage.js完整代码
module.exports = { elements: { counterOfItemsInList: { // 修正属性名错误 locateStrategy: 'css selector', selector: "input[data-id='counter']", }, expandCollapseBtn: { locateStrategy: 'css selector', selector: '.expand_collapse_btn', }, listOfItems: { locateStrategy: 'css selector', selector: '.list_of_items', } }, commands: [{ displayFunctionsList: function () { // 箭头函数保留外层this指向(即页面对象实例) const displayFunctionsList = (elems) => { // forEach的回调也用箭头函数,不改变this指向 elems.value.forEach((element) => { this.elementIdClick(element.ELEMENT) .waitForElementVisible('@listOfItems') .pause(2000) }) } // 用@别名不需要传定位策略,直接传元素别名即可 this.elements('@expandCollapseBtn', displayFunctionsList, 5000) // 支持链式调用 return this }, closeFunctionsList: function () { const closeFunctionsList = (elems) => { elems.value.forEach((element) => { this.elementIdClick(element.ELEMENT) .waitForElementVisible('@counterOfItemsInList') .pause(2000) }) } this.elements('@expandCollapseBtn', closeFunctionsList, 5000) return this } }] }
可选替代方案(不习惯箭头函数可采用)
如果不想用箭头函数,也可以在自定义命令开头提前存储页面对象引用,所有内部调用都用存储的变量替代this即可,效果完全一致:
displayFunctionsList: function () { // 提前存储页面对象引用 const self = this function displayFunctionsList(elems) { elems.value.forEach(function (element) { self.elementIdClick(element.ELEMENT) .waitForElementVisible('@listOfItems') .pause(2000) }) } self.elements('@expandCollapseBtn', displayFunctionsList, 5000) return self }
你现有的测试调用代码不需要做任何修改,直接运行即可正常执行。
内容的提问来源于stack exchange,提问作者Estefania Lomonaco
相关产品推荐
相关产品推荐

