在Nightwatch中获取匹配元素计数的正确方法?

问题描述 投票:31回答:5

我正在尝试测试todo应用程序是否具有正确数量的元素。

文档似乎几乎只涉及单个元素,因此我不得不使用Selenium Protocol函数。这是测试匹配选择器计数的正确方法(在这种情况下,检查2个li元素)?

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

这适用于我的测试,但我不确定是否有使用回调的问题。也不确定为什么Nightwatch没有任何处理多个元素的辅助函数。

nightwatch.js
5个回答
13
投票

我在VueJS模板中找到了以下非常优雅的解决方案。它显示了如何在Nightwatch中添加custom assertion,它计算选择器返回的元素数量。有关如何在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


8
投票

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

    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++;
            });
        });
    });

7
投票

或者,如果你想确定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();
}

2
投票

我使用内置方法Chris K's answer修改了this.api.elements以支持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


0
投票

如果你喜欢一些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');

0
投票

你可以使用expect.elements(<selector>).count()

  browser.expect.elements('div').count.to.equal(10);
  browser.expect.elements('p').count.to.not.equal(1);
© www.soinside.com 2019 - 2024. All rights reserved.