Get element attribute value in Protractor

I am writing a Protractor test that needs to wait for an element attribute to have a non-empty value, and then I want to return that value to the caller function. It turned out to be harder to write than I expected!

I can correctly schedule the browser.wait() command to wait for the element attribute to have a non-empty value, and I confirmed that this value is actually what I expect to get inside the callback function, but for some reason I cannot return this value outside the callback function and to the rest of the test code.

This is what my code looks like:

 function test() { var item = getItem(); console.log(item); } function getItem() { var item; browser.wait(function() { return element(by.id('element-id')).getAttribute('attribute-name').then(function(value) { item = value; // console.log(item); return value !== ''; }); }); return item; } 

I can say that the execution order is not what I expect, because when I uncomment the console.log() call inside the callback function, I see that the expected value is being printed. However, the same call to test() prints "undefined".

What's going on here? What am I missing? How can I get the attribute value from the callback function correctly?

I appreciate your help.

+6
source share
2 answers

I would not combine the expectations and parts of the receiving attributes - logically these are two separate things, keeping them separate:

 browser.wait(function() { return element(by.id('element-id')).getAttribute("attribute").then(function(value) { item = value; // console.log(item); return value !== ''; }); }); element(by.id('element-id')).getAttribute("attribute").then(function (value) { console.log(value); }); 

Note that you can simplify the wait condition as follows:

 var EC = protractor.ExpectedConditions; var elm = $('#element-id[attribute="expected value"]'); browser.wait(EC.presenceOf(elm), 5000); elm.getAttribute("attribute").then(function (value) { console.log(value); }); 

Just FYI, you might have solved your current problem with deferred :

 function test() { getItem().then(function (value) { console.log(value); }); } function getItem() { var item = protractor.promise.defer(); browser.wait(function() { return element(by.id('element-id')).getAttribute('attribute').then(function(value) { var result = value !== ''; if (result) { item.fulfill(value); } return result; }); }); return item.promise; } 
+10
source

After a more detailed description of how the protractor works with promises and plans / registers them using the control flow, I found an easier solution for working next to the first @alecxe solution. Here it is:

 function test() { var item = getItem().then(function(item) { console.log(item); }); } function getItem() { return browser.wait(function() { return element(by.id('element-id')).getAttribute('attribute-name').then(function(value) { return value; }); }); } 

Since browser.wait() returns the promise itself, it can be associated with another then() inside the caller, and thus the correct execution order is guaranteed.

+1
source

All Articles