Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if text is found in column in Protractor

Tags:

protractor

I'm trying to assert that a name is displayed in a column of a table. I've written an inResults function that will iterate through a column's text to see if a name exists. Here's what I'm trying:

Page object:

this.names = element.all(by.repeater('row in rows').column('{{row}}'));

this.inResults = function(nameString) {
    var foundit = '';
    this.names.each(function(name) {
        name.getText().then(function(it) {
            console.log(it); // each name IS printed...
            if(it == nameString) {
                console.log('it\'s TRUE!!!!'); // this gets printed...

                foundit = true;
            }
        });
    });
    return foundit; // returns '' but should be true?
};

Spec expect:

expect(friendPage.inResults('Jo')).toBeTruthy();

Both console statements print as expected... but my expect fails as foundit's value is still ''. I've tried this a number of ways and none are working. What am I missing?

like image 832
Brine Avatar asked Sep 13 '14 18:09

Brine


3 Answers

I've devised what I think is a better/cleaner way to solve this. It's less complex and doesn't require locator/css code in the method.

friend.page.js

// locator
this.friendName = function(text) { return element.all(by.cssContainingText('td.ng-binding', text)) };

// method
this.inResults = function(name) {
    return this.friendName(name).then(function(found) {
        return found.length > 0;
    });
};

friend.spec.js

expect(friendPage.inResults('Jo')).toBeTruthy();

I've added this to my protractor_example project on GitHub...

like image 64
Brine Avatar answered Nov 09 '22 21:11

Brine


I would recommend you to use filter: http://angular.github.io/protractor/#/api?view=ElementArrayFinder.prototype.filter

this.inResults = function(nameString) {    
  return this.names.filter(function(name) {
    return name.getText().then(function(text) {          
      return text === nameString;
    });
  }).then(function(filteredElements) {
    // Only the elements that passed the filter will be here. This is an array.
    return filteredElements.length > 0;
  });
});

// This will be a promise that resolves to a boolean.
expect(friendPage.inResults('Jo')).toBe(true);
like image 36
Andres D Avatar answered Nov 09 '22 22:11

Andres D


Use map to do this.This will return a deferred that will resolve with the values in an array, so if you have this:

this.mappedVals =element.all(by.repeater('row in rows').column('{{row}}')).map(function (elm) {
    return elm.getText();
});

It will resolve like this:

this.inResults = function(nameString) {
  var foundit = '';
  mappedVals.then(function (textArr) {
    // textArr will be an actual JS array of the text from each node in your repeater
    for(var i=0; i<textArr.length; i++){
       if(it == textArr[i]) {
            console.log('it\'s TRUE!!!!'); // this gets printed...
            foundit = true;
        }
    }
    return foundit;
  });
}

And Use that in Spec file like,

friendPage.inResults('Jo').then(function(findIt){
  expect(findIt).toBeTruthy();
});
like image 2
Hardik Sheth Avatar answered Nov 09 '22 21:11

Hardik Sheth