Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 893
Tev Avatar asked Sep 23 '15 20:09

Tev


People also ask

What is the command to run the script Nightwatch?

You can add Nightwatch to your project simply by running npm install nightwatch --save-dev . This places the Nightwatch executable in your ./node_modules/.

How do you scroll on Nightwatch?

url("http://example.com") . waitForElementPresent('body', 2000, "Be sure that the page is loaded") . execute('scrollTo(x, y)') .


2 Answers

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.

like image 69
Chris K Avatar answered Nov 03 '22 00:11

Chris K


Just to reassure you I do a similar thing when trying to grab all matching elements, ex:

    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++;             });         });     }); 
like image 21
Madison Haynie Avatar answered Nov 02 '22 22:11

Madison Haynie