2

I'm trying to follow the instructions here to bundle puppeteer, with the intention of including it in a chrome extension as a hacky way of scripting operations in the browser window (specifically, printing a page to PDF, which is surprisingly impossible with just the Chrome Extension API as far as I can tell).

As per the README in the link above, I've set up my Chrome extension as follows:

background.html

<script src="./puppeteer/utils/browser/puppeteer-web.js"></script>
<script src="background.js"></script>

background.js

const puppeteer = require("puppeteer");

Throws the error puppeteer/utils/browser/puppeteer-web.js:10877 (anonymous function) Uncaught TypeError: Puppeteer is not a constructor.

What am I missing here?

Chrome version: Version 69.0.3497.100

Node version: 7.4.0

Jess
  • 1,515
  • 3
  • 23
  • 32
  • 1
    Finally someone made a question about puppeteer web. :D Can you share a bit of your code? – Md. Abu Taher Oct 26 '18 at 04:14
  • I tested out puppeteer-web, so far it worked absolutely fine for me. Can you tell me your browser version, node version etc so we can figure out what's wrong? – Md. Abu Taher Oct 26 '18 at 05:54
  • @Md.AbuTaher I've updated the details! – Jess Oct 26 '18 at 21:36
  • What I cannot understand is, the error log says `Puppeteer`, not `puppeteer`. Are you sure the error happens if you just require the library? – Md. Abu Taher Oct 27 '18 at 10:07
  • Yeah, it's erroring on this line: `module.exports = new Puppeteer(__dirname, preferredRevision, isPuppeteerCore);` (in `puppeteer-web.js`). Is there another way to `require` it besides how I have it above? – Jess Oct 27 '18 at 15:07
  • Provided working solution as answer, added an issue https://github.com/GoogleChrome/puppeteer/issues/3455 just in case. Peace. – Md. Abu Taher Oct 27 '18 at 17:04

1 Answers1

2

Chrome extensions does not allow unsafe-eval, that is reason why puppeteer is not working on chrome extension. Set the following on manifest.json.

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"

Tested with following code,

const puppeteer = require('puppeteer');

async function getTitle() {
  const browser = await puppeteer.connect({
    browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser/9f0a2240-2cb7-4efa-ac3c-8ef883d36d12',
  });
  const page = await browser.newPage();
  await page.goto('http://example.com');
  const title = await page.title();
  await page.close();
  await browser.disconnect();
  return title;
}

getTitle().then(console.log);

Result:

How did I find it:

The code is running perfectly if I run it directly or put it on a page, but wasn't working from chrome extension only.

The asyncawait check here helped me find the culprit.

let asyncawait = true;
try {
  new Function('async function test(){await 1}');
} catch (error) {
  asyncawait = false;
}
Md. Abu Taher
  • 17,395
  • 5
  • 49
  • 73
  • Thank you!! I assume you got the `browserWSEndpoint` by running chrome.exe with special command line flags -- do you happen to know if there's a way to programmatically get that endpoint for another tab in your own browser (if puppeteer is running in the extension's background window)? – Jess Oct 27 '18 at 20:21