最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - get element attribute value in Protractor - Stack Overflow

programmeradmin1浏览0评论

I'm writing a Protractor test that has to wait for an element attribute to have a non-empty value and then I want to return that value to the caller function. This has proven to be more difficult to write than I expected!

I am able to correctly schedule a browser.wait() command to wait for the element attribute to have a non-empty value and I have verified that this value is in fact what I am expecting to get inside the callback function, but for some reason, I am not able to return that value outside of the callback function and onto the rest of the test code.

Here is how 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 tell that the order of execution is not as I expect it to be, because when I uncomment the console.log() call inside the callback function, I see the expected value printed out. However, the same call in the test() function prints 'undefined'.

What is going on here? What am I missing? How can I get the attribute value out of the callback function properly?

I appreciate your help.

I'm writing a Protractor test that has to wait for an element attribute to have a non-empty value and then I want to return that value to the caller function. This has proven to be more difficult to write than I expected!

I am able to correctly schedule a browser.wait() command to wait for the element attribute to have a non-empty value and I have verified that this value is in fact what I am expecting to get inside the callback function, but for some reason, I am not able to return that value outside of the callback function and onto the rest of the test code.

Here is how 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 tell that the order of execution is not as I expect it to be, because when I uncomment the console.log() call inside the callback function, I see the expected value printed out. However, the same call in the test() function prints 'undefined'.

What is going on here? What am I missing? How can I get the attribute value out of the callback function properly?

I appreciate your help.

Share Improve this question edited Jan 23, 2016 at 16:31 exbuddha asked Jan 23, 2016 at 8:15 exbuddhaexbuddha 6331 gold badge9 silver badges19 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 14

I would not combine the wait and the getting attribute parts - logically these are two separate things, keep 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 may simplify the wait condition this way:

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 may have solved your current problem with the 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;
}

After doing some more reading about how protractor works with promises and schedules/registers them with the control flow, I found an easier work-around close to the first solution @alecxe provided. Here it goes:

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 a promise itself, it can be chained with another then() inside the caller and this way the right order of execution is guaranteed.

发布评论

评论列表(0)

  1. 暂无评论