tutorial example español javascript selenium selenium-webdriver iteration protractor

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; }); });

FYI, propuso hacer takewhile() incorporado .