
Prototype: Puppeteer for Firefox - amjd
https://github.com/GoogleChrome/puppeteer/tree/master/experimental/puppeteer-firefox
======
SideburnsOfDoom
In case you're wondering, and the linked page doesn't explain:

> Puppeteer is a Node library which provides a high-level API to control
> headless Chrome or Chromium over the DevTools Protocol. It can also be
> configured to use full (non-headless) Chrome or Chromium.

[https://developers.google.com/web/tools/puppeteer/](https://developers.google.com/web/tools/puppeteer/)

~~~
Gipetto
Thank you. This industry has a huge failure mode in touting tech used in
projects/frameworks without linking out to at least the source so that someone
can learn about them. Can't tell you how many things I've bailed on because it
was a pile of obscure library references that weren't (to me) worth looking
up.

~~~
couchand
To be fair, in this case the linked page is a subdirectory of the main
Puppeteer project.

~~~
kaycebasques
This is also an experimental project. Who here thoroughly documents their
experiments? Although to be fair we did announce it at I/O so that calls for
more documentation.

Disclosure: Chrome DevTools docs guy

------
mintplant
Huh. I worked on exactly this idea as a Mozilla intern in 2017. I wrote a
collection of Rust crates (mentioned in [0]) comprising auto-generated types
for all Chrome DevTools Protocol messages [1], (de)serialization, and a server
lib to handle both the initial HTTP handshake and subsequent command execution
over WebSockets. I used that to build out an initial CDP server inside Firefox
(and Servo) with support for a couple of sample commands.

At the end of the internship I handed over everything I'd built by that point,
with the idea that they (Mozilla) would turn it into a finished project. But I
never saw any activity on that front after I left, so I assumed the idea'd
been scrapped. Feels very weird seeing this pop up out of the blue on HN
today.

[0]
[https://bugzilla.mozilla.org/show_bug.cgi?id=1523104#c1](https://bugzilla.mozilla.org/show_bug.cgi?id=1523104#c1)

[1] Complete with documentation comment generation; I found the result of
running rustdoc over that crate super useful as an alternative to the official
CDP docs site: [https://www.spinda.net/files/mozilla/rust-
cdp/doc/cdp/index....](https://www.spinda.net/files/mozilla/rust-
cdp/doc/cdp/index.html)

~~~
kaycebasques
There’s a lot of debate between the browser vendors and automation tools
around whether the Chrome DevTools Protocol is the right abstraction layer to
focus browser automation around. It’s a nuanced topic and if you dig into it
you’ll see that all the different sides make good arguments. My guess is that
this debate stalled your project. I’m putting myself out here on the topic
because having a coherent and enjoyable cross-browser integration testing
story would be a huge win for the web at large and it’s something worth making
people aware of in the hopes that we can find common ground.

Edit: I actually have no right to comment on what stalled your project and
have no idea what happened there. I just wanted to discuss the fact that we
need a good abstraction layer but seem stuck in debate.

Disclosure: Chrome DevTools docs guy, just speaking personally based on my
research into the topic over the last year

~~~
mintplant
No need to apologize, I appreciate your perspective. That was my assumption as
well at the time - that the debate had shifted the other way and CDP support
fell off of the priority list.

------
eknkc
It is kind of usable but is still missing stuff. You can check the status
here:
[https://aslushnikov.github.io/ispuppeteerfirefoxready/](https://aslushnikov.github.io/ispuppeteerfirefoxready/)

------
felixfbecker
We're using it to test our browser extension at Sourcegraph in both Firefox
and Chrome:
[https://github.com/sourcegraph/sourcegraph/blob/master/brows...](https://github.com/sourcegraph/sourcegraph/blob/master/browser/src/e2e/e2e.test.ts)

------
nealrs
Tangentially related => I used ffmpeg + puppeteer to build StoryScroll
[https://neal.rs/app](https://neal.rs/app), which turns blog posts into
scrolling videos for social media.

I also used to build a desktop app that my team uses to download Alexa Flash
Briefing metrics (because there's no API for that)

Puppeteer's full-screen screenshots & DOM manipulation abilities are clutch!!

------
sebazzz
For automated testing, why Puppeteer instead of Selenium?

~~~
d33
Much better access to low-level information. You can hook (and mock) requests,
see what POST data was sent and basically do lots of magic. Also, my
experience with Selenium under Python is that doing anything bigger quickly
turns into one giant timing hack.

~~~
HunOL
If it really E2E from user perspective you shouldn't doing any magic and
manipulate POST data.

~~~
danShumway
You're not technically wrong, but unit/integration/E2E are not hard categories
for tests, they're just points along a continuum.

Sometimes I want to directly control a browser to run a test or examine a UI
component, but I still want to mock parts of my application. This is one of
the biggest weaknesses with Selenium -- it takes a very narrow view of what
testing is, so it becomes much less useful as soon as you're trying to do
anything interesting.

Different applications call for different testing strategies. Selenium could
be a low-level browser controller that _allows_ you to write strict E2E tests,
but instead it's a low-level browser controller that is almost fanatical about
only supporting strict E2E tests, even when it means that basic actions need
to be more complicated. I think that's a design mistake, but whatever.

~~~
bluntfang
>This is one of the biggest weaknesses with Selenium -- it takes a very narrow
view of what testing is

Selenium/WebDriver isn't a testing tool. It's a a W3C protocol for remote
control of web browsers. I think once you get over that misconception,
selenium starts to make a lot more sense.

~~~
danShumway
That still doesn't explain to me design decisions like how WebDriver's file
upload works.

If I'm remote-controlling a browser over a network, wouldn't I occasionally
want to send it an arbitrary file upload? Why do I need to separately transfer
the file using a different service, and then refer to it with the disk path?

The only reason I can think of is, "normal users couldn't do that." But normal
users also can't control a browser over a network. There's no reason to
restrict a control protocol to only things that normal users can do.

~~~
bluntfang
>There's no reason to restrict a control protocol to only things that normal
users can do.

The selenium maintainers seem to have a very strong opposite opinion.

------
kaycebasques
We announced this at Google I/O 2019 and mentioned it in What’s New In
DevTools (Chrome 76):
[https://developers.google.com/web/updates/2019/05/devtools#p...](https://developers.google.com/web/updates/2019/05/devtools#puppeteer)

------
digitarald
For anybody who wants to follow along, the Firefox work is tracked here:
[https://gitter.im/webhintio/Firefox](https://gitter.im/webhintio/Firefox)

The experiment was a great start to see what is needed to support Puppeteer.
The next step is coming up with a well-integrated architecture. Find me on the
web to talk to me about your use cases and ideas for Puppeteer.

~~~
digitarald
Actual link:
[https://bugzilla.mozilla.org/show_bug.cgi?id=1545057](https://bugzilla.mozilla.org/show_bug.cgi?id=1545057)

------
tnolet
Anyone who wants to play around with some Puppeteer examples, I built
[https://puppeteersandbox.com](https://puppeteersandbox.com).

If you want to record your own scripts, I also am actively developing
[https://checklyhq.com/Puppeteer-recorder](https://checklyhq.com/Puppeteer-
recorder), a Chrome extension.

~~~
folkhack
That second link is a 404, although I love your 404 page GIF =)

Checkly looks like a great product!

~~~
tnolet
Thanks, building a SaaS is 99% getting the 404 pages right!

------
rehemiau
How is the DevTools/Remote protocol better (or worse) than WebDriver prptocol
for integration testing?

~~~
nicoburns
It's much more reliable.

~~~
Congeec
How? With selenium I have a case that WebElement.click() fails but it doesn’t
throw. Also Select(...).select_by_visible_text() throws WebDriverException,
StaleElementException, etc even if you WebDriverWait()’d for it to be
available. To me these show selenium is unreliable. How puppeteer is reliable
pertaining to these cases?

~~~
zelo
It's probably because in the meantime dom nodes has been replaced by new ones.

Selenium has it's quirks but when you understand how it works and it's
limitations and user centric philosophy there is nothing that can stop you
from writing rock solid stable tests.

~~~
Congeec
Sorry I didn't defined the problems clearly and thank your for your help. I am
using selenium using python for web automation, not testing. The latter
problem was by and large solved by subclassing WebDriverWait by adding common
Exceptions related to nodes staleness. The former problem was tackled by
writing a for loop detecting changes of the context to know if
WebElement.click() fails silently.

The thing is I have to write these workarounds everywhere. What's more, I
inject javascript code a lot to avoid nodes staleness caused by network
latency. I believe selenium is not designed for writing lots of javascript.
And javascript code in a string of python can not be linted, which increases
debugging workload.

To this point, the cost of these hacks is too much in my project. I find
puppeteer play nicely with javascript after trying. But the difference and
reliability between waitFor() in puppeteer and WebDriverWait() in selenium
still remain questionable.

I am wondering if using puppeteer can ease pains mentioned above.

~~~
zelo
Selenium for sure doesn't fit in your use case then :). I pointed "user-
centric approach" because selenium focuses on allowing only things normal user
could do in normal user way which is limiting for automation but it's a
blessing if you want to look as close to the real user as you can. I worked on
solving google ReCaptcha v2/v3 at bigger scale and it's been a solid
advantage.

> And javascript code in a string of python can not be linted, which increases
> debugging workload.

If you use PyCharm or any other JetBrains IDE you can use `Language
Injections` [0]

> I am wondering if using puppeteer can ease pains mentioned above.

I'm not sure about puppeteer but Chrome DevTools Protocol [1] (I think this is
what puppeteer use under the hood, but I'm not sure) may be interesting for
you because it gives low level access to browser mechanisms like injecting
code before page load, request interception or separate browser contexts
between separate tabs.

[0] [https://www.jetbrains.com/help/pycharm/using-language-
inject...](https://www.jetbrains.com/help/pycharm/using-language-
injections.html)

[1] [https://chromedevtools.github.io/devtools-
protocol/](https://chromedevtools.github.io/devtools-protocol/)

~~~
Congeec
Thank you. The Language Injections feature amazes a vim user, though similar
limited plugin exists.

------
marmada
Has anyone else found Puppeteer to be very slow? I was using it to scrape a
webpage and found it to be much slower than Selenium.

~~~
floatingatoll
What is the use case you're trying out Puppeteer for?

~~~
marmada
Scraping all the posts from a Facebook group.

------
breatheoften
Puppeteer is really really good. I just discovered it and used it for
something and it’s a blast to work with.

I’m seriously thinking there is a cloud api play in the near future — a
puppeteer Page is a pretty awesome container format ... a Puppeteer Page or
BrowserContext per request would provide an awesome cloud-function-like
programming model I think...

~~~
anandchowdhary
I really like [https://microlink.io](https://microlink.io) for browser-based
automation.

------
world32
Nice work, I have been using puppeteer with chrome recently and it is a great
piece of kit. If the prototype is successful will you keep the chrome and
firefox packages separate or merge them and have an abstraction layer so
puppeteer can issue commands regardless of chrome/firefox being used for the
browser?

~~~
felixfbecker
They already have the same API

~~~
world32
Yeah, that doesn't answer my question though ;)

~~~
pawelmurias
Merging them in a single package gives you nothing at a significant price.
puppeteer = wantFox ? require('puppeteer-firefox') : require('puppeteer')

~~~
world32
Sure but now there are two separate codebases for the same API. A lot of code
will be duplicated between the two codebases, you'll have to maintain two sets
of issues on github etc.

If it were me I would aim to merge the firefox puppeteer into chrome puppeteer
but fair enough if they want to keep them separate.

EDIT: I guess it depends on how much of the code in the puppeteer chrome
codebase is tightly coupled to chrome dev tools. Like if 25% of specific to
chrome, then that would mean that 75% of the code can be shared between the
chrome implementation and the firefox one, in that case I think merging and
hiding the 25% chrome/firefox specific stuff behind an abstraction layer is
the best option.

------
thatwasunusual
This is nice work. Does anyone know if it's possible to enable reader view
"programatically", though?

~~~
fuzzy2
Sure, just go to `about:reader?url=whatever`

Or did you mean something else?

~~~
thatwasunusual
This is exactly what I'm after. Thanks a lot! :)

------
no_wizard
Looks like they’re quite far along in developing this according to this status
page

[https://aslushnikov.github.io/ispuppeteerfirefoxready/](https://aslushnikov.github.io/ispuppeteerfirefoxready/)

------
zserge
Huh. That's great news. Time to add Firefox support to Lorca lib, I guess.

------
fsiefken
is there a benefit to using firefox with puppeteer compared to chromium and
puppeteer? or is it just a matter of choice and being able to also use firefox
for automated testing?

~~~
pmontra
I run integration tests in Ruby on Rails with Capybara using both the Chrome
and Firefox drivers. That project was stopped for a while and when I went back
to it the Firefox driver didn't work anymore. I didn't have the time to check
what went wrong and fix it but I'm developing with Firefox anyway. I think
it's important to test with the major browsers. My customer didn't ask about
IE. I remember when I had a few VMs for that and its incompatible version tied
to a specific version of Windows.

~~~
fsiefken
Ah yes, browser compatibility! IE will soon be chromium-webkit based.

------
dxxvi
For what I see, puppeteer is very much like testcafe (able to run with
headless/full Firefox, Chrome, Edge ..., but testcafe doesn't need a custom-
built Firefox). TestCafe can run javascript code on the page and return the
data back, that means it can be used to get data in POST requests. It can take
screenshots too. If anybody is familiar with both tools, could you please what
this tool can do but the other cannot?

~~~
nostalgk
I have never heard of TestCafe, but I've used Puppeteer for a variety of
projects with Chrome. My latest one was using it to convert HTML files into
PDFs en masse.

~~~
mikepurvis
Is there an advantage to that approach over the more direct wkhtmltopdf?

~~~
royjacobs
It looks exactly like it would in the latest version of Chrome and is not
dependent on Qt's Webkit version.

------
kyriakos
How's pdf rendering in Firefox? Chrome headless has its issues with headers
and footers

~~~
mjepronk
It's good, however it's not possible to use the remote debugging protocol for
printing to PDF yet.

------
ldng
I was under the impression it was about to be retired ? Did something change ?

------
sbmthakur
What is the equivalent of Chrome Dev tools protocol here?

~~~
world32
It says its based on the mozilla remote protocol:
[https://wiki.mozilla.org/Remote](https://wiki.mozilla.org/Remote)

"The Firefox Remote Protocol is a low-level debugging interface based on the
CDP protocol."

------
pilaf
Weird that they'd pick a red panda for the logo.

------
blodovnik
Firefox has lost its lead because it's lost the developers.

Chrome has invested massively in developer tools for chrome and it's shows....
I think chrome is the best software ever written. The developer tools are so
powerful that it'd hard to even know the full breadth of what's in there.

Firefox offers nothing to developers over chrome, which is sad.

~~~
daveFNbuck
> Firefox offers nothing to developers over chrome, which is sad.

Firefox has multi-account containers. Having different tabs logged in to
different accounts is huge for me.

~~~
Bjartr
I use Chrome profiles to great effect.

~~~
daveFNbuck
Can't you only have one profile open at a time, and each one is linked to a
different Google account?

Firefox allows you to have each tab open in a different container, and they
don't have to be tied to anything in particular.

I can have different tabs open to the AWS console for each AWS account I use.
I can also switch tabs to change between different user accounts to test
interactions between users on the site I'm developing.

~~~
jamesgeck0
> Can't you only have one profile open at a time

No. Each profile opens in a new Chrome window. You can have as many open as
you'd like.

> and each one is linked to a different Google account?

No. Local profiles have always been a thing.

Chrome's implementation has better UX for privacy IMHO; it's harder to
accidentally open a tab in a different profile than expected, which I do _all
the time_ in Firefox. In Chrome, Cmd+T opens a new tab in the active profile.
In Firefox, Cmd+T opens a new tab in the default profile.

~~~
daveFNbuck
Yeah, the implementation could use some work. I also use the temporary
containers plugin so by default tabs open in new containers. I think this
gives better security than either of these defaults. If I need a site to open
up in a particular container, I can always set that too.

