javascript - example - Tomar elementos mientras una condición se evalúa como verdadera(extendiendo ElementArrayFinder)
protractor vs selenium (2)
Tal vez me estoy perdiendo algo, pero ¿no podría simplemente pasar por elementos
ul li a
mientras le dieron algo de getText () y almacenarlos en una matriz, o hacer algo con ellos directamente en ese ciclo?
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();
}
});
}());
Tenemos un menú representado como una lista
ul->li
(simplificada):
<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>
Donde en algún lugar en la posición N, hay un divisor, que puede identificarse
evaluando
filterItem.isDivider
o comprobando el texto del enlace a (en el caso de un divisor, está vacío).
Ahora, el objetivo es obtener todos los elementos del menú que se encuentran antes del divisor. ¿Cómo abordarías el problema?
Mi enfoque actual es bastante genérico: extender
ElementArrayFinder
y agregar la función
takewhile()
(inspirada en los
itertools.takewhile()
Python).
Así es como lo implementé (basado en
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_);
};
Y así es como lo estoy usando:
this.getInclusionFilters = function () {
return element.all(by.css("ul.dropdown-menu li")).takewhile(function (inclusionFilter) {
return inclusionFilter.evaluate("!filterItem.isDivider");
});
};
Pero, la prueba está suspendida hasta que se llegue a
takewhile()
en la llamada
takewhile()
.
Si pongo
console.log
s en el bucle y después, puedo ver que empuja correctamente los elementos antes del divisor y se detiene cuando lo alcanza.
Podría estar perdiendo algo aquí.
Usando transportador 2.2.0.
Además, avíseme si estoy complicando demasiado el problema.
takewhile()
realmente funcionó para mí una vez que
takewhile()
el
protractor.promise = require("q");
from
onPrepare()
: estaba allí para reemplazar el
protractor.promise
con
q
sobre la marcha para poder usar la función de azúcar sintáctica como
spread()
.
Aparentemente,
no es seguro usar
q
en lugar de
protractor.promise
.
Todo lo que tengo que hacer ahora es agregar esto a
onPrepare()
:
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_);
};
El uso es muy similar al
filter()
:
element.all(by.css("ul li a")).takewhile(function (elm) {
return elm.getText().then(function (text) {
return text;
});
});