DEV Community

Gajanan Patil
Gajanan Patil

Posted on

Use Puppeteer in browser extension

Problem

Recently in one of the projects, I had to do some automation on web pages through extension. So i wanted to leverage puppeteer api instead of forming and executing raw devtool commands through chrome.debugger extension api directly or dispatching events on target elements through content scripts as some web pages discards the untrusted events.

Solution

To achieve this, I created a puppeteer transport package which will allow you to use puppeteer in your browser extension's background_page(v2)/service_worker(v3). This package internally uses chrome.debugger api for communicating with Chrome Devtools Protocol.

You can check repo here. Repo contains v2 extension/v3 extension examples which you can load in your browser to test.

Usage

Since the target is attached using chrome.debugger api, browser doesn't need to be started using remote debugging flag.

Here is an example code snippet :-

import puppeteer from 'puppeteer-core/lib/cjs/puppeteer/web';
import { ExtensionDebuggerTransport } from 'puppeteer-extension-transport';

const run = async (tabId: number) => {
  const extensionTransport = await ExtensionDebuggerTransport.create(tabId);
  const browser = await puppeteer.connect({
    transport: extensionTransport,
    defaultViewport: null,
  });

  // use first page from pages instead of using browser.newPage()
  const [page] = await browser.pages();

  await page.goto('https://wikipedia.org');

  const screenshot = await page.screenshot({
    encoding: 'base64',
  });
  console.log(`data:image/png;base64,${screenshot}`);

  const englishButton = await page.waitForSelector('#js-link-box-en > strong');
  await englishButton?.click();

  const searchBox = await page.waitForSelector('#searchInput');
  await searchBox?.type('telephone');
  await page.keyboard.press('Enter');

  await page.close();
};

chrome.commands.onCommand.addListener(command => {
  if (command === 'test') {
    chrome.tabs.create(
      {
        active: true,
        url: 'https://www.google.co.in',
      },
      tab => (tab.id ? run(tab.id) : null)
    );
  }
});
Enter fullscreen mode Exit fullscreen mode

Execution :-

Execution image

With this, from extension you can do :-

  1. automation
  2. monitor and handle page/network lifecycle events
  3. profiling/crawling of web pages
  4. any other thing you would like to use puppeteer for

You can find reference docs for package here.

For more information checkout :-
https://github.com/gajananpp/puppeteer-extension-transport

Discussion (0)