1

In Puppeteer's evaluate function, I can access variables that seem to be predefined, but only in the scope of the function:

// Excerpt
page.evaluate(() => {
  alert("Hello world!!");
});

There aren't any parameters that get passed into the function either...

Whereas if it wasn't inside the evaluate function, I can't access all the variables. What's even more interesting is that the code inside evaluate has nothing to do with the code outside of it.

// Excerpt
page.evaluate(() => {
  console.log("Hello world!!");
});

The above code does not print inside the Node.js console, but rather in the Chromium browser.

How does this work and how can I do it too?

code
  • 5,690
  • 4
  • 17
  • 39
  • Yes, the callback is serialized and executed in the browser context. Just define the variables inside the callback and it'll be as if you'd defined them in the browser console. If you want to access logs from the console in Node, see [How do print the console output of the page in puppeter as it would appear in the browser?](https://stackoverflow.com/questions/58089425). If you want to pass data to the callback from Node, see [How can I pass variable into an evaluate function?](https://stackoverflow.com/questions/46088351). Anything you return from the callback must be serializable. – ggorlen Jun 29 '21 at 23:43
  • @ggorlen no, I don't have a problem with it. I already know how to do it. I'm asking how Puppeteer defined variables for the callback without any parameters... – code Jun 29 '21 at 23:51
  • 1
    What variables do you mean? `alert` and `console.log` are attached to the browser's `window` object. If you did pass data arguments to the callback, Puppeteer just calls a fancy version of `JSON.stringify` on them, then once it deserializes the function in browser context, it calls a fancy `JSON.parse` on each parameter and invokes your callback with the items. See [the source](https://github.com/puppeteer/puppeteer/blob/523aa0aafa9b2bf2c14e0ba416e4100f73bafa0a/src/common/ExecutionContext.ts#L196). – ggorlen Jun 30 '21 at 00:40

1 Answers1

1

Puppeteer wraps your function using Function constructor and Function#toString and then evaluate it in the custom context, like this:

let functionText = evaluateFunc.toString();

let newFunc = new Function(`
function alert() {...}

(${functionText})
`);

newFunc();

Therefore variables, functions, etc. outside of the function isn't accessible.

If you want to pass arguments inside evaluate function, see How can I pass variable into an evaluate function?