Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Promises in Postman tests?

I need to use some async code in my Postman test.

As it's a complex scenario I've reproduced the scenario in a very simple test with the following code:

let promiseNumber = 0;

function resolvedPromise() {
    return new Promise((resolve, reject) => {
        pm.sendRequest('https://postman-echo.com/get', (err, res) => {
            if (err) {
                console.log(err);
                reject();
            } else {
                console.log(`Resolved promise ${++promiseNumber}`);
                resolve();
            }
        });
    });
}

resolvedPromise()
    .then(resolvedPromise)
    .then(resolvedPromise)
    .catch(err => console.log(err));

The expected result on the console would be:

Resolved promise 1
Resolved promise 2
Resolved promise 3

But instead I receive:

Resolved promise 1

Is there a way to make Promises or async code available at Postman?

like image 420
Felipe Plets Avatar asked Dec 26 '18 16:12

Felipe Plets


People also ask

What is promise in API?

The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.

What are programming promises?

A promise is an object returned by an asynchronous function, which represents the current state of the operation. At the time the promise is returned to the caller, the operation often isn't finished, but the promise object provides methods to handle the eventual success or failure of the operation.

Does postman support async await?

The Postman Sandbox detects open timeouts and intervals and awaits execution until they're all cleared/resolved. If we use a dummy Interval object, we can use async/await to have a cleaner method of chaining asynchronous calls.

Do promises pause execution?

Promises Can Be Paused Just because you are already executing inside a then() function, doesn't mean you can't pause it to complete something else first. To pause the current promise, or to have it wait for the completion of another promise, simply return another promise from within then() .


1 Answers

UPDATE: The original solution used 2147483647 as timeout value, now it was refactored to use Number.MAX_SAFE_INTEGER as suggested in the comments.

I did some more tests and realize that it always stop working after I use pm.sendRequest. If I try to resolve the Promise it works.

Seems a known bug looking at this thread.

The workaround for it would be only leave an open timeout while processing the code. Just ensure all possible paths clear the timeout or the call will hang for 300000 years 😀

// This timeout ensure that postman will not close the connection before completing async tasks.
//  - it must be cleared once all tasks are completed or it will hang
const interval = setTimeout(() => {}, Number.MAX_SAFE_INTEGER);

let promiseNumber = 0;

function resolvedPromise() {
    return new Promise((resolve, reject) => {
        pm.sendRequest('https://postman-echo.com/get', (err, res) => {
            if (err) {
                console.log(err);
                reject();
            } else {
                console.log(`Resolved promise ${++promiseNumber}`);
                resolve();
            }
        });
    });
}

resolvedPromise()
    .then(resolvedPromise)
    .then(resolvedPromise)
    .then(() => clearTimeout(interval))
    .catch(err => {
        console.log(err);
        clearTimeout(interval);
    });

Now it prints the expected result:

Resolved promise 1
Resolved promise 2
Resolved promise 3
like image 160
Felipe Plets Avatar answered Oct 16 '22 23:10

Felipe Plets