Issue with helper functions returning promises


#1

Hi everyone,

When switching from Nightmare to Puppeteer I noticed a lot fo good things happen. One strange thing I have noticed is that async functions that are in helpers seem to be returning promises, when they used to be handled by codecept and return the values. This was helpful because then I would not have to await the values in page objects / tests and wouldn’t have to make all the functions async.

Here is an example of something in a helper (included in the codecept.json) that I would expet to not return a promise but is:

      async asyncFunc(name) {
        const puppeteer = this.helpers.Puppeteer;
        let result = await puppeteer.executeScript((correctPlanName) => {
          const plans = document.querySelectorAll('tr.ng-scope');
          for (let i = 0; i < plans.length; i++) {
            const planName = plans[i].querySelector('[data-title="\'Name\'"]');
            const curName = planName.innerText.trim();
            if (correctPlanName === curName) {
              const editButton = plans[i].querySelector('.fa.fa-pencil');
              editButton.click();
              return true;
            }
          }
          return false;
        }, name);
        await puppeteer.wait(2);
        return result
      }

Also in testing if I just make the whole function return true it is still a promise. Any insight would be very welcome :slight_smile:


#2

When you declare function as async it means it returns a promise.
That’s how async works


#3

So when we were using Nightmare, if we put async functions in a helper file codeceptJS would know it was supposed to return a promise and it would save us having to use async in the Page object itself. Is that not the case with Puppeteer?

I am definitely aware of how async/await works but I thought codecept was handling the promise in Helpers


#4

A promise returned from a helper is taken by CodeceptJS into the global promise chain called “recorder”.
So it’s automatically appended to all other executed promises.
Not sure of the difference between Nightmare and Puppeteer but that’s how CodeceptJS works :slight_smile:


#5

Okay cool, thanks for the insight!


#6

So then I am out of luck if I want to not have to put async and await on a function?

The only reason I ask is because If I have a situation where I have an async function in a helper, every page object that uses that needs async and await, every test that uses that page object function needs async/await, it just gets messy. Any ideas on how to avoid that?


#7

No, every as I said async functions are appended to promise chain. So you probably won’t need async/await for anything. But seems can be not so nice when executed from inside Page Objects.

I need to learn more to say something exact.