Puppeteer: How to listen to object events Puppeteer: How to listen to object events google-chrome google-chrome

Puppeteer: How to listen to object events


First, you have to expose a function that can be called from within the page. Second, you listen for the event and call the exposed function and pass on the event data.

// Expose a handler to the pageawait page.exposeFunction('onCustomEvent', ({ type, detail }) => {    console.log(`Event fired: ${type}, detail: ${detail}`);});// listen for events of type 'status' and// pass 'type' and 'detail' attributes to our exposed functionawait page.evaluateOnNewDocument(() => {    window.addEventListener('status', ({ type, detail }) => {        window.onCustomEvent({ type, detail });    });});await page.goto(/* ... */);

If there is an event status fired in the page now (like the code you have given), you would see it being logged in the console of your Node.js application.

As posted in the comments, a more complex example can be found in the puppeteer examples.


If you want to actually await the custom event, you can do it this way.

const page = await browser.newPage();/**  * Attach an event listener to page to capture a custom event on page load/navigation.  * @param {string} type Event name.  * @return {!Promise}  */function addListener(type) {  return page.evaluateOnNewDocument(type => {    // here we are in the browser context    document.addEventListener(type, e => {      window.onCustomEvent({ type, detail: e.detail });    });  }, type);}const evt = await new Promise(async resolve => {  // Define a window.onCustomEvent function on the page.  await page.exposeFunction('onCustomEvent', e => {    // here we are in the node context    resolve(e); // resolve the outer Promise here so we can await it outside  });  await addListener('status'); // setup listener for "status" custom event on page load  await page.goto('http://example.com');  // N.B! Do not use { waitUntil: 'networkidle0' } as that may cause a race condition});console.log(`${evt.type} fired`, evt.detail || '');

Built upon the example at https://github.com/puppeteer/puppeteer/blob/main/examples/custom-event.js


A simpler method await waitForEvent('event-name', 10)

/** * Wait for the browser to fire an event (including custom events) * @param {string} eventName - Event name * @param {integer} seconds - number of seconds to wait. * @returns {Promise} resolves when event fires or timeout is reached */async function waitForEvent(eventName, seconds) {    seconds = seconds || 30;    // use race to implement a timeout    return Promise.race([        // add event listener and wait for event to fire before returning        page.evaluate(function(eventName) {            return new Promise(function(resolve, reject) {                document.addEventListener(eventName, function(e) {                    resolve(); // resolves when the event fires                });            });        }, eventName),        // if the event does not fire within n seconds, exit        page.waitForTimeout(seconds * 1000)    ]);}

Source