Q: How to structure Protractor promises 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.)

A: 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:


*

*Flattening Promise Chains    

*How do I reference a promise returned from a chained function?

*How do I access previous promise results in a .then() chain?
