3

In this example I'm testing whether an element is located at the bottom of the page. I'm using the promises in Protractor/Webdriver, but I think I'm using it wrong because I don't think it's supposed to look this messy.

describe('Element', function(){
    it('should be placed at bottom', function(){
        element(by.id('page').getSize().then(function(dimP){
            element(by.id('element').getLocation().then(function(locE){
                element(by.id('element').getSize().then(function(dimE){
                    expect(locE.y + dimE.height).toEqual(dimP.height);
                })
            });
        });
    })
});

How can I do this in a cleaner way? I'm using Protractor version 2.1.0.

I have tried to do like this:

expect(element(by.id('page').getSize().height).toEqual(1000);

But it says Expected undefined to equal 1000. So it seems like I can't use return values as explained here: https://github.com/angular/protractor/blob/master/docs/control-flow.md

(I am using a page object in my actual test, so the variables are not as ugly as in the example.)

KMK
  • 1,439
  • 5
  • 21
  • 39

1 Answers1

3

Since getSize() and getLocation() both return promises and you need actual values, you have to resolve all of the promises, either explicitly with then(), or let expect() implicitly do this for you.

I'm actually understanding your question as "How to flatten a promise chain in Protractor?". This is there promise.all() would help to resolve multiple promises at once which would save you from writing multiple nested then() callbacks:

var elm = element(by.id('element')),
    page = element(by.id('page'));

var promises = [elm.getSize(), elm.getLocation(), page.getSize()];

protractor.promise.all(promises).then(function (values) {
    expect(values[0].height + values[1].y).toEqual(values[2].height);
});

See also:

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • How can I make expect() resolve the promise? Am I doing something wrong in the second code block, since it resolves to _undefined_? The promise.all() seem like a good solution. – KMK Aug 04 '15 at 12:23
  • @KMK implicitly resolving promises with expect is something I've mentioned, but is not needed here. And, unfortunately, you cannot get a property value from a not yet resolved promise like `element(by.id('page')).getSize().height`. Basically, from what I understand, your question is about flattening a promise chain. I'll update the answer with some more information. Stay tuned. Thanks! – alecxe Aug 04 '15 at 13:44