I have a website that municates through postMessage mands
window.parent.postMessage(munication, this.origin);
When using playwright, I'm trying to do an "on message" handler
function eventListener(returnEvent: any): any {
window.addEventListener('message', function(event: MessageEvent) {
console.log('Im here');
if (event.data.messageId === 'payment-method') {
console.log('setting return event', event);
returnEvent = event;
return returnEvent;
}
});
}
...
let returnEvent: any = {};
await page.evaluate(eventListener, returnEvent);
await creditCardDetailsPage.fillFormValid();
await page.waitForTimeout(5000); //give time for message event to fire
console.log('event was', returnEvent);
await expect(returnEvent).toEqual(<MY DATA OBJECT HERE>)
console output
Im here
setting return event MessageEvent
event was {}
I cannot put my expects in the page.evaluate()
code, because then it's executing within the context of the javascript tag that it's injecting, and not within the context of the spec.
I have a website that municates through postMessage mands
window.parent.postMessage(munication, this.origin);
When using playwright, I'm trying to do an "on message" handler
function eventListener(returnEvent: any): any {
window.addEventListener('message', function(event: MessageEvent) {
console.log('Im here');
if (event.data.messageId === 'payment-method') {
console.log('setting return event', event);
returnEvent = event;
return returnEvent;
}
});
}
...
let returnEvent: any = {};
await page.evaluate(eventListener, returnEvent);
await creditCardDetailsPage.fillFormValid();
await page.waitForTimeout(5000); //give time for message event to fire
console.log('event was', returnEvent);
await expect(returnEvent).toEqual(<MY DATA OBJECT HERE>)
console output
Im here
setting return event MessageEvent
event was {}
I cannot put my expects in the page.evaluate()
code, because then it's executing within the context of the javascript tag that it's injecting, and not within the context of the spec.
- You're going to have to have your listener add something to the page or console log something (in the page context) and then you'll have to pick up that change in your test – Ben Gooding Commented Sep 22, 2021 at 23:07
- This test is also closer to a unit test that you ideally shouldn't be testing this here. It's much more mon to test the result of an action in browser tests and how the DOM is impacted by an action. – Ben Gooding Commented Sep 22, 2021 at 23:10
3 Answers
Reset to default 4I wanted to eventually get it to an expect
, rather an evaluate
or a waitForEvent
.
Sadly I couldn't find anything for listening to a message event. Instead we just go for console.info
.
This solution wraps the page.on('console', ...)
into an async function that we can simply use as a 'resolve if success, hang if failure' switch
// Return true if the page emits 'Hello, World!' to the console info level
async function waitForMessageAsync(): Promise<boolean> {
return new Promise(function (resolve) {
page.on('console', (msg) => {
if (msg.type() === 'log' && msg.text() === 'Hello, World!') {
resolve(true);
}
});
});
}
await expect(await waitForMessageAsync).toBeTruthy();
This way, expect
will fail the test if it times out waiting for our 'Hello, World!'
message!