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

Firefox extensions with v2.1.0 puppeteer #5532

Closed
corford opened this issue Mar 23, 2020 · 9 comments
Closed

Firefox extensions with v2.1.0 puppeteer #5532

corford opened this issue Mar 23, 2020 · 9 comments

Comments

@corford
Copy link

corford commented Mar 23, 2020

Now that puppeteer-firefox is deprecated (#5397) and there is not yet any Firefox support for connect() (#5152), is there a recommended way for using Puppeteer and Firefox with extensions/add-ons ?

This was the previous method we used with puppeteer-firefox (gleaned from: #4162):

const webExt = require('web-ext').default;
const pptrFirefox = require('puppeteer-firefox');
const getPort = require('get-port');

(async () => {
  const CDPPort = await getPort();
  await webExt.cmd.run(
      {
        sourceDir: 'path-to-add-on',
        firefox: pptrFirefox.executablePath(),
        args: [`-juggler=${CDPPort}`]
      },
      {
        // These are non CLI related options for each function.
        // You need to specify this one so that your NodeJS application
        // can continue running after web-ext is finished.
        shouldExitProgram: false
      }
    );

    const browserWSEndpoint = `ws://127.0.0.1:${CDPPort}`
    browser = await pptrFirefox.connect({
      browserWSEndpoint
    })
})();
@corford corford changed the title Firefox extensons with v2.1.0 puppeteer Firefox extensions with v2.1.0 puppeteer Mar 23, 2020
@mjzffr
Copy link
Contributor

mjzffr commented Mar 26, 2020

Thanks for filing. I'm not sure when a Mozilla or Google engineer will be able to work on #5152 given what's going on in the world, but I expect it only requires relatively minor modifications to Launcher.js. @corford Would you like to take a stab at it?

@corford
Copy link
Author

corford commented Mar 29, 2020

@mjzffr I dug in a bit more this weekend and actually it seems puppeteer.connect() already supports connecting to a running Firefox nightly instance (I was able to confirm this by checking the Launcher.js code then running Firefox nightly with --remote-debugger and successfully connecting to it with puppeteer.connect()). Given this, I'm not sure what lack of support #5152 is referring to (the issue doesn't give much info).

After confirming the above, I was able to load an FF extension:

const child_process = require('child_process');
const getPort = require('get-port');
const webExt = require('web-ext').default;
const pptr = require('puppeteer-core');

(async () => {
  const CDPPort = await getPort();
  const args = ['--headless', `--remote-debugger=localhost:${CDPPort}`];
  await webExt.cmd.run(
      {
        sourceDir: '/path/to/add-on',
        firefox: '/opt/firefox/firefox-bin',
        args: args
      },
      {
        shouldExitProgram: false
      }
    );
    
    // Needed because `webExt.cmd.run` returns before the DevTools agent starts running.
    // Alternative would be to wrap the call to pptr.connect() with some custom retry logic
    child_process.execSync('sleep 5');

    const browserURL = `http://localhost:${CDPPort}`;
    browser = await pptr.connect({
      browserURL
    });
})();

@mjzffr
Copy link
Contributor

mjzffr commented Mar 31, 2020

@corford That's great.

It's entirely possible that the previous fixes to puppeteer.launch took care of #5152 -- the issue was more of a to-do than a bug report. Indeed, the related unit tests do pass for Firefox.

As for avoiding the sleep: I'm not familiar with web-ext, but puppeteer.launch gets around this by parsing stderr output of the ChildProcess for the ws url.

@lfilho
Copy link

lfilho commented Jun 13, 2020

Hey @corford and @mjzffr the above is not working for me for some reason.

Could you kindly check #6016 out?

Thank you very much

@alexanderby
Copy link

@corford The proposed solution doesn't work, because

  1. --remote-debugger flag has no effect, FF starts on a port it wants.
  2. socket hang up error when connecting Puppeteer.

@mjzffr
Copy link
Contributor

mjzffr commented Oct 9, 2020

Try --remote-debugging-port. It will use port 9222 by default, or you can specify a port number.

@alexanderby
Copy link

@mjzffr Thanks for the suggestion. I think it ignores this flag. When adding webExt.util.logger.consoleStream.makeVerbose(); it logs Firefox args: -start-debugger-server 64496 -foreground -no-remote -profile /var/folders/dz/f75ytxz11m18cxh5xpy6c3kc0000gn/T/cc2ffe71-2b89-4c23-9ff7-d47d317a330b --remote-debugging-port=1234. So -start-debugger-server 64496 specifies the port to use.

@mjzffr
Copy link
Contributor

mjzffr commented Oct 9, 2020

@alexanderby I'm not sure I understand where you're trying to pass --remote-debugging-port.

What I meant is you should start Firefox Nightly with --remote-debugging-port then use the above script to connect to the already running browser binary. This will start the server that is compatible with Puppeteer.

The Firefox options are confusing: -start-debugger-server starts the Firefox DevTools server, which is a different component/protocol entirely and is not relevant to Puppeteer.

@alexanderby
Copy link

alexanderby commented Oct 9, 2020

@mjzffr Here's a code example #6498
I tried passing the option in web-ext args:

const path = require('path');
const puppeteer = require('puppeteer-core');
const webExt = require('web-ext');

async function openFirefox() {
    webExt.util.logger.consoleStream.makeVerbose();
    const PORT = 1234;
    const runner = await webExt.cmd.run({
        sourceDir: path.join(__dirname, 'extension'),
        firefox: {
            'darwin': '/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin',
            'win32': `${process.env.PROGRAMFILES}\\Firefox Nightly\\firefox.exe`,
        }[process.platform],
        args: [`--remote-debugging-port=${PORT}`]
    }, {
        shouldExitProgram: false,
    });
    const {debuggerPort} = runner.extensionRunners[0].runningInfo;
    console.log(debuggerPort);
    return await puppeteer.connect({
        browserWSEndpoint: `ws://localhost:${PORT}`,

    });
}

But it just starts the debugger on it's own port, the specified one is not available (connect ECONNREFUSED 127.0.0.1:1234).

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

No branches or pull requests

5 participants