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 有啥区别?

如何在不发送请求的情况下拦截 Moya 请求并返回失败响应

将鼠标悬停在 nightwatchjs 中的链接上

使用 XCUI 在 iOS 模拟器上使用 NightwatchJS 进行自动化测试

nightwatchjs 基于nodejs&& webdriver 协议的自动化测试&&持续集成框架

Nightwatch:等待没有通过/失败结果的元素