Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Support for puppeteer-web #12022

Open
shivamothkuri opened this issue Feb 29, 2024 · 18 comments
Open

[Feature]: Support for puppeteer-web #12022

shivamothkuri opened this issue Feb 29, 2024 · 18 comments
Assignees

Comments

@shivamothkuri
Copy link

Feature description

As part of this PR, you have removed support for puppeteer web and want to look at that feature soon. Could you please implement this feature? Or if there is an alternative, could you please redirect me to one.

I want to use puppeteer-web to execute puppeteer script inside my chrome extension. I see there is a way to start chrome with remote debugging enabled and use puppeteer.connect to connect via ws, but I don't feel that is a cleaner way of doing it.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

It should be possible to execute puppeteer-core inside the extension. Is anything missing for that?

@shivamothkuri
Copy link
Author

@OrKoN As puppeteer-core has node specific dependencies like util, fs it throws error in the browser

Uncaught TypeError: The "original" argument must be of type Function
    at t.promisify (util.js:602:11)
    at 6b55 (index.js:11:18)
    at r (bootstrap:19:22)
    at 9a1f (BrowserFetcher.js:64:39)
    at r (bootstrap:19:22)
    at 29bb (Puppeteer.js:32:29)
    at r (bootstrap:19:22)
    at 8ce5 (initializePuppeteer.js:20:24)
    at r (bootstrap:19:22)
    at Object.f6b1 (puppeteer-core.js:33:34)

image

Somehow, these node specific dependencies should be separated to make this work on a browser.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

@shivamothkuri yeah you need to perhaps exclude them when you bundle

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

Do you have a test repo for this? Are you using webpack or rollup? I'd recommend using the rollup as webpack might be doing too many things.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

Also, what version do you use? BrowserFetcher does not exist anymore.

@shivamothkuri
Copy link
Author

I don't have a test repo, yet. I'm trying it on my local setup.

I got an archived repo which kind of solves my issue. But, this repo is using very old version of puppeteer-core v4.0. The author has used browserify and aliasify, which don't have good updates recently and failing to modularise ES2022 code from latest puppeteer-core, like using #(hashes) for private methods/variables.

So, I tried to use a older version of puppeteer-core v18.0.0. Even for this, the node dependencies are an issue.

I tried to use rollup, but the number of things to exclude are never ending. And, I would face same problem when I will try to update to a newer puppeteer-core version.

@shivamothkuri
Copy link
Author

Also, what version do you use? BrowserFetcher does not exist anymore.

Its puppeteer-core v18.0.0

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

Please try using the latest version, there should not be many things to exclude in the latest version: all Node dependencies would be only loaded in the node runtime and there should be not much to do. In fact, puppeteer-core is used by Chrome DevTools in the browser so that should mostly working.

@shivamothkuri
Copy link
Author

Ok. Let me try with latest version and get back. Thanks

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

So building something like this seems to work (main.js):

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

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

const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://localhost:9222'
});

await browser.disconnect();

index.html

<script type="module" src="out/main.js"></script>

rollupconfig:

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  input: 'main.mjs',
  output: {
    format: 'esm',
    dir: 'out'
  },
  plugins: [nodeResolve({
    browser: true,
    resolveOnly: ['puppeteer-core']
  })]
};

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

You need to run a browser like this: "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary" --remote-debugging-port=9222 --remote-allow-origins='*' and the URL to connect will be something like ws://127.0.0.1:9222/devtools/browser/7c4e3772-fcf9-41a2-8dc0-6c1d0920638b. Rollup still prints some warnings in ElementHandle but at least opening the page works, I think the warnings need to be solved with rollup.

@shivamothkuri
Copy link
Author

yes, I'm aware of this solution to use remote-debugging-port. But, I don't want my users to change the way they are opening the chrome.

If we use record/replay from chrome devtools recorder, it just works. I want to build an experience like that.

Do you have the source code/docs on how chrome devtools is able to replay without debugging port enabled?

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

@shivamothkuri that is not possible for security reasons.

@OrKoN
Copy link
Collaborator

OrKoN commented Feb 29, 2024

You can use https://developer.chrome.com/docs/extensions/reference/api/debugger but it is a bit more work to write a custom transport and that API does not support modern CDP sessions that Puppeteer requires. That is not directly related to running Puppeteer in the browser though.

@OrKoN OrKoN added the P3 label Feb 29, 2024
@OrKoN OrKoN self-assigned this Feb 29, 2024
@nprbst
Copy link

nprbst commented Mar 3, 2024

You can use https://developer.chrome.com/docs/extensions/reference/api/debugger but it is a bit more work to write a custom transport and ". That is not directly related to running Puppeteer in the browser though.

@OrKoN, can you expand on "that API does not support modern CDP sessions that Puppeteer requires", please?

@shivamothkuri
Copy link
Author

shivamothkuri commented Mar 4, 2024

@OrKoN I tried with latest puppeteer-core(22.3.0) and I'm using a custom transport for protocol from puppeteer-extension-transport .

This works for puppeteer-core v13.x, but having trouble for later releases.

When I tried with latest puppeteer-core version, I ger below error in the console
FYI - puppeteer-extension-transport is using CDP v1.3

CallbackRegistry.ts:117 Uncaught (in promise) s: Protocol error (Browser.getVersion): {"code":-32601,"message":"'Browser.getVersion' wasn't found"}
    at <instance_members_initializer> (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:13:890)
    at new c (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:13:954)
    at l.create (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:13:116)
    at C._rawSend (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:188:1873)
    at C.send (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:188:1813)
    at tn (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:240:47294)
    at to (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:240:47838)
    at async Object.executePuppeteerCode (chrome-extension://flpoboeigldifdddkkmfnikkmpmbpjob/background.js:240:52911)

I have my sample extension with this error message pushed here: https://github.com/shivamothkuri/chrome-ui-recorder

@OrKoN
Copy link
Collaborator

OrKoN commented Mar 4, 2024

You can use https://developer.chrome.com/docs/extensions/reference/api/debugger but it is a bit more work to write a custom transport and ". That is not directly related to running Puppeteer in the browser though.

@OrKoN, can you expand on "that API does not support modern CDP sessions that Puppeteer requires", please?

Puppeteer relies on the flat session mode https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-attachToTarget (i.e., multiple sessions in one connection with sessionId used to match commands to sessions) but AFAIK chrome.debugger only supports non-flat mode meaning a different chrome.debugger API needs to be invoked to attached to each of the targets manually (that might not work well if you want to configure the target before it starts running).

@OrKoN
Copy link
Collaborator

OrKoN commented Mar 4, 2024

@shivamothkuri looks like in the meantime some domains have been restricted for extensions so this explains the error you are seeing. I think the only short-term solution for newer versions is to catch this command on the transport level and return a dummy response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants