Correct way to get a count of matching elements in Nightwatch?

Tev picture Tev · Sep 23, 2015 · Viewed 20.3k times · Source

I'm trying to test if a todo app has the right number of elements.

The docs seem to deal almost exclusively with single elements, so I had to use the Selenium Protocol functions. Would this be the right way to test the count of matching selectors (in this case, checking for 2 li elements)?

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

This works in my test, but I wasn't sure if there were gotchas around using a callback for this. Also not sure why Nightwatch doesn't have any helper functions dealing with more than one element.

Answer

Chris K picture Chris K · Aug 15, 2017

I found the following very elegant solution within a VueJS template. It shows how to add a custom assertion into Nightwatch that counts the number of elements returned by a selector. See http://nightwatchjs.org/guide#writing-custom-assertions for details of how to write custom assertions within Nightwatch.

Once installed, usage is as simple as:

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

The plugin:

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

This code was added to vuejs-templates by yyx990803 in 2016. So full credit goes to yyx990803.