I’m having issues with Puppeteer’s page.waitForFunction method. It’s not working as I thought it would. Here’s what I’m trying to do:
// Check for a specific message
await page.waitForFunction(() => {
const messageBox = document.getElementById('notification');
return messageBox && messageBox.innerText.includes('Expected notification');
});
// Look for results after clicking a button
await page.waitForSelector('#results-container', {
visible: true,
timeout: 3 * 60 * 1000
});
The weird thing is, even when I can see the message on the page and confirm it in the browser console, the first function doesn’t seem to trigger the next step. It’s like it’s stuck.
Also, these two events (message and results) are mutually exclusive. If one happens, the other won’t.
Any ideas on how to make this work correctly? I’m scratching my head here!
I’ve encountered similar issues with page.waitForFunction before. One thing to consider is that the function runs in the browser context, so any variables or functions from your Node.js environment won’t be available.
A workaround I’ve found effective is to use page.evaluate in combination with a custom Promise. This allows you to check for both conditions simultaneously:
I’ve run into this exact problem before, and it can be really frustrating. One thing that worked for me was using a MutationObserver instead.
Here’s a snippet that might help:
await page.evaluate(() => {
return new Promise((resolve) => {
const observer = new MutationObserver((mutations) => {
for (let mutation of mutations) {
if (mutation.type === 'childList') {
const messageBox = document.getElementById('notification');
const resultsContainer = document.getElementById('results-container');
if (messageBox && messageBox.innerText.includes('Expected notification')) {
observer.disconnect();
resolve('notification');
} else if (resultsContainer && window.getComputedStyle(resultsContainer).display !== 'none') {
observer.disconnect();
resolve('results');
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
});
});
This approach watches for DOM changes and checks your conditions each time. It’s been more reliable for me, especially with dynamic content. Hope this helps!