From 99124564b12c3f4a7122fab12c5697ebb5f5cd46 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 17 Apr 2024 08:55:56 +0200 Subject: [PATCH] docs: example of puppeteer in extension --- .eslintignore | 4 +- examples/puppeteer-in-extension/.gitignore | 2 + examples/puppeteer-in-extension/background.js | 16 + examples/puppeteer-in-extension/main.mjs | 187 +++++++ examples/puppeteer-in-extension/manifest.json | 10 + .../puppeteer-in-extension/package-lock.json | 461 ++++++++++++++++++ examples/puppeteer-in-extension/package.json | 16 + .../puppeteer-in-extension/playground.html | 1 + .../puppeteer-in-extension/rollup.config.mjs | 20 + .../puppeteer/puppeteer-in-extension.js | 41 ++ test/installation/src/puppeteer.spec.ts | 23 + 11 files changed, 780 insertions(+), 1 deletion(-) create mode 100644 examples/puppeteer-in-extension/.gitignore create mode 100644 examples/puppeteer-in-extension/background.js create mode 100644 examples/puppeteer-in-extension/main.mjs create mode 100644 examples/puppeteer-in-extension/manifest.json create mode 100644 examples/puppeteer-in-extension/package-lock.json create mode 100644 examples/puppeteer-in-extension/package.json create mode 100644 examples/puppeteer-in-extension/playground.html create mode 100644 examples/puppeteer-in-extension/rollup.config.mjs create mode 100644 test/installation/assets/puppeteer/puppeteer-in-extension.js diff --git a/.eslintignore b/.eslintignore index ef59bf07ea44d..aa5a050992532 100644 --- a/.eslintignore +++ b/.eslintignore @@ -53,4 +53,6 @@ packages/ng-schematics/src/**/files/ # examples examples/puppeteer-in-browser/out/**/* -examples/puppeteer-in-browser/node_modules/**/* \ No newline at end of file +examples/puppeteer-in-browser/node_modules/**/* +examples/puppeteer-in-extension/out/**/* +examples/puppeteer-in-extension/node_modules/**/* \ No newline at end of file diff --git a/examples/puppeteer-in-extension/.gitignore b/examples/puppeteer-in-extension/.gitignore new file mode 100644 index 0000000000000..8e5962ee72741 --- /dev/null +++ b/examples/puppeteer-in-extension/.gitignore @@ -0,0 +1,2 @@ +out +node_modules \ No newline at end of file diff --git a/examples/puppeteer-in-extension/background.js b/examples/puppeteer-in-extension/background.js new file mode 100644 index 0000000000000..4fe6908c2f87f --- /dev/null +++ b/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'); +}; diff --git a/examples/puppeteer-in-extension/main.mjs b/examples/puppeteer-in-extension/main.mjs new file mode 100644 index 0000000000000..c9d71cb3ca738 --- /dev/null +++ b/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}; diff --git a/examples/puppeteer-in-extension/manifest.json b/examples/puppeteer-in-extension/manifest.json new file mode 100644 index 0000000000000..c4587c2d702f7 --- /dev/null +++ b/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"] +} diff --git a/examples/puppeteer-in-extension/package-lock.json b/examples/puppeteer-in-extension/package-lock.json new file mode 100644 index 0000000000000..833ffc592949f --- /dev/null +++ b/examples/puppeteer-in-extension/package-lock.json @@ -0,0 +1,461 @@ +{ + "name": "puppeteer-in-extension", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "puppeteer-in-extension", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^4.14.3" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.3.tgz", + "integrity": "sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.3.tgz", + "integrity": "sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.3.tgz", + "integrity": "sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.3.tgz", + "integrity": "sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.3.tgz", + "integrity": "sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.14.3.tgz", + "integrity": "sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.3.tgz", + "integrity": "sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.3.tgz", + "integrity": "sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.3.tgz", + "integrity": "sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.3.tgz", + "integrity": "sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.3.tgz", + "integrity": "sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.3.tgz", + "integrity": "sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.3.tgz", + "integrity": "sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.3.tgz", + "integrity": "sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.3.tgz", + "integrity": "sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.3.tgz", + "integrity": "sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.3.tgz", + "integrity": "sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.14.3", + "@rollup/rollup-android-arm64": "4.14.3", + "@rollup/rollup-darwin-arm64": "4.14.3", + "@rollup/rollup-darwin-x64": "4.14.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.3", + "@rollup/rollup-linux-arm-musleabihf": "4.14.3", + "@rollup/rollup-linux-arm64-gnu": "4.14.3", + "@rollup/rollup-linux-arm64-musl": "4.14.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.3", + "@rollup/rollup-linux-riscv64-gnu": "4.14.3", + "@rollup/rollup-linux-s390x-gnu": "4.14.3", + "@rollup/rollup-linux-x64-gnu": "4.14.3", + "@rollup/rollup-linux-x64-musl": "4.14.3", + "@rollup/rollup-win32-arm64-msvc": "4.14.3", + "@rollup/rollup-win32-ia32-msvc": "4.14.3", + "@rollup/rollup-win32-x64-msvc": "4.14.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + } + } +} diff --git a/examples/puppeteer-in-extension/package.json b/examples/puppeteer-in-extension/package.json new file mode 100644 index 0000000000000..d149953c5963b --- /dev/null +++ b/examples/puppeteer-in-extension/package.json @@ -0,0 +1,16 @@ +{ + "name": "puppeteer-in-extension", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "rollup -c && cp manifest.json out/ && cp background.js out/" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^4.14.3" + } +} diff --git a/examples/puppeteer-in-extension/playground.html b/examples/puppeteer-in-extension/playground.html new file mode 100644 index 0000000000000..99d6fda7df993 --- /dev/null +++ b/examples/puppeteer-in-extension/playground.html @@ -0,0 +1 @@ + Playground diff --git a/examples/puppeteer-in-extension/rollup.config.mjs b/examples/puppeteer-in-extension/rollup.config.mjs new file mode 100644 index 0000000000000..fb82296b61850 --- /dev/null +++ b/examples/puppeteer-in-extension/rollup.config.mjs @@ -0,0 +1,20 @@ +/** + * @license + * Copyright 2024 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ +import {nodeResolve} from '@rollup/plugin-node-resolve'; + +export default { + input: 'main.mjs', + output: { + format: 'esm', + dir: 'out', + }, + plugins: [ + nodeResolve({ + browser: true, + resolveOnly: ['puppeteer-core'], + }), + ], +}; diff --git a/test/installation/assets/puppeteer/puppeteer-in-extension.js b/test/installation/assets/puppeteer/puppeteer-in-extension.js new file mode 100644 index 0000000000000..fe28eb9b688ad --- /dev/null +++ b/test/installation/assets/puppeteer/puppeteer-in-extension.js @@ -0,0 +1,41 @@ +import puppeteer from 'puppeteer'; +import path from 'path'; + +const pathToExtension = path.join( + process.cwd(), + 'puppeteer-in-extension', + 'out' +); + +const browser = await puppeteer.launch({ + headless: true, + executablePath: + '/Users/alexrudenko/src/pptr-test/chrome/mac_arm-126.0.6449.0/chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing', + args: [ + `--disable-extensions-except=${pathToExtension}`, + `--load-extension=${pathToExtension}`, + ], +}); + +try { + const port = process.argv[2]; + + const workerTarget = await browser.waitForTarget( + target => + target.type() === 'service_worker' && + target.url().endsWith('background.js') + ); + const worker = await workerTarget.worker(); + const result = await worker.evaluate(async url => { + while (!('testConnect' in globalThis)) { + await new Promise(resolve => setTimeout(resolve, 100)); + } + return await globalThis.testConnect(url); + }, `http://localhost:${port}/playground.html`); + + if (result !== 'Playground') { + throw new Error('Unexpected playground.html page title: ' + result); + } +} finally { + await browser.close(); +} diff --git a/test/installation/src/puppeteer.spec.ts b/test/installation/src/puppeteer.spec.ts index 95787500ea544..e4a1c754f7bcf 100644 --- a/test/installation/src/puppeteer.spec.ts +++ b/test/installation/src/puppeteer.spec.ts @@ -69,6 +69,29 @@ describe('`puppeteer`', () => { await server.stop(); } }); + + it('runs in the extension', async function () { + const examplePath = join(this.sandbox, 'puppeteer-in-extension'); + fs.cpSync(join(EXAMPLES_DIR, 'puppeteer-in-extension'), examplePath, { + recursive: true, + }); + spawnSync('npm', ['ci'], { + cwd: examplePath, + shell: true, + }); + spawnSync('npm', ['run', 'build'], { + cwd: examplePath, + shell: true, + }); + + const server = await TestServer.create(examplePath); + try { + const script = await readAsset('puppeteer', 'puppeteer-in-extension.js'); + await this.runScript(script, 'mjs', [String(server.port)]); + } finally { + await server.stop(); + } + }); }); // Skipping this test on Windows as windows runners are much slower.