Reputation: 385
I have a doubt, it is written that : Finding web elements is asynchronous, whether it’s a single element or a collection, so the result is a promise. So if this is the case , the how below code snippet is working:
describe('the contact list', () => {
it('with filter: should find existing ' +
'contact "Craig Service"', () => {
let tbody = element(by.tagName('tbody'));
let trs = tbody.all(by.tagName('tr'));
let craigService = trs.filter(elem => {
return elem.all(by.tagName('td')).get(1).getText()
.then(text => {
return text === 'Craig Service';
});
});
Isn't trs needs to be resolved using then().. ,before we are moving to the next line where we are using filter function( craigService)? If that is being handled by Protractor promise -manager, can we use the same strategy for getting the text of an element using gettext()..and later using it without using then()..?
Upvotes: 2
Views: 72
Reputation: 8948
If that is being handled by Protractor promise -manager
Protractor promise manager (AKA SELENIUM_PROMISE_MANAGER) is removed starting from protractor 6. So forget about it
Finding web elements is asynchronous
In my own words, finding web elements with a purpose of manipulating with it (click()
, getText()
etc) is asynchronous and thus returns a Promise, which need to be resolved. However what you have on this line
let trs = tbody.all(by.tagName('tr'));
is just an elementArrayFinder declaration. It doesn't return promise, and thus it has a synchronous nature. So you can declare this element, long time before you even open a browser
If you intend to work with protractor a lot, bookmark this protractor API page. On this page, they say what every command returns. If that does not have promise.Promise
or something like that, it doesn't need to be resolved (exception is browser.get
which I happen to know is a promise too, but they don't mention that)
Answering your quesion
Isn't
trs
needs to be resolved
As per protractor page element()
doesn't return a Promise, as well as element.all()
so NO, they don't need to be resolved
Now when you know how to find out if you work with promises or not, lets talk how to resolve Promises
.then()
syntax (not really good, but old indeed)element(by.css('.class')).getText().then(function(text){
console.log(text)
})
Now when you know this method, erase that from your memory. This is extra information which will make your code not readable and extremely hard to debug. Just look at this Promise Hell and you'll understand what I'm talking about
async/await
This is as good as copy/paste on your computer. God bless creators of both, I can't imagine my life without them. So the same code from #1 now looks like thislet text = await element(by.css('.class')).getText();
console.log(text)
Doesn't it make a lot more sense when you look at the snippet? For another example see this thread. Basically await
says to javascript 'stop, resolve promise, return it's value'
To summarize, if you resolve your snippet's promises with async/await
you'll get
describe('the contact list', () => {
it('with filter: should find existing contact "Craig Service"', async () => { // pay attention to this async
let tbody = element(by.tagName('tbody'));
let trs = tbody.all(by.tagName('tr'));
let craigService = await trs.filter(async elem => { // async again
let text = await elem.all(by.tagName('td')).get(1).getText()
return text === 'Craig Service'
});
Upvotes: 1