<ahref="https://pptr.dev/contributing"target="_blank"rel="noopener noreferrer">contributing guide</a>.</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="q-what-is-the-status-of-cross-browser-support">Q: What is the status of cross-browser support?<aclass="hash-link"href="#q-what-is-the-status-of-cross-browser-support"title="Direct link to heading"></a></h2><p>Official Firefox support is currently 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.</p><p>From Puppeteer v2.1.0 onwards you can specify
<ahref="https://wiki.mozilla.org/Remote"target="_blank"rel="noopener noreferrer">the current approach</a> works with “stock”
Firefox.</p><p>We will 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).</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="q-what-are-puppeteers-goals-and-principles">Q: What are Puppeteer’s goals and principles?<aclass="hash-link"href="#q-what-are-puppeteers-goals-and-principles"title="Direct link to heading"></a></h2><p>The goals of the project are:</p><ul><li>Provide a slim, canonical library that highlights the capabilities of the
<ahref="https://chromedevtools.github.io/devtools-protocol/"target="_blank"rel="noopener noreferrer">DevTools Protocol</a>.</li><li>Provide a reference implementation for similar testing libraries. Eventually,
these other frameworks could adopt Puppeteer as their foundational layer.</li><li>Grow the adoption of headless/automated browser testing.</li><li>Help dogfood new DevTools Protocol features...and catch bugs!</li><li>Learn more about the pain points of automated browser testing and help fill
those gaps.</li></ul><p>We adapt
<ahref="https://www.chromium.org/developers/core-principles"target="_blank"rel="noopener noreferrer">Chromium principles</a> to
help us drive product decisions:</p><ul><li><strong>Speed</strong>: Puppeteer has almost zero performance overhead over an automated
page.</li><li><strong>Security</strong>: Puppeteer operates off-process with respect to Chromium, making
it safe to automate potentially malicious pages.</li><li><strong>Stability</strong>: Puppeteer should not be flaky and should not leak memory.</li><li><strong>Simplicity</strong>: Puppeteer provides a high-level API that’s easy to use,
understand, and debug.</li></ul><h2class="anchor anchorWithStickyNavbar_LWe7"id="q-is-puppeteer-replacing-seleniumwebdriver">Q: Is Puppeteer replacing Selenium/WebDriver?<aclass="hash-link"href="#q-is-puppeteer-replacing-seleniumwebdriver"title="Direct link to heading"></a></h2><p><strong>No</strong>. Both projects are valuable for very different reasons:</p><ul><li>Selenium/WebDriver focuses on cross-browser automation; its value proposition
is a single standard API that works across all major browsers.</li><li>Puppeteer focuses on Chromium; its value proposition is richer functionality
and higher reliability.</li></ul><p>That said, you <strong>can</strong> use Puppeteer to run tests against Chromium, e.g. using
the community-driven
<ahref="https://github.com/smooth-code/jest-puppeteer"target="_blank"rel="noopener noreferrer">jest-puppeteer</a>. While this
probably shouldn’t be your only testing solution, it does have a few good points
compared to WebDriver:</p><ul><li>Puppeteer requires zero setup and comes bundled with the Chromium version it
works best with, making it
<ahref="https://github.com/puppeteer/puppeteer/#getting-started"target="_blank"rel="noopener noreferrer">very easy to start with</a>.
At the end of the day, it’s better to have a few tests running chromium-only,
than no tests at all.</li><li>Puppeteer has event-driven architecture, which removes a lot of potential
flakiness. There’s no need for evil “sleep(1000)” calls in puppeteer scripts.</li><li>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.</li><li>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.</li></ul><h2class="anchor anchorWithStickyNavbar_LWe7"id="q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy">Q: Why doesn’t Puppeteer v.XXX work with Chromium v.YYY?<aclass="hash-link"href="#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy"title="Direct link to heading"></a></h2><p>We see Puppeteer as an <strong>indivisible entity</strong> with Chromium. Each version of
Puppeteer bundles a specific version of Chromium –<strong>the only</strong> version it is
guaranteed to work with.</p><p>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:</p><ul><li>A Puppeteer bug is reported:
<ahref="https://github.com/puppeteer/puppeteer/issues/2709"target="_blank"rel="noopener noreferrer">https://github.com/puppeteer/puppeteer/issues/2709</a></li><li>It turned out this is an issue with the DevTools protocol, so we’re fixing it
in Chromium: <ahref="https://chromium-review.googlesource.com/c/chromium/src/+/1102154"target="_blank"rel="noopener noreferrer">https://chromium-review.googlesource.com/c/chromium/src/+/1102154</a></li><li>Once the upstream fix is landed, we roll updated Chromium into Puppeteer:
<ahref="https://github.com/puppeteer/puppeteer/pull/2769"target="_blank"rel="noopener noreferrer">https://github.com/puppeteer/puppeteer/pull/2769</a></li></ul><p>However, oftentimes it is desirable to use Puppeteer with the official Google
Chrome rather than Chromium. For this to work, you should install a
<code>puppeteer-core</code> version that corresponds to the Chrome version.</p><p>For example, in order to drive Chrome 71 with puppeteer-core, use <code>chrome-71</code>
npm tag:</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token function"style="color:#d73a49">npm</span><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">install</span><spanclass="token plain"> puppeteer-core@chrome-71</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2class="anchor anchorWithStickyNavbar_LWe7"id="q-which-chromium-version-does-puppeteer-use">Q: Which Chromium version does Puppeteer use?<aclass="hash-link"href="#q-which-chromium-version-does-puppeteer-use"title="Direct link to heading"></a></h2><p>Find the version using one of the following ways:</p><ul><li>Look for the <code>chromium</code> entry in
which contains mapping between Chromium and the smallest Puppeteer version
that supports it.</li></ul><h2class="anchor anchorWithStickyNavbar_LWe7"id="q-which-firefox-version-does-puppeteer-use">Q: Which Firefox version does Puppeteer use?<aclass="hash-link"href="#q-which-firefox-version-does-puppeteer-use"title="Direct link to heading"></a></h2><p>Since Firefox support is experimental, Puppeteer downloads the latest
<ahref="https://wiki.mozilla.org/Nightly"target="_blank"rel="noopener noreferrer">Firefox Nightly</a> when the <code>PUPPETEER_PRODUCT</code>
environment variable is set to <code>firefox</code>. That's also why the value of <code>firefox</code>
is <code>latest</code> -- Puppeteer isn't tied to a particular Firefox version.</p><p>To fetch Firefox Nightly as part of Puppeteer installation:</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token assign-left variable"style="color:#36acaa">PUPPETEER_PRODUCT</span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain">firefox </span><spanclass="token function"style="color:#d73a49">npm</span><spanclass="token plain"> i puppeteer</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token comment"style="color:#999988;font-style:italic"># or "yarn add puppeteer"</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4class="anchor anchorWithStickyNavbar_LWe7"id="q-whats-considered-a-navigation">Q: What’s considered a “Navigation”?<aclass="hash-link"href="#q-whats-considered-a-navigation"title="Direct link to heading"></a></h4><p>From Puppeteer’s standpoint, <strong>“navigation” is anything that changes a page’s
URL</strong>. Aside from regular navigation where the browser hits the network to fetch
and <ahref="https://developer.mozilla.org/en-US/docs/Web/API/History_API"target="_blank"rel="noopener noreferrer">History API</a>
usage.</p><p>With this definition of “navigation,” <strong>Puppeteer works seamlessly with
single-page applications.</strong></p><h4class="anchor anchorWithStickyNavbar_LWe7"id="q-whats-the-difference-between-a-trusted-and-untrusted-input-event">Q: What’s the difference between a “trusted" and "untrusted" input event?<aclass="hash-link"href="#q-whats-the-difference-between-a-trusted-and-untrusted-input-event"title="Direct link to heading"></a></h4><p>In browsers, input events could be divided into two big groups: trusted vs.
untrusted.</p><ul><li><strong>Trusted events</strong>: events generated by users interacting with the page, e.g.
using a mouse or keyboard.</li><li><strong>Untrusted event</strong>: events generated by Web APIs, e.g. <code>document.createEvent</code>
or <code>element.click()</code> methods.</li></ul><p>Websites can distinguish between these two groups:</p><ul><li>using an
event flag</li><li>sniffing for accompanying events. For example, every trusted <code>'click'</code> event
is preceded by <code>'mousedown'</code> and <code>'mouseup'</code> events.</li></ul><p>For automation purposes it’s important to generate trusted events. <strong>All input
events generated with Puppeteer are trusted and fire proper accompanying
events.</strong> If, for some reason, one needs an untrusted event, it’s always
possible to hop into a page context with <code>page.evaluate</code> and generate a fake
event:</p><divclass="language-ts codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-ts codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token keyword"style="color:#00009f">await</span><spanclass="token plain"> page</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token function"style="color:#d73a49">evaluate</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token plain"></span><spanclass="token operator"style="color:#393A34">=></span><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> document</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token function"style="color:#d73a49">querySelector</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token string"style="color:#e3116c">'button[type=submit]'</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token function"style="color:#d73a49">click</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">;</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">}</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">;</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4class="anchor anchorWithStickyNavbar_LWe7"id="q-what-features-does-puppeteer-not-support">Q: What features does Puppeteer not support?<aclass="hash-link"href="#q-what-features-does-puppeteer-not-support"title="Direct link to heading"></a></h4><p>You may find that Puppeteer does not behave as expected when controlling pages
that incorporate audio and video. (For example,
<ahref="https://github.com/puppeteer/puppeteer/issues/291"target="_blank"rel="noopener noreferrer">video playback/screenshots is likely to fail</a>.)
There are two reasons for this:</p><ul><li>Puppeteer is bundled with Chromium — not Chrome — and so by default, it
You should only use this configuration if you need an official release of
Chrome that supports these media formats.)</li><li>Since Puppeteer (in all configurations) controls a desktop version of
Chromium/Chrome, features that are only supported by the mobile version of
Chrome are not supported. This means that Puppeteer
<ahref="https://caniuse.com/#feat=http-live-streaming"target="_blank"rel="noopener noreferrer">does not support HTTP Live Streaming (HLS)</a>.</li></ul><h4class="anchor anchorWithStickyNavbar_LWe7"id="q-i-am-having-trouble-installing--running-puppeteer-in-my-test-environment-where-should-i-look-for-help">Q: I am having trouble installing / running Puppeteer in my test environment. Where should I look for help?<aclass="hash-link"href="#q-i-am-having-trouble-installing--running-puppeteer-in-my-test-environment-where-should-i-look-for-help"title="Direct link to heading"></a></h4><p>We have a
guide for various operating systems that lists the required dependencies.</p><h4class="anchor anchorWithStickyNavbar_LWe7"id="q-chromium-gets-downloaded-on-every-npm-ci-run-how-can-i-cache-the-download">Q: Chromium gets downloaded on every <code>npm ci</code> run. How can I cache the download?<aclass="hash-link"href="#q-chromium-gets-downloaded-on-every-npm-ci-run-how-can-i-cache-the-download"title="Direct link to heading"></a></h4><p>The default download path is <code>node_modules/puppeteer/.local-chromium</code>. However,
you can change that path with the <code>PUPPETEER_DOWNLOAD_PATH</code> environment
variable.</p><p>Puppeteer uses that variable to resolve the Chromium executable location during
launch, so you don’t need to specify <code>PUPPETEER_EXECUTABLE_PATH</code> as well.</p><p>For example, if you wish to keep the Chromium download in <code>~/.npm/chromium</code>:</p><divclass="language-sh codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-sh codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">export PUPPETEER_DOWNLOAD_PATH=~/.npm/chromium</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">npm ci</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># by default the Chromium executable path is inferred</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># from the download path</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">npm test</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># a new run of npm ci will check for the existence of</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Chromium in ~/.npm/chromium</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">npm ci</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4class="anchor anchorWithStickyNavbar_LWe7"id="q-i-have-more-questions-where-do-i-ask">Q: I have more questions! Where do I ask?<aclass="hash-link"href="#q-i-have-more-questions-where-do-i-ask"title="Direct link to heading"></a></h4><p>There are many ways to get help on Puppeteer:</p><ul><li><ahref="https://github.com/puppeteer/puppeteer/issues"target="_blank"rel="noopener noreferrer">bugtracker</a></li><li><ahref="https://stackoverflow.com/questions/tagged/puppeteer"target="_blank"rel="noopener noreferrer">Stack Overflow</a></li></ul><p>Make sure to search these channels before posting your question.</p></div></article><navclass="pagination-nav docusaurus-mt-lg"aria-label="Docs pages navigation"><aclass="pagination-nav__link pagination-nav__link--prev"href="/next/guides/request-interception"><divclass="pagination-nav__sublabel">Previous</div><divclass="pagination-nav__label">Request Interception</div></a><aclass="pagination-nav__link pagination-nav__link--next"href="/next/troubleshooting"><divclass="pagination-nav__sublabel">Next</div><divclass="pagination-nav__label">Troubleshooting</div></a></nav></div></div><divclass="col col--3"><divclass="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ulclass="table-of-contents table-of-contents__left-border"><li><ahref="#q-who-maintains-puppeteer"class="table-of-contents__link toc-highlight">Q: Who maintains Puppeteer?</a></li><li><ahref="#q-what-is-the-status-of-cross-browser-support"class="table-of-contents__link toc-highlight">Q: What is the status of cross-browser support?</a></li><li><ahref="#q-what-are-puppeteers-goals-and-principles"class="table-of-contents__link toc-highlight">Q: What are Puppeteer’s goals and principles?</a></li><li><ahref="#q-is-puppeteer-replacing-seleniumwebdriver"class="table-of-contents__link toc-highlight">Q: Is Puppeteer replac