Question about working with promises in protractor

Quick disclaimer: I know Protractor is being retired at the end of next year for new versions of Angular.

Ok, I have a test that compares the value on a summary page to the sum of values on a detail page.

Summary of my spec file:

let expectedValue = summaryPage.getExpectedTotal();
let actualValue = detailPage.getActualTotal();
expect(expectedValue).toEqual(actualValue);

The difficulty lies in my getActualTotal method from my page object file. To summarize with comments in-line to clarify:

getActualTotal() {
  
    let runningTotal = 0;

    // getNumberOfSubTotalsToSum gets elements and then performs .count() on the array to return a number

    this.getNumberOfSubTotalsToSum().then(function (numberOfSubTotals) {
      
      for (let i = 0; i < (numberOfSubTotals - 1); i++) {
        element.all(by.xpath('an//xpath//goes//here')).get(i).getText().then(function (text) {
          runningTotal += Number(text);
          console.log('inner total ' + runningTotal); // prints correct total
        });
      }
      console.log('outer total ' + runningTotal); // prints undefined
      
    });
    return runningTotal; // returns 0
  }

So essentially it seems like the total I need to compare in my test is ‘trapped’ inside my for loop and I think it has to do with the timing of my promises resolving but I’m not sure what I need to do to fix it.

3 Likes

May I ask why you do not want to use async/await?

I had the same issues with protractor so i switched to awaits.

3 Likes

I don’t really have a great answer, this is just what I tried first. What would it look like to use async/awaits in this context?

I think it should be somenthing like this but i am not really sure.

Here is an article with comparison betwenn async, promises and callbacks

https://jasmine.github.io/tutorials/async

async getActualTotal() {

let runningTotal = 0;

// getNumberOfSubTotalsToSum gets elements and then performs .count() on the array to return a number

await this.getNumberOfSubTotalsToSum() {
  
  for (let i = 0; i < (numberOfSubTotals - 1); i++) {
    await element.all(by.xpath('an//xpath//goes//here')).get(i).getText() {
      runningTotal += Number(text);
    await   console.log('inner total ' + runningTotal); // prints correct total
    });
  }
  await console.log('outer total ' + runningTotal); // prints undefined
  
});
return await runningTotal; // returns 0

}