Reputation: 1183
I'm using the automated testing framework, Protractor.
I've come to find that Protractor frequently makes use of promises
to asynchronously resolve code evaluation.
Question: How can I manually resolve a promise to a specific value, once a condition is met?
Update: 09/08/2017
Sorry, I was just a bit unclear on promises
. I was able to get this working correctly now with:
// match variable
var match = false;
// get all elements with `div` tag
var scanElements = element.all(by.css('div')).each(function(el) {
// get text content of element
el.getText().then(function(text) {
// split words into array based on (space) delimeter
var sp = text.split(' ');
for (var i = 0; i < sp.length; i++) {
if (sp[i] == 'Stack Overflow') {
match = true;
}
}
});
});
// on complete
scanElements.then(function() {
if (match) {
console.log('Status: Found match!');
}
else {
console.log('Status: No match');
}
});
Upvotes: 1
Views: 413
Reputation: 3091
In your exact example you can use .getText()
on ElementArrayFinder -
// calling .getText() exactly on ElementArrayFinder returns promise
let hasStackOverflow = $$('div').getText().then(texts=> {
// texts would be array of strings
return texts.includes('Your Text exact match')
})
hasStackOverflow.then(has=> {
if (has) {
console.log('Status: Found match!');
}
else {
console.log('Status: No match');
}
})
Upvotes: 0
Reputation: 1079
There is no issue here according to the documentation the return type of element.all().each() is null after it iterates through everything.
A promise that will resolve when the function has been called on all the ElementFinders. The promise will resolve to null.
Edit 1: Is filter a valid option?
element.all(by.css('div'))
.filter(function(element) {
return element.getText().then(function(text) {
var sp = text.split(' ');
for ( var i =0; i< sp.length; i++) {
if(sp[0] == 'protractor') return true;
}
return false;
});
}).first();
Will first filter and then return first element that matches
Upvotes: 1
Reputation: 3915
You should use map
instead of each
. If you look at the source code, this is how each
is implemented:
each(fn: (elementFinder?: ElementFinder, index?: number) => any): wdpromise.Promise<any> {
return this.map(fn).then((): any => {
return null;
});
}
So, as you can see it internally uses map
and hides the result by returning null
. It is also pointed out in the documentation.
Also rename element
to something else just to avoid ambiguity with protractor's element
object.
Upvotes: 1