Skip to content

Commit

Permalink
docs: example of puppeteer in extension
Browse files Browse the repository at this point in the history
  • Loading branch information
OrKoN committed May 2, 2024
1 parent 461a8ff commit 9912456
Show file tree
Hide file tree
Showing 11 changed files with 780 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .eslintignore
Expand Up @@ -53,4 +53,6 @@ packages/ng-schematics/src/**/files/

# examples
examples/puppeteer-in-browser/out/**/*
examples/puppeteer-in-browser/node_modules/**/*
examples/puppeteer-in-browser/node_modules/**/*
examples/puppeteer-in-extension/out/**/*
examples/puppeteer-in-extension/node_modules/**/*
2 changes: 2 additions & 0 deletions examples/puppeteer-in-extension/.gitignore
@@ -0,0 +1,2 @@
out
node_modules
16 changes: 16 additions & 0 deletions examples/puppeteer-in-extension/background.js
@@ -0,0 +1,16 @@
/**
* @license
* Copyright 2024 Google Inc.
* SPDX-License-Identifier: Apache-2.0
*/
import {connect} from './main.js';

globalThis.testConnect = async url => {
const tab = await chrome.tabs.create({
url,
});
const tabId = tab.id;
const browser = await connect(tabId);
const [page] = await browser.pages();
return await page.evaluate('document.title');
};
187 changes: 187 additions & 0 deletions examples/puppeteer-in-extension/main.mjs
@@ -0,0 +1,187 @@
/**
* @license
* Copyright 2024 Google Inc.
* SPDX-License-Identifier: Apache-2.0
*/

// globalThis.__PUPPETEER_DEBUG = '*';

import {Puppeteer} from 'puppeteer-core/lib/esm/puppeteer/common/Puppeteer.js';

const puppeteer = new Puppeteer({
isPuppeteerCore: true,
});

const tabTargetInfo = {
targetId: 'tabTargetId',
type: 'tab',
title: 'tab',
url: 'about:blank',
attached: false,
canAccessOpener: false,
};

const pageTargetInfo = {
targetId: 'pageTargetId',
type: 'page',
title: 'page',
url: 'about:blank',
attached: false,
canAccessOpener: false,
};

class Transport {
constructor(tabId) {
this.tabId = tabId;
}
send(message) {
const parsed = JSON.parse(message);
switch (parsed.method) {
case 'Browser.getVersion': {
this.onmessage(
JSON.stringify({
id: parsed.id,
sessionId: parsed.sessionId,
method: parsed.method,
result: {
protocolVersion: '1.3',
product: 'chrome',
revision: 'unknown',
userAgent: 'chrome',
jsVersion: 'unknown',
},
})
);
return;
}
case 'Target.getBrowserContexts': {
this.onmessage(
JSON.stringify({
id: parsed.id,
sessionId: parsed.sessionId,
method: parsed.method,
result: {
browserContextIds: [],
},
})
);
return;
}
case 'Target.setDiscoverTargets': {
this.onmessage(
JSON.stringify({
method: 'Target.targetCreated',
params: {
targetInfo: tabTargetInfo,
},
})
);
this.onmessage(
JSON.stringify({
method: 'Target.targetCreated',
params: {
targetInfo: pageTargetInfo,
},
})
);
this.onmessage(
JSON.stringify({
id: parsed.id,
sessionId: parsed.sessionId,
method: parsed.method,
result: {},
})
);
return;
}
case 'Target.setAutoAttach': {
if (parsed.sessionId === 'tabTargetSessionId') {
this.onmessage(
JSON.stringify({
method: 'Target.attachedToTarget',
params: {
targetInfo: pageTargetInfo,
sessionId: 'pageTargetSessionId',
},
})
);
} else if (!parsed.sessionId) {
this.onmessage(
JSON.stringify({
method: 'Target.attachedToTarget',
params: {
targetInfo: tabTargetInfo,
sessionId: 'tabTargetSessionId',
},
})
);
}
this.onmessage(
JSON.stringify({
id: parsed.id,
sessionId: parsed.sessionId,
method: parsed.method,
result: {},
})
);
return;
}
}
if (parsed.sessionId === 'pageTargetSessionId') {
delete parsed.sessionId;
}
chrome.debugger
.sendCommand(
{tabId: this.tabId, sessionId: parsed.sessionId},
parsed.method,
parsed.params
)
.then(response => {
this.onmessage(
JSON.stringify({
id: parsed.id,
sessionId: parsed.sessionId ?? 'pageTargetSessionId',
method: parsed.method,
result: response,
})
);
})
.catch(err => {
this.onmessage(
JSON.stringify({
id: parsed.id,
sessionId: parsed.sessionId ?? 'pageTargetSessionId',
method: parsed.method,
error: err,
})
);
});
}
close() {
console.log('close');
}
}

async function connect(tabId) {
await chrome.debugger.attach({tabId}, '1.3');
const transport = new Transport(tabId);

chrome.debugger.onEvent.addListener((debugee, method, params) => {
if (debugee.tabId !== tabId) {
return;
}
transport.onmessage(
JSON.stringify({
sessionId: debugee.sessionId ?? 'pageTargetSessionId',
method: method,
params: params,
})
);
});

return puppeteer.connect({
transport,
});
}

export {connect};
10 changes: 10 additions & 0 deletions examples/puppeteer-in-extension/manifest.json
@@ -0,0 +1,10 @@
{
"name": "Puppeteer in extension",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js",
"type": "module"
},
"permissions": ["debugger", "background"]
}

0 comments on commit 9912456

Please sign in to comment.