<divrole="region"><ahref="#"class="skipToContent_fXgn">Skip to main content</a></div><navclass="navbar navbar--fixed-top"><divclass="navbar__inner"><divclass="navbar__items"><buttonaria-label="Navigation bar toggle"class="navbar__toggle clean-btn"type="button"tabindex="0"><svgwidth="30"height="30"viewBox="0 0 30 30"aria-hidden="true"><pathstroke="currentColor"stroke-linecap="round"stroke-miterlimit="10"stroke-width="2"d="M4 7h22M4 15h22M4 23h22"></path></svg></button><aclass="navbar__brand"href="/puppeteer/"><divclass="navbar__logo"><imgsrc="https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png"alt="Puppeteer Logo"class="themedImage_ToTc themedImage--light_HNdA"><imgsrc="https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png"alt="Puppeteer Logo"class="themedImage_ToTc themedImage--dark_i4oU"></div><bclass="navbar__title text--truncate">Puppeteer</b></a></div><divclass="navbar__items navbar__items--right"><aaria-current="page"class="navbar__item navbar__link navbar__link--active"href="/puppeteer/">Next</a><divclass="searchBox_ZlJk"><divclass="navbar__search searchBarContainer_NW3z"><inputplaceholder="Search"aria-label="Search"class="navbar__search-input"><divclass="loadingRing_RJI3 searchBarLoadingRing_YnHq"><div></div><div></div><div></div><div></div></div><divclass="searchHintContainer_Pkmr"><kbdclass="searchHint_iIMx">ctrl</kbd><kbdclass="searchHint_iIMx">K</kbd></div></div></div><divclass="toggle_vylO colorModeToggle_DEke"><buttonclass="clean-btn toggleButton_gllP toggleButtonDisabled_aARS"type="button"disabled=""title="Switch between dark and light mode (currently light mode)"aria-label="Switch between dark and light mode (currently light mode)"><svgviewBox="0 0 24 24"width="24"height="24"class="lightToggleIcon_pyhR"><pathfill="currentColor"d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svgviewBox="0 0 24 24"width="24"height="24"class="darkToggleIcon_wfgR"><pathfill="currentColor"d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg></button></div></div></div><divrole="presentation"class="navbar-sidebar__backdrop"></div></nav><divclass="main-wrapper docsWrapper_BCFX"><buttonaria-label="Scroll back to top"class="clean-btn theme-back-to-top-button backToTopButton_sjWU"type="button"></button><divclass="docPage__5DB"><asideclass="theme-doc-sidebar-container docSidebarContainer_b6E3"><divclass="sidebar_njMd"><navclass="menu thin-scrollbar menu_SIkG"><ulclass="theme-doc-sidebar-menu menu__list"><liclass="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><aclass="menu__link"href="/puppeteer/">Puppeteer</a></li><liclass="theme-doc-sidebar-item-linktheme-doc-sidebar-item-lin
See our <ahref="https://puppeteer.github.io/puppeteer/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://puppeteer.github.io/puppeteer/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-js codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-js codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token keyword control-flow"style="color:#00009f">await</span><spanclass="token plain"> page</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token method function property-access"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 arrow 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"></span><spanclass="token dom variable"style="color:#36acaa">document</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token method function property-access"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 method function property-access"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">}<