Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Class as an Argument to page.evaluate in Puppeteer

In Puppeteer, page.evaluate throws an error if I pass a class as an argument.

It works for regular objects though.

Is there some workaround to make it work?

const puppeteer = require("puppeteer");

(async () => {
let browser = await puppeteer.launch({
    headless: true
});
let page = await browser.newPage();
class SomeClass {
    constructor() {
        this.a = 3;
    }
}
await page.evaluate((SomeClass) => {
    let object = new SomeClass();
    console.log(object.a);
}, SomeClass);
})();
like image 492
yewang Avatar asked Jul 16 '18 06:07

yewang


People also ask

How do you pass a function in page to evaluate?

You cannot pass a function directly into page. evaluate() , but you can call another special method ( page. exposeFunction ), which expose your function as a global function (also available in as an attribute of your page window object), so you can call it when you are inside page.

What is page evaluate in puppeteer?

evaluate()Evaluates a function in the page context. Inside this function we have access to the document object, so we can call any DOM API: const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer. launch() const page = await browser. newPage() await page.

How do you click a puppeteer button?

How to click on a button using puppeteer. click() is used to click on any element or button in the puppeteer. the only challenging thing with this is finding the element. Once you got the element just fire the click() function.

What is puppeteer JS?

Puppeteer is a Node. js library developed by Google that lets you control headless Chrome through the DevTools Protocol. It is a tool for automating testing in your application using headless Chrome or Chromebit devices, without requiring any browser extensions like Selenium Webdriver or PhantomJS.


2 Answers

There is a similar problem if you try to pass a function. I've seen people stringifying the function to pass it to puppeteer to make it work, so in your case I'd do this using eval. Many people think eval is evil, maybe there is a better way, but at least it's a possible workaround.

class SomeClass {
    constructor() {
        this.a = 3;
    }
}    
await page.evaluate((strSomeClass) => {
    eval("window.SomeClass = " + strSomeClass);
    let object = new SomeClass();
    console.log(object.a);
}, SomeClass.toString());
like image 151
Paula Vega Avatar answered Oct 05 '22 15:10

Paula Vega


You can avoid using eval() by passing an instance of the object, rather then the object itself, to page.evaluate():

await page.evaluate(object => {
  console.log(object.a);
}, new SomeClass);

Your full program should look something like this:

'use strict';

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: true,
  });

  const page = await browser.newPage();

  class SomeClass {
    constructor() {
      this.a = 3;
    }
  }

  await page.evaluate(object => {
    console.log(object.a);
  }, new SomeClass);

  await browser.close();
})();
like image 45
Grant Miller Avatar answered Oct 05 '22 14:10

Grant Miller