【问题标题】: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.日志(我的错误); }

标签: selenium automated-tests nightwatch.js


【解决方案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();
  });
});

至于为什么需要.performthis 可能会有所帮助。

【讨论】:

    【解决方案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();
                  }
              });
          })
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 2019-04-14
        • 1970-01-01
        • 2022-10-20
        • 2017-03-25
        • 2010-12-29
        • 2012-07-17
        相关资源
        最近更新 更多