Friday, October 28, 2016

Using Protractor in a loop by means of Closure function or .filter()

All functions of Protrator return only promises that are hard to use in a loop. For example,
var els = element.all(by.css('selector'));
for (var i = 0; i < 3; ++i) {
  els.get(i).getText().then(function(text) {
    if (text === 'should click') {
      els.get(i).click(); //Index out of bound. Trying to access element at index:3, but there are only 3 elements"
    }
  })
}
The index i takes the values of 0, 1 and 2 and no code inside the .then() block is executed. It will be executed when i = 3 causing the error of Index out of bound!
There are two solutions to such a problem:
1. Using Closure function for the promise in a loop
var els = element.all(by.css('selector'));
function closureFunc(i){
  return function(text){
    if (text === 'should click') {
       els.get(i).click(); // i should take 0, 1 and 2
    }
  };
} 

for (var i = 0; i < 3; ++i) {
  els.get(i).getText().then(closureFunc(i));
}
2. Using the method .filter() of Protrator to avoind using .then() in a loop
var els = element.all(by.css('selector'));
els.filter(function(elem) {
  return elem.getText().then(function(text) {
    return text === 'should click';
  });
}).click(); 
// note here we first used a 'filter' to select the appropriate elements, 
// and used the fact that actions like `click` can act on an array to click all matching elements.

No comments:

Post a Comment