10

I am new to using nightwatch.js. I want to get a list of elements and verify text value of each and every element with a given string. I have tried :

function iter(elems) {
      elems.value.forEach(function(element) {
        client.elementIdValue(element.ELEMENT)
      })
    };
    client.elements('css selector', 'button.my-button.to-iterate', iter);

For another stackoverflow question But what I am using right now is

waitForElementPresent('elementcss', 5000).assert.containsText('elementcss','Hello')

and it is returning me the output

Warn: WaitForElement found 5 elements for selector "elementcss". Only the first one will be checked.

So I want that it should verify text value of each and every element of list.

vibhor
  • 181
  • 1
  • 2
  • 7

5 Answers5

8

All the things can not be done by nightwatch js simple commands , so they have provided the custom command means selenium protocol. Here you can have all the selenium protocol. I have used following code to assert text value of each and every element with a given string "text". Hope it will help you

    module.exports = {
  '1. test if multiple elements have the same text' : function (browser) {
    function iter(elems) {
       elems.value.forEach(function(element) {
        browser.elementIdText(element.ELEMENT, function(result){
          browser.assert.equal(result.value,'text')
        })
       })
     };

    browser
      .url('file:///home/user/test.html')
      .elements('tag name', 'a', iter);

    }

  };

My HTML snippet

<div id="test">
<a href="google.com" class='red'> text </a>
<a href="#" class='red'> text </a>
<a href="#" class='red'> text 1</a>
</div>
Juhi Saxena
  • 1,077
  • 11
  • 16
2

I was able to do it as :

.elements('css selector', 'cssValue', function (elements) {
        for(var i=0;i<elements.value.length;i++){
        var elementCss = 'div.search-results-item:nth-child(' + (i+1) + ') span';
            client.assert.containsText(elementCss,'textValue');
        }
        })
Tunaki
  • 116,530
  • 39
  • 281
  • 370
vibhor
  • 181
  • 1
  • 2
  • 7
1

Put your function iter in a for loop and before that use

client.elements('css selector', '#CollectionClass', function (result) {
  if(result.value.length > 1) {   
     var count;
     for(count=1; count<result.value.length; count++) {
       result.value.forEach(function(element) {
       client.elementIdValue(element.ELEMENT);
       client.elementIdText(selectedHighlight.ELEMENT, function(resuddlt) {
         this.assert.equal(typeof resuddlt, "object");
         this.assert.equal(resuddlt.status, 0);
         this.assert.equal(resuddlt.value, "your value");
      });
     }     
   }
  }
};
Ashish-BeJovial
  • 1,529
  • 1
  • 29
  • 53
0

You have stated what you have tried (which is good) but you haven't presented us with sanitized HTML that demonstrates the problem (which reduces precision in possible answers).

There are many ways in HTML to contain information, and the built-in Nightwatch containsText will serialize any text it finds within a structure that contains substructures.

So for example, if you have as Juhi suggested,

<div id="test">
<a href="google.com" class='red'> text </a>
<a href="#" class='red'> text </a>
<a href="#" class='red'> text 1</a>
</div>

Then the assertions

.verify.containsText('#test', ' text ') // first one
.verify.containsText('#test', ' text ') // second one
.verify.containsText('#test', ' text 1') // third one

will pass, because they each verify the specific information without the need for writing a loop. Nightwatch will look at the test element and serialize the elements into the string text text text 1

Now if you need a loop for other reasons this is all academic, but your original question seemed to be targeted at how to get the text information out, not necessarily how to execute one possible solution to the problem (which is writing a loop).

0

I created custom assertions - custom-assertions/hasItems.js with content:

exports.assertion = function hasItems(selector, items) {
  this.message = `Testing if element <${selector}> has items: ${items.join(", ")}`;
  this.expected = items;
  this.pass = selectedItems => {
    if (selectedItems.length !== items.length) {
      return false;
    }
    for (let i = 0; i < selectedItems.length; i++) {
      if (selectedItems[i].trim() !== items[i].trim()) {
        return false;
      }
    }
    return true;
  };
  this.value = res => res.value;
  function evaluator(_selector) {
    return [...document.querySelectorAll(_selector)].map(
      item => item.innerText
    );
  }
  this.command = cb => this.api.execute(evaluator, [selector], cb);
};

lusarz
  • 155
  • 2
  • 9