I’m working on automating a web-based game using Puppeteer. I can successfully navigate to the site, log in, and reach the game page, but I’m having trouble with the next step.
My goal is to inject JavaScript code that monitors the page continuously using jQuery. This script should watch for specific game states and trigger actions in my Node.js Puppeteer script when certain conditions are met.
Here’s what I want to achieve: I need a browser-level function that checks the page every second for element A. Once element A appears, the script should extract some data B from the page and somehow communicate this back to my Node.js code. When my Puppeteer script receives data B, it should perform actions like moving the mouse or clicking elements.
I’m not sure how to establish this communication between the injected page script and my main Puppeteer code. Is there a way to set up event listeners or callbacks that can bridge this gap? Any guidance on the best approach would be really helpful.
you could also use page.evaluateHandle()
with promises. create a promise in your injected script that resolves when element A appears, then await it in your puppeteer code. try await page.evaluateHandle(() => new Promise(resolve => setInterval(() => { if(elementExists) resolve(dataB) }, 1000)))
- your node script just waits until the condition’s met without constantly polling.
Use page.exposeFunction()
to bridge your browser and Node.js. Expose a function in your Puppeteer script that will receive data from the page, then inject your monitoring script with page.evaluate()
or page.addScriptTag()
. When your jQuery code spots element A and grabs data B, it calls the exposed function directly to send everything back to Node.js. That function can then trigger your mouse movements or clicks. Way cleaner than polling or constantly scraping from Node.js - you get real-time communication that only fires when your conditions are actually met.
You can also use page.waitForFunction()
with return values. Your Node.js code waits for specific conditions while the browser handles the monitoring. Try something like const dataB = await page.waitForFunction(() => { const elementA = document.querySelector('your-selector'); return elementA ? extractYourData() : false; }, {polling: 1000})
- it’ll pause until your condition’s met and return the data directly. This keeps your monitoring logic clean and handles timing automatically without intervals or custom functions.