【问题标题】:Correct way to get a count of matching elements in Nightwatch?在 Nightwatch 中获取匹配元素计数的正确方法?
【发布时间】:2015-12-21 08:06:40
【问题描述】:

我正在尝试测试待办事项应用的元素数量是否正确。

文档似乎几乎只处理单个元素,所以我不得不使用 Selenium 协议函数。这是否是测试匹配选择器计数的正确方法(在这种情况下,检查 2 个 li 元素)?

client.elements('css selector','#todo-list li', function (result) {
    client.assert.equal(result.value.length, 2);
});

这在我的测试中有效,但我不确定使用回调是否存在问题。也不知道为什么 Nightwatch 没有任何帮助函数处理多个元素。

【问题讨论】:

  • 在我看来这是将 Selenium 协议与 Nightwatch 一起使用的正确方法(请参阅 nightwatchjs.org/api#elements)。你为什么怀疑回调?我同意它不漂亮,但它应该像它应该的那样工作
  • 我在 console.log(result) 中看到以下内容:{ state: 'success', sessionId: '4568bfcf-fa1a-4d4c-bd19-082c3983cc42', hCode: 1527071402, value: [] , class: 'org.openqa.selenium.remote.Response', status: 0 } --- 元素没有传入函数。有什么想法吗?
  • 我使用的是“id”而不是“css 选择器”。使用“css 选择器”确实会产生长度。

标签: nightwatch.js


【解决方案1】:

我在 VueJS 模板中找到了以下非常优雅的解决方案。它展示了如何将 custom assertion 添加到 Nightwatch 中,以计算选择器返回的元素数量。有关如何在 Nightwatch 中编写自定义断言的详细信息,请参阅 http://nightwatchjs.org/guide#writing-custom-assertions。

安装后,使用方法如下:

browser.assert.elementCount('#todo-list li', 2)

插件:

// A custom Nightwatch assertion.
// the name of the method is the filename.
// can be used in tests like this:
//
//   browser.assert.elementCount(selector, count)
//
// for how to write custom assertions see
// http://nightwatchjs.org/guide#writing-custom-assertions
exports.assertion = function (selector, count) {
  this.message = 'Testing if element <' + selector + '> has count: ' + count;
  this.expected = count;
  this.pass = function (val) {
    return val === this.expected;
  }
  this.value = function (res) {
    return res.value;
  }
  this.command = function (cb) {
    var self = this;
    return this.api.execute(function (selector) {
      return document.querySelectorAll(selector).length;
    }, [selector], function (res) {
      cb.call(self, res);
    });
  }
}

此代码于 2016 年添加到 vuejs-templates by yyx990803。因此,完整的功劳归于 yyx990803。

【讨论】:

  • 你有没有机会告诉我们如何实现这一点?我的意思是设置 nightwatch 来接受这个自定义断言
  • 添加这个:创建一个名为 plugins 或其他的目录。在您的 nightwatch.json 文件中,将该目录路径添加到“custom_assertions_path”。将代码添加到一个名为 elementCount.js 的文件中,并将该文件添加到您的插件目录中,这应该可以工作。
  • 我添加了一个 TypeScript 版本,无需在浏览器中执行代码即可完成此操作。
【解决方案2】:

只是为了让你放心,我在尝试抓取所有匹配元素时会做类似的事情,例如:

    browser.elements("xpath","//ul[@name='timesList']/h6", function(result){
        els = result.value;
        var i = 0;
        els.forEach(function(el, j, elz){
            browser.elementIdText(el.ELEMENT, function(text) {
                dates[i] = text.value;
                i++;
            });
        });
    });

【讨论】:

  • 需要注意的是 CSS 选择器是 browser.elements('css selector', ...) 但 XPath 选择器是 browser.elements('xpath', ...)。我一直在尝试使用“xpath 选择器”,但不...这不是名称选择器。
【解决方案3】:

或者,如果您想确定存在n 的元素数量,可以使用:nth-of-type/:nth-child 选择器和nightwatch 的expect 的组合。

例如,如果您想测试#foo 是否有九个直系子代:

function(browser) {
  browser
    .url('http://example.com')
    .expect.element('#foo > *:nth-child(9)').to.be.present;
  browser.end();
}

或者如果#bar 有三个直接的article 孩子:

function(browser) {
  browser
    .url('http://example.com')
    .expect.element('#bar > article:nth-of-type(3)').to.be.present;
  browser.end();
}

【讨论】:

  • 应该注意的是,这个解决方案似乎只有在目标元素组织得“干净”的情况下才有效。例如,我有一个 div.items div.item 的购物车,购物车中有三件商品 (div.item)。不幸的是,当购物车中没有与div.item 元素同级的内容时,还有一个隐藏的div.empty。所以在这种情况下,当尝试计算 div.item 元素时,它实际上是 :nth-of-type(2-4),因为空 div 元素是 item 元素的父元素的第一个子元素。
【解决方案4】:

我通过使用内置方法this.api.elements 调整了Chris K's answer 以支持XPath 表达式:

exports.assertion = function elementCount(selector, count) {
  this.message = 'Testing if element <' + selector + '> has count: ' + count

  this.expected = count

  this.pass = function pass(val) {
    return val === this.expected
  }

  this.value = function value(res) {
    return res.value.length
  }

  this.command = function command(callback) {
    return this.api.elements(this.client.locateStrategy, selector, callback)
  }
}

有关使用说明和积分,请参阅his answer

【讨论】:

    【解决方案5】:

    你可以使用expect.elements(&lt;selector&gt;).count():

      browser.expect.elements('div').count.to.equal(10);
      browser.expect.elements('p').count.to.not.equal(1);
    

    【讨论】:

      【解决方案6】:

      如果你喜欢一点 TypeScript,这里有一个断言可以确认元素计数:

      import { NightwatchCallbackResult, NightwatchAssertion, NightwatchAPI } from "nightwatch";
      
      module.exports.assertion = function (selector: string, count: number, description?: string) {
      
          this.message = description || `Testing if element <${selector}> has count: ${count}`;
          this.expected = count;
      
          this.pass = (value: number) => value === this.expected;
      
          this.value = (result: number) => result;
      
          this.command = (callback: (result: number) => void): NightwatchAPI => {
      
              const self: NightwatchAssertion = this;
      
              return self.api.elements(this.client.locateStrategy, selector, (result: NightwatchCallbackResult) => {
                  callback(result.value.length);
              });
          }
      
      }
      

      这样使用:

      browser.assert.elementCount('body', 1, 'There is only one body element');
      

      【讨论】:

        猜你喜欢
        • 2016-05-27
        • 1970-01-01
        • 1970-01-01
        • 2015-08-08
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多