Whenever I try to pass a function, like this:
var myFunc = function() { console.log(\"lol\"); };
await page.evaluate(func => {
func();
return true;
},
Created a helper function that wraps page.evaluate:
const evaluate = (page, ...params) => browserFn => {
const fnIndexes = [];
params = params.map((param, i) => {
if (typeof param === "function") {
fnIndexes.push(i);
return param.toString();
}
return param;
});
return page.evaluate(
(fnIndexes, browserFnStr, ...params) => {
for (let i = 0; i < fnIndexes.length; i++) {
params[fnIndexes[i]] = new Function(
" return (" + params[fnIndexes[i]] + ").apply(null, arguments)"
);
}
browserFn = new Function(
" return (" + browserFnStr + ").apply(null, arguments)"
);
return browserFn(...params);
},
fnIndexes,
browserFn.toString(),
...params
);
};
export default evaluate;
Takes all parameters and converts functions to string.
Then recreates functions in browser context.
See https://github.com/puppeteer/puppeteer/issues/1474
You can use this function like so:
const featuredItems = await evaluate(page, _getTile, selector)((get, s) => {
const items = Array.from(document.querySelectorAll(s));
return items.map(node => get(node));
});