Nightwatchjs:如何在不创建错误/失败/异常的情况下检查元素是不是存在
Posted
技术标签:
【中文标题】Nightwatchjs:如何在不创建错误/失败/异常的情况下检查元素是不是存在【英文标题】:Nightwatchjs: how to check if element exists without creating an error/failure/exceptionNightwatchjs:如何在不创建错误/失败/异常的情况下检查元素是否存在 【发布时间】:2015-10-19 15:24:06 【问题描述】:在我正在测试的页面中,可能会显示两个按钮:BASIC 或 ADVANCED。
我希望能够判断“高级”按钮是否正在显示——如果是,请单击它。
如果显示 BASIC 按钮,我什么也不想做,继续我的测试。
我尝试过的所有 Nightwatchjs 选项都会生成失败消息。例如,如果我“waitforpresent”或“waitforvisible”并且按钮不存在,它会生成错误/失败。我只想知道存在哪个按钮,以便我可以在我的代码中做出决定。
这是我尝试过的:
try
browser.isVisible('#advanced-search', function(result) console.log(result.state); )
catch (myError)
console.log(myError);
想法?
【问题讨论】:
不应该是在Nightwatchjs
之上的一个简单的if/else逻辑来确定元素的可见性吗?您通常不希望测试寻找一些可能不存在的元素(至少为了性能)。在这种情况下,我会查看该元素是否存在,否则(可能尝试/捕获)也可以
我已经尝试过这种构造......但是一旦发出 Nightwatchjs “等待”或“可见”语句,就会引发错误。
您尝试过的一些代码怎么样?可以分享一下吗?
这里是一个例子:try browser.isVisible('#advanced-search', function(result) console.log(result.state); ) catch (myError) console.日志(我的错误);
【参考方案1】:
您可以通过使用Selenium protocol "element" 和回调函数来检查结果状态以确定是否找到该元素来实现此目的。例如:
browser.element('css selector', '#advanced-search', function(result)
if(result.status != -1)
//Element exists, do something
else
//Element does not exist, do something else
);
【讨论】:
我在一个简单的谷歌主页示例中尝试了几个 .elements 命令,而 Saifur 的答案实际上是正确的。如果元素不存在,状态码将设置为 0,但元素数组将为空。因此你的答案是错误的:( 您是对的,当您使用.elements()
时,状态为0,元素数组为空。但是,我的示例使用.element()
。两者很容易混淆,它们仅相差 s,但行为却大不相同。
我试图将这个添加到我上面的评论中,但我太慢了:(如果你不相信,请查看我的Gist,你可以将文件下载到你的测试目录并运行它像平常一样【参考方案2】:
您似乎在使用 isVisible 时走在了正确的轨道上。从 nightwatch documentation 中,我们看到在回调中您可以检查 result.value
属性以查看该元素是否可见,即:
browser.isVisible('#advanced-search', results =>
if (results.value) /* is visible */
else /* is not visible */
);
或者,您可以使用 Saifur 建议的方法。调用 selenium api 的.elements
命令,然后检查结果数组的长度:
browser.elements('css selector', '#advanced-search', results =>
if (results.value.length > 0) /* element exists */
else /* element does not exist */
);
这实际上可以包装成custom command:
// isPresent.js
module.exports.command = function (selector, callback)
return this.elements('css selector', selector, results =>
if (results.status !== 0) // some error occurred, handle accordingly
callback(results.value.length > 0);
);
;
那么在普通代码中你可以这样称呼它:
browser.isPresent('#advanced-search', advancedSearchPresent =>
// make decisions here
如果您要在回调中进行额外的 api 调用,最好将其全部包装在 .perform
调用中:
browser.perform((_, done) =>
browser.isPresent('#advanced-search', advancedSearchPresent =>
// ...do more stuff...
done();
);
);
至于为什么需要.perform
,this 可能会有所帮助。
【讨论】:
【参考方案3】:语法可能有点不对劲。对 NightWatchJS 不是很熟悉。但是,概念保持不变。
//I would not wait for a element that should not exist
//rather I would find the list of the element and see if the count is greater than 0
//and if so, we know the element exists
browser.findElements(webdriver.By.css('#advanced-search')).then(function(elements)
if(elements.length> 0)
console.log(elements.length);
);
查看更多示例here
【讨论】:
【参考方案4】:我的团队使用一个函数对几种不同的登录表单进行身份验证,我们使用一个名为 ifElementExists
的自定义命令来完成分支逻辑,以了解我们使用的是哪种表单。我们还在其他一些没有更好方法来确定当前状态的页面上使用它。
import CustomCommandShorthand from './customCommands';
import isFunction from 'lodash';
exports.command = function ifElementExists(this: CustomCommandShorthand, selector: string, ifTrue: Function, ifFalse?: Function)
this.perform(() =>
if (!isFunction(ifTrue))
throw new Error(`The second argument must be callable. You passed a $typeof ifTrue instead of a function.`);
this.element('css selector', selector, function ifElementExistsCallback( status )
if (status !== -1)
return ifTrue();
if (isFunction(ifFalse))
ifFalse();
);
)
【讨论】:
以上是关于Nightwatchjs:如何在不创建错误/失败/异常的情况下检查元素是不是存在的主要内容,如果未能解决你的问题,请参考以下文章
NightwatchJS 和 WebdriverIO 有啥区别?
使用 XCUI 在 iOS 模拟器上使用 NightwatchJS 进行自动化测试