Search code examples
angularrestcodeceptjs

Polling a-sync REST service till result is true within CodeceptJS scenario


Looking for a solution to poll an a-sync REST call till result is FOUND with Codeception / codeceptJS e2e testing suite. Have no clue at all if this is possible at all. Polling will go on for max 1 to 2 minutes and every 10 seconds will be okay.

Scenario.only('Poll for print job status', async (I, loginAs) => {

    const guid = '4b46b91f-5e03-4bd1-845e-96d179b9f607';

    const endPointObj = { endPoint: 'https://......../print-service/api/print/job/',
                          headers: { 'Ocp-Apim-Subscription-Key': 'theKey' },
                          APIversion: '?api-version=2019-07-01' 
                        }

    const printJobService = async (guid, found) => {

      let serviceResultData;
      const serviceResult = await I.sendGetRequest(`${endPointObj.endPoint}${guid}${endPointObj.APIversion}`, endPointObj.headers);

      serviceResultData = serviceResult.data;

      return serviceResultData;
    }

    const printJobServiceResultFound = await printJobService(guid);
    const response = printJobServiceResultFound;
    // checkResult is an external UTIL function that checks the result
    assert.equal(checkResult(response), 'FOUND');

    pause();
});

So I've got this working, but this is only a 1-time run. Have been thinking of different approaches but only thing I came up with is the retry() function but that relies on something failing. My service doesn't fail.

The function printJobService needs to be polled.

Insights would be much appreciated.


Solution

  • This was written for an older RxJS which polled recursively to a service till the service returned a JSON attribute __next, once the __next was not there that means the polling had to stop. You can modify it to rxJS 6+. Let me know if it helps

    poll(): Observable<{source : STATS[], data : any[]}>{
        return this.retrieve('STATS')
        .map(res=>res.json().d)
        .delay(5000)
        .expand(obj => obj.__next 
            ? this.retrieve('STATS',obj.__next.substr(obj.__next.indexOf('?')+1)).map(res=>res.json().d)
            : Observable.empty()
        )
        .reduce((acc, data) => acc.concat(data.results), [])
        .map((stats) => {
          // when succesful
        })
        .catch(this.errorHandler);
    };