-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Making ElementArrayFinder from an array of ElementFinders #2538
Comments
Not relevant but I'm curious: have you actually tried the SO answer? I think it might be slightly wrong but I'm not sure without running it. |
I have similar implementation for my project. Basically it's convenient to have 2 options |
I just wasn't sure about how they were handling the promises. |
@alecxe sure: element.all.of = function(finders) {
var combinedLocator = {
toString: function() {
return _.invoke(this.locators, 'toString').join(', ');
}
};
var newElements = q.when(finders);
var arrayFinder = new ElementArrayFinder(null, function() { return newElements; }, combinedLocator);
// TODO: consider pull-request into protractor.js
arrayFinder.asElementFinders_ = arrayFinder.getWebElements; // cause we have ElementFinders in newElements
newElements.then(function(finders) {
combinedLocator.locators = _.invoke(finders, 'locator');
});
return arrayFinder;
};
// usage Array
element.all.of([ element(by.id), element(by.name('button1'), element(by.name('button2') ]);
// usage promise
var buttons = element.all(by.repeater('item in items')).reduce(function(allButtons, item) { //
return allButtons.concat(findButtonsIn(item));
}, []);
element.all.of(buttons); |
I'm still not convinced this function is needed. Looking at your stackoverflow issue, here's your original code: 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();
}
});
}());
// Now you want to convert tableItems to an ElementArrayFinder like:
// var myEls = ElementArrayFinder.fromArray(tableItems); You can just rewrite it with filter: var els = element.all(by.css('ul li a'));
var filteredEls = els.filter(function(el) {
return el.getText().then(function(text) {
return !!text;
})
});
// filteredEls is exactly what you want The rewrite makes the code shorter and easier to understand. Can you provide me with an example where the |
The good example for this is when you want to aggregate elements that were found by different locators but logically relate to one thing (or when you have a promise which returns an array of finders, as in case with ElementFinder#reduce) For example, |
Ok fair enough. It looks like you already have the code ready, can you send it as a PR and I'll take a look? |
Closing this as stale, with no example or PR. |
@juliemr @hankduan I'm wondering if I have to do the same thing as the SO solution, too. Use case: I have to get text from a tooltip. Requirements:
Because of Req 2, I want a function that will always return an ElementArrayFinder. That way, I can have another function that calls getText() on the result of my function, a different function that calls click() on the result, etc. Because of Req 3, and because I'm doing this in a page object method, I have to chain together a click with a call to element.all(). I'm doing this in a page object method in order to reuse code, but perhaps I'm making my page objects too complex? If the click() call was made in the spec itself, I'd get the protractor synchronous magic to help me out. Here's a simple test case, which tries to get elements in the "color" option selector in the protractor test page. To relate this test case to my use case, imagine that the color options are the left-hand labels in the tooltip, and getSomethingToClick() was clicking on whatever makes the tooltip pop up.
|
I ended up writing a Protractor util:
And modified my getColorOptionsAtEndOfChain() method:
|
This is basically a follow-up to the resolved SO topic: http://stackoverflow.com/questions/32599679/making-elementarrayfinder-from-an-array-of-elementfinders.
Would it make sense to have
fromArray()
method available onElementArrayFinder
built-in?Thanks.
Feel free to close this one if you think this is not something we can benefit from.
The text was updated successfully, but these errors were encountered: