See our <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://pptr.dev/api/puppeteer.puppeteernode.launch"target="_blank"rel="noopener noreferrer"><code>puppeteer.launch({product: 'firefox'})</code></a> to run your Puppeteer scripts in Firefox Nightly, without any additional custom patches. While <ahref="https://www.npmjs.com/package/puppeteer-firefox"target="_blank"rel="noopener noreferrer">an older experiment</a> required a patched version of Firefox, <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 wit
Aside from regular navigation where the browser hits the network to fetch a new document from the web server, this includes <ahref="https://www.w3.org/TR/html5/single-page.html#scroll-to-fragid"target="_blank"rel="noopener noreferrer">anchor navigations</a> 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 <ahref="https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted"target="_blank"rel="noopener noreferrer"><code>Event.isTrusted</code></a> 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></