Use Puppeteer in browser extension
Tags: javascript, webdev, programming, tutorial
Published: 2021-12-06 19:46:08

## Problem

Recently in one of the projects, I had to do some automation on web pages through **extension**. So i wanted to leverage [puppeteer](https://pptr.dev/) api instead of forming and executing raw devtool commands through [chrome.debugger](https://developer.chrome.com/docs/extensions/reference/debugger/) extension api directly or dispatching events on target elements through content scripts as some web pages discards the [untrusted events](https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted).

## 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](https://chromedevtools.github.io/devtools-protocol/).

You can check repo [here](https://github.com/gajananpp/puppeteer-extension-transport). Repo contains  [v2 extension](https://github.com/gajananpp/puppeteer-extension-transport/tree/main/examples/extension-v2)/[v3 extension](https://github.com/gajananpp/puppeteer-extension-transport/tree/main/examples/extension-v3) 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 :-
```typescript
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)
    );
  }
});
```

Execution :-


![Execution image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txxs1uk7boy8a55fc7j1.gif)



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](https://github.com/gajananpp/puppeteer-extension-transport/blob/main/docs/README.md).


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