Take elements while a condition evaluates to true (extending ElementArrayFinder)

0
0

We have a menu represented as a ul->li list (simplified):

<ul class="dropdown-menu" role="menu">
<li ng-repeat="filterItem in filterCtrl.filterPanelCfg track by filterItem.name"
ng-class="{'divider': filterItem.isDivider}" class="ng-scope">
<a href="" class="ng-binding"> Menu Item 1</a>
</li>
...
<li ng-repeat="filterItem in filterCtrl.filterPanelCfg track by filterItem.name"
ng-class="{'divider': filterItem.isDivider}" class="ng-scope">
<a href="" class="ng-binding"> Menu Item 2</a>
</li>
</ul>

Where somewhere at position N, there is a divider, which can be identified by evaluating filterItem.isDivider or by checking the text of the a link (in case of a divider, it’s empty).

Now, the goal is to get all of the menu items that are located before the divider. How would you approach the problem?


My current approach is rather generic – to extend ElementArrayFinder and add takewhile() function (inspired by Python’s itertools.takewhile()). Here is how I’ve implemented it (based on filter()):

protractor.ElementArrayFinder.prototype.takewhile = function(whileFn) {
var self = this;
var getWebElements = function() {
return self.getWebElements().then(function(parentWebElements) {
var list = [];
parentWebElements
.forEach(function(parentWebElement, index) {
var elementFinder =
protractor
.ElementFinder.fromWebElement_(self.ptor_, parentWebElement, self.locator_);
list
.push(whileFn(elementFinder, index));
});
return protractor.promise.all(list).then(function(resolvedList) {
var filteredElementList = [];
for (var index = 0; index < resolvedList.length; index++) {
if (!resolvedList[index]) {
break;
}
filteredElementList
.push(parentWebElements[index])
}
return filteredElementList;
});
});
};
return new protractor.ElementArrayFinder(this.ptor_, getWebElements, this.locator_);
};

And, here is how I’m using it:

this.getInclusionFilters = function () {
return element.all(by.css("ul.dropdown-menu li")).takewhile(function (inclusionFilter) {
return inclusionFilter.evaluate("!filterItem.isDivider");
});
};

But, the test is just hanging until jasmine.DEFAULT_TIMEOUT_INTERVAL is reached on the takewhile() call.

If I put console.logs into the loop and after, I can see that it correctly pushes the elements before the divider and stops when it reaches it. I might be missing something here.

Using protractor 2.2.0.


Also, let me know if I’m overcomplicating the problem.

  • You must to post comments
0
0

Maybe I’m missing something, but couldn’t you just go through ul li a elements while they gave you something from getText(), and store them to some array, or do something with them directly in that loop?

var i = 0;
var el = element.all(by.css('ul li a'));
var tableItems = [];
(function loop() {
el
.get(i).getText().then(function(text){
if(text){
tableItems
.push(el.get(i));
i
+=1;
loop
();
}
});
}());
  • You must to post comments
Showing 1 result
Your Answer
Post as a guest by filling out the fields below or if you already have an account.
Name*
E-mail*
Website