Frequently asked questions

What is the status of cross-browser support?

Official Firefox support is experimental. The ongoing collaboration with Mozilla aims to support common end-to-end testing use cases, for which developers expect cross-browser coverage. The Puppeteer team needs input from users to stabilize Firefox support and to bring missing APIs to our attention.

From Puppeteer v2.1.0 onwards you can specify puppeteer.launch({product: 'firefox'}) to run your Puppeteer scripts in Firefox Nightly, without any additional custom
patches. While an older experiment required a patched version of Firefox, the current approach works with "stock" Firefox.

We continue to collaborate with other browser vendors to bring Puppeteer support to browsers, such as Safari. This effort includes exploration of a standard for executing cross-browser commands (instead of relying on the non-standard DevTools Protocol used by Chrome).

What are Puppeteer's goals and principles?

The goals of the project are:

  • Provide a slim, canonical library that highlights the capabilities of the DevTools Protocol.
  • Provide a reference implementation for similar testing libraries. Eventually, these other frameworks could adopt Puppeteer as their foundational layer.
  • Grow the adoption of headless/automated browser testing.
  • Help dogfood new DevTools Protocol features...and catch bugs!
  • Learn more about the pain points of automated browser testing and help fill those gaps.

We adapt Chromium principles to help us drive product decisions:

  • Speed: Puppeteer has almost zero performance overhead over an automated page.
  • Security: Puppeteer operates off-process with respect to Chromium, making it safe to automate potentially malicious pages.
  • Stability: Puppeteer should not be flaky and should not leak memory.
  • Simplicity: Puppeteer provides a high-level API that's easy to use, understand, and debug.

Is Puppeteer replacing Selenium/WebDriver?

No. Both projects are valuable for very different reasons:

  • Selenium/WebDriver focuses on cross-browser automation; its value proposition is a single standard API that works across all major browsers.
  • Puppeteer focuses on Chromium; its value proposition is richer capabilities and higher reliability.

That said, you can use Puppeteer to run tests against Chromium, such as using the community-driven jest-puppeteer. While this probably shouldn't be your only testing solution, it does have a few good points compared to WebDriver:

  • Puppeteer requires zero setup and comes bundled with the Chromium version it works best with. It's better to have a few tests running Chromium-only, than no tests at all.
  • Puppeteer has event-driven architecture, which removes a lot of potential flakiness. There's no need for evil "sleep(1000)" calls in puppeteer scripts.
  • Puppeteer runs headless by default, which makes it fast to run. Puppeteer v1.5.0 also exposes browser contexts, making it possible to efficiently parallelize test execution.
  • Puppeteer shines when it comes to debugging: flip the "headless" bit to false, add "slowMo", and you'll see what the browser is doing. You can even open Chrome DevTools to inspect the test environment.

Why doesn't Puppeteer v.XXX work with Chromium v.YYY?

We see Puppeteer as an indivisible entity with Chromium. Each version of Puppeteer bundles a specific version of Chromium – the only version it's guaranteed to work with.

This is not an artificial constraint. A lot of work on Puppeteer is actually taking place in the Chromium repository. Here's a typical story:

  1. A Puppeteer bug is reported
  2. This is an issue with the DevTools protocol, so we fix it in Chromium
  3. Once the upstream fix lands, we roll updated Chromium into Puppeteer

However, oftentimes it's desirable to use Puppeteer with the official Google Chrome rather than Chromium. For this to work, you should install a puppeteer-core version that corresponds to the Chrome version.

For example, in order to drive Chrome 101 with puppeteer-core, use chrome-101 npm tag:

npm install puppeteer-core@chrome-101

Which Chromium version does Puppeteer use?

Find the version using one of the following ways:

  • Look for the chromium entry in revisions.ts. To find the corresponding Chromium commit and version number, search for the revision prefixed by an r in OmahaProxy's "Find Releases" section.
  • Look for the versionsPerRelease map in versions.js which contains mapping between Chromium and Puppeteer versions. Note: The file contains only Puppeteer versions where Chromium is updated. Not all Puppeteer versions are listed.

Which Firefox version does Puppeteer use?

Since Firefox support is experimental, Puppeteer downloads the latest Firefox Nightly when the PUPPETEER_PRODUCT environment variable is set to firefox. That's also why the value of firefox in revisions.ts is latest -- Puppeteer isn't tied to a particular Firefox version.

To fetch Firefox Nightly as part of Puppeteer installation:

PUPPETEER_PRODUCT=firefox npm i puppeteer
# or "yarn add puppeteer"

What's considered a navigation?

From Puppeteer's standpoint, "navigation" is anything that changes a page's URL. Aside from regular navigation where the browser hits the network to fetch a new document from the web server, this includes anchor navigations and History API usage.

With this definition of "navigation," Puppeteer works seamlessly with single-page applications.

What's the difference between a "trusted" and "untrusted" input event?

In browsers, input events could be divided into two big groups: trusted versus untrusted.

  • Trusted events: events generated by users interacting with the page, such as using a mouse or keyboard.
  • Untrusted event: events generated by Web APIs, such as document.createEvent or element.click() methods.

Websites can distinguish between these two groups:

  • using an Event.isTrusted event flag
  • sniffing for accompanying events. For example, every trusted 'click' event is preceded by 'mousedown' and 'mouseup' events.

For automation purposes it's important to generate trusted events. All input events generated with Puppeteer are trusted and fire proper accompanying events.

If, for some reason, one needs an untrusted event, it's always possible to go into a page context with page.evaluate and generate a fake event:

await page.evaluate(() => {
  document.querySelector('button[type=submit]').click();
});

What features does Puppeteer not support?

You may find that Puppeteer does not behave as expected when controlling pages that incorporate audio and video. For example, video playback and screenshots are likely to fail.) There are two reasons for this:

  • Puppeteer is bundled with Chromium (not Chrome). So by default, it inherits all of Chromium's media-related limitations. This means that Puppeteer doesn't support licensed formats such as AAC or H.264.
    • It's possible to force Puppeteer to use a separately-installed version Chrome instead of Chromium with the executablePath option to puppeteer.launch. You should only use this configuration if you need an official release of Chrome that supports these media formats.
  • Since Puppeteer (in all configurations) controls a desktop version of Chromium or Chrome, features that are only supported by the mobile version of Chrome are not supported. This means that Puppeteer doesn't support HTTP Live Streaming (HLS).

I'm having trouble installing / running Puppeteer in my test environment. Where should I look for help?

We have a troubleshooting guide for various operating systems that lists the required dependencies.

Chromium gets downloaded on every npm ci run. How can I cache the download?

The default download path is node_modules/puppeteer/.local-chromium. However, you can change that path with the PUPPETEER_DOWNLOAD_PATH environment variable.

Puppeteer uses that variable to resolve the Chromium executable location during launch, so you don't need to specify PUPPETEER_EXECUTABLE_PATH as well.

For example, to keep the Chromium download in ~/.npm/chromium:

export PUPPETEER_DOWNLOAD_PATH=~/.npm/chromium
npm ci

# by default the Chromium executable path is inferred
# from the download path
npm test

# a new run of npm ci will check for the existence of
# Chromium in ~/.npm/chromium
npm ci

I have more questions! Where do I ask?

There are many ways to get help on Puppeteer:

Make sure to search these channels before posting your question.