Search code examples
arraystypescriptpromiseprotractorresolve

Why is my method not waiting for the promise to resolve before returning?


I am attempting to build an array populated with Merchant names, each having an element ID. I check to see if the row has a value first since I don't know how many merchants will be in the list except that there will be fewer than 20. I want to return the array so I can sort it and perform other manipulations for validations. The promise is not waiting to resolve before returning.

I can see the array building but I want to output the final list Banamex Merchant,Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant

As you can see below, the various ways I'm trying to output the final list are returning before the list is even built even though I've built a promise and am calling .then() to return the response in my it() statement.

merchants.po.ts

export class MerchantsPage {
        buildMerchantListArray(): Promise < string[] > {
            return new Promise < string[] > (resolve => {
                const list: string[] = [];

                for (let i = 20; i >= 0; i--) {
                    this.getMerchantName(i)
                        .isPresent()
                        .then((present) => {
                            if (present) {
                                this.getMerchantName(i)
                                    .getText()
                                    .then((text: string) => {
                                        list.unshift(text);
                                        console.log('building list: ' + list)
                                    })
                            }
                        });
                }

                return resolve(list);

            });
        }

        doBuild() {
            this.buildMerchantListArray()
                .then((list: string[]) => {
                    return console.log('doBuild: ' + list);
                });
        }

        /**
         * Get table element for Merchant's Name of row i
         * @param i
         * @returns {ElementFinder}
         */
        getMerchantName(i: number): ElementFinder {
            return element(by.id('Merchant-' + i + '-Name'));
        }
    }

merchants.e2e-spec.ts

import {FooterParams} from '../../../../components/footer/footer.params';
import {Footer} from '../../../../components/footer/footer.po';
import {Logo} from '../../../utility/logo/logo.po';
import {LoginParams} from '../../../authentication/login/login.params';
import {LoginPage} from '../../../authentication/login/login.po';
import {AppPage} from '../../../../app.po';
import {Header} from '../../../dashboard/header/header.po';
import {ElementFinder} from 'protractor';
import {MerchantsPage} from './merchants.po';
import {MerchantsParams} from './merchants.params';

describe('Merchants Pages of Dashboard App', () => {
    let app: AppPage;
    let login: LoginPage;
    let navigation: Header;
    let page: MerchantsPage;

    beforeAll(() => {
        navigation = new Header();
        app = new AppPage();
        login = new LoginPage();
        page = new MerchantsPage();
        app.navigateTo('dashboard').then(() => {
            login.checkAuthentication(LoginParams.user, LoginParams.user_pwd);
        });
    });

    beforeEach(() => {
        Logo.getLogo().click().then(() => {
            navigation.clickAdminDropdown().then(() => {
                navigation.clickMerchants();
                expect(page.getMerchantsHeader().getText()).toContain(MerchantsParams.merchantsHeaderText);
                Footer.getFooter().then((footer: ElementFinder) => {
                    (expect(footer.getText()).toContain(FooterParams.footer));
                });
            });
        });
    });

    it('should verify the Merchants list view is alphabetical by Name', () => {
        Promise.resolve(page.buildMerchantListArray()).then((arr) => {
            console.log('my list: ' + arr);
        });

        page.doBuild();

        page.buildMerchantListArray().then((response) => {
            console.log('response: ' + response);
        });

    });

});

Console Output

Jasmine started
my list:
doBuild:
response:
building list: TestMerchant
building list: Paytrace Merchant,TestMerchant
building list: Michelle's Business,Paytrace Merchant,TestMerchant
building list: Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Banamex Merchant,Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: TestMerchant
building list: Paytrace Merchant,TestMerchant
building list: Michelle's Business,Paytrace Merchant,TestMerchant
building list: Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Banamex Merchant,Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: TestMerchant
building list: Paytrace Merchant,TestMerchant
building list: Michelle's Business,Paytrace Merchant,TestMerchant
building list: Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant
building list: Banamex Merchant,Dashboard Demo,eServices Merchant,Germany Merchant,Global Canada Merchant,Michelle's Business,Paytrace Merchant,TestMerchant

  Merchants Pages of Dashboard App
    √ should verify the Merchants list view is alphabetical by Name

Solution

  • The problem you have is your promises runs away. You didn't wait for them to complete before the returning promise resolves.

    Try this:

    function buildMerchantListArray() {
      const list: string[] = []
      const promises: Promise<void>[] = []
      for (let i = 20; i >= 0; i--) {
        promises.push(
          this.getMerchantName(i)
            .isPresent()
            .then((present) => {
              if (present) {
                this.getMerchantName(i)
                  .getText()
                  .then((text: string) => {
                    list.unshift(text);
                    console.log('building list: ' + list)
                  })
              }
            })
        )
      }
      return Promise.all(promises).then(() => list)
    }