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) ]);}