最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how can I get playwright to listen to message events - Stack Overflow

programmeradmin1浏览0评论

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.

Share Improve this question asked Sep 22, 2021 at 22:46 Matt WestlakeMatt Westlake 3,6517 gold badges43 silver badges83 bronze badges 2
  • 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
Add a ment  | 

3 Answers 3

Reset to default 4

I 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!

发布评论

评论列表(0)

  1. 暂无评论