Hi all.
I'm running some test with jest + jsdom, and found a problem, not sure if there is a bug or I'm missing something.
The following test snippet creates an event listener for the 'message' type, and then posts a message:
const messageHandler = event => {
console.log('message handler called');
};
window.addEventListener('message', messageHandler, false);
window.postMessage('called', '*');
await new Promise(resolve => setTimeout(resolve, 1000)); // wait a bit
If we run the above test, we can see in the console the message 'message handler called' as expected.
However, when creating the event listener inside a Promise, calling the corresponding postMessage does not seem to trigger the event, and the Promise cannot be resolved.
Example:
const functionThatReturnsPromise = function() {
return new Promise((resolve) => {
const messageHandlerForPromise = event => {
console.log('message handler for promise called');
// solve the Promise if message is posted
resolve({ data: 'solved' });
}
// adding event listener inside the Promise
window.addEventListener('message', messageHandlerForPromise, false);
});
};
window.postMessage('called', '*');
await new Promise(resolve => setTimeout(resolve, 100)); // wait a bit
const promiseToSolve = functionThatReturnsPromise();
return promiseToSolve.then(result => {
expect(result.data).toBe('solved');
});
In the above code, the Promise will never get resolved, as the postMessage does not seems to trigger the event listener.
Is this a bug, or there is something missing here ?
Thanks a lot in advance,
Full test here:
test("window.postMessage", async () => {
const messageHandler = event => {
console.log('message handler called');
};
window.addEventListener('message', messageHandler, false);
window.postMessage('called', '*');
await new Promise(resolve => setTimeout(resolve, 1000)); // wait a bit
window.removeEventListener('message', messageHandler, false);
const functionThatReturnsPromise = function() {
return new Promise((resolve) => {
const messageHandlerForPromise = event => {
console.log('message handler for promise called');
resolve({ data: 'solved' });
}
window.addEventListener('message', messageHandlerForPromise, false);
});
};
window.postMessage('called', '*');
await new Promise(resolve => setTimeout(resolve, 100)); // wait a bit
const promiseToSolve = functionThatReturnsPromise();
return promiseToSolve.then(result => {
expect(result.data).toBe('solved');
});
}, 5000);