{"componentChunkName":"component---src-templates-post-js","path":"/blog/2020/01/24/playwright/","result":{"data":{"post":{"html":"<p>If you’ve ever used <a href=\"https://github.com/puppeteer/puppeteer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Puppeteer</a>, you’d know it enables you to control a Chrome instance (or any other <strong>Chrome DevTools</strong> Protocol based browser) and execute common actions, much like in a real browser - programmatically, through a decent API. The same team has now build a new product called <a href=\"https://github.com/microsoft/playwright\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Playwright</a> which apparently is their new favourite.</p>\n<!--more-->\n<h2 id=\"what-is-playwright-\" style=\"position:relative;\"><a href=\"#what-is-playwright-\" aria-label=\"what is playwright  permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Playwright? 🤔</h2>\n<p><a href=\"https://github.com/microsoft/playwright\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Playwright</a> is a Node library which allows you to automate all major browsers - Chrome, Firefox, WebKit, and the new Microsoft Edge - plus the ability to execute actions, take screenshots, and much more, similar to Puppeteer.</p>\n<p>In their own words:</p>\n<blockquote>\n<p>Playwright is focused on enabling cross-browser web automation platform that is <strong>ever-green</strong>, <strong>capable</strong>, <strong>reliable</strong> and <strong>fast</strong>. Our primary goal with Playwright is to improve automated UI testing by eliminating flakiness, improving the speed of execution and offering insights into the browser operation.</p>\n</blockquote>\n<p>Imagine the possibility of running end to end tests on all major browsers before you ship your any product to your users.</p>\n<h2 id=\"is-is-replacing-puppeteer\" style=\"position:relative;\"><a href=\"#is-is-replacing-puppeteer\" aria-label=\"is is replacing puppeteer permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Is is replacing Puppeteer?</h2>\n<p>Based on what I see and how they’ve answered, I’d say YES. But with a promise to contain all of the functionality of Puppeteer, and make it a cross platform, vendor-neutral, and a collaboration effort between all major parties.</p>\n<p>The lessons learnt are incorporated into it, APIs are testing-friendly, and it will be a cloud native product. For example all the user agent/device emulation is setup consistently on an object called <code class=\"language-text\">BrowserContext</code> to enable <em>multi-page</em> scenarios, <code class=\"language-text\">click</code> waits for the element to be available and visible by default, there is a way to wait for <em>network</em> and other events, etc.</p>\n<h2 id=\"getting-started\" style=\"position:relative;\"><a href=\"#getting-started\" aria-label=\"getting started permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting started</h2>\n<p>You can install Playwright via <code class=\"language-text\">npm</code>:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"70447058851814730000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`npm i playwright`, `70447058851814730000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-bash line-numbers\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i playwright</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>This will install Playwright and its dependencies. Note that it will also download the browser binaries which are quite bulky (~50MB to ~150MB).</p>\n<h3 id=\"launching-a-browser\" style=\"position:relative;\"><a href=\"#launching-a-browser\" aria-label=\"launching a browser permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Launching a browser</h3>\n<p>Playwright module provides a method to launch a browser instance. The following is a typical example of using Playwright to drive automation. Below snippet shows opening a Chrome instance and browsing <code class=\"language-text\">example.com</code> page.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"32668873171439270000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`const playwright = require('playwright').chromium;  // Or 'firefox' or 'webkit'.\r\n\r\n(async () => {\r\n  const browser = await playwright.launch();\r\n  const context = await browser.newContext();\r\n  const page = await context.newPage('http://example.com');\r\n  // other actions...\r\n  await browser.close();\r\n})();`, `32668873171439270000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token keyword\">const</span> playwright <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'playwright'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>chromium<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// Or 'firefox' or 'webkit'.</span>\r\n\r\n<span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token keyword\">const</span> browser <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> playwright<span class=\"token punctuation\">.</span><span class=\"token function\">launch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> context <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">newContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> page <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> context<span class=\"token punctuation\">.</span><span class=\"token function\">newPage</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://example.com'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token comment\">// other actions...</span>\r\n  <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">close</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h3 id=\"taking-a-screenshot-of-the-page\" style=\"position:relative;\"><a href=\"#taking-a-screenshot-of-the-page\" aria-label=\"taking a screenshot of the page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Taking a screenshot of the page</h3>\n<p>You can execute most of the actions available on DevTools. For example we can take a screenshot of the page like so:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"73524157505250570000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`const pw = require('playwright');\r\n\r\n(async () => {\r\n  const browser = await pw.webkit.launch(); // or 'chromium', 'firefox'\r\n  const context = await browser.newContext();\r\n  const page = await context.newPage();\r\n\r\n  await page.goto('https://www.example.com/');\r\n  await page.screenshot({ path: 'example.png' });\r\n\r\n  await browser.close();\r\n})();`, `73524157505250570000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token keyword\">const</span> pw <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'playwright'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token keyword\">const</span> browser <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> pw<span class=\"token punctuation\">.</span>webkit<span class=\"token punctuation\">.</span><span class=\"token function\">launch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// or 'chromium', 'firefox'</span>\r\n  <span class=\"token keyword\">const</span> context <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">newContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> page <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> context<span class=\"token punctuation\">.</span><span class=\"token function\">newPage</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n  <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">goto</span><span class=\"token punctuation\">(</span><span class=\"token string\">'https://www.example.com/'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">screenshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">path</span><span class=\"token operator\">:</span> <span class=\"token string\">'example.png'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n  <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">close</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h3 id=\"emulate-a-device\" style=\"position:relative;\"><a href=\"#emulate-a-device\" aria-label=\"emulate a device permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Emulate a device</h3>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"57243841750130820000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`const playwright = require('playwright').firefox;  \r\nconst iPhone = playwright.devices['iPhone 11 Pro'];\r\n\r\n(async () => {\r\n  const browser = await playwright.launch();\r\n  const context = await browser.newContext({\r\n    viewport: iPhone.viewport,\r\n    userAgent: iPhone.userAgent\r\n  });\r\n  const page = await context.newPage('http://example.com');\r\n  // other actions...\r\n  await browser.close();\r\n})();`, `57243841750130820000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token keyword\">const</span> playwright <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'playwright'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>firefox<span class=\"token punctuation\">;</span>  \r\n<span class=\"token keyword\">const</span> iPhone <span class=\"token operator\">=</span> playwright<span class=\"token punctuation\">.</span>devices<span class=\"token punctuation\">[</span><span class=\"token string\">'iPhone 11 Pro'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token keyword\">const</span> browser <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> playwright<span class=\"token punctuation\">.</span><span class=\"token function\">launch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> context <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">newContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token literal-property property\">viewport</span><span class=\"token operator\">:</span> iPhone<span class=\"token punctuation\">.</span>viewport<span class=\"token punctuation\">,</span>\r\n    <span class=\"token literal-property property\">userAgent</span><span class=\"token operator\">:</span> iPhone<span class=\"token punctuation\">.</span>userAgent\r\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> page <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> context<span class=\"token punctuation\">.</span><span class=\"token function\">newPage</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://example.com'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token comment\">// other actions...</span>\r\n  <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">close</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h3 id=\"going-beyond-simple\" style=\"position:relative;\"><a href=\"#going-beyond-simple\" aria-label=\"going beyond simple permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Going beyond simple</h3>\n<p>Playwright allows you to easily emulate geo-location data.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"39270499825192665000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`const pw = require('playwright');\r\nconst pixel2 = pw.devices['Pixel 2'];\r\n\r\n(async () => {\r\n  const browser = await pw.chromium.launch();\r\n  const context = await browser.newContext({\r\n    viewport: pixel2.viewport,\r\n    userAgent: pixel2.userAgent,\r\n    geolocation: { longitude: 12.492507, latitude: 41.889938 },\r\n    permissions: { 'https://www.google.com': ['geolocation'] }\r\n  });\r\n\r\n  const page = await context.newPage('https://maps.google.com');\r\n  await page.click('text=&quot;Your location&quot;');\r\n  await page.waitForRequest(/.*pwa\\/net.js.*/);\r\n  await page.screenshot({ path: 'colosseum-android.png' });\r\n  await browser.close();\r\n})();`, `39270499825192665000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token keyword\">const</span> pw <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'playwright'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">const</span> pixel2 <span class=\"token operator\">=</span> pw<span class=\"token punctuation\">.</span>devices<span class=\"token punctuation\">[</span><span class=\"token string\">'Pixel 2'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token keyword\">const</span> browser <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> pw<span class=\"token punctuation\">.</span>chromium<span class=\"token punctuation\">.</span><span class=\"token function\">launch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> context <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">newContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token literal-property property\">viewport</span><span class=\"token operator\">:</span> pixel2<span class=\"token punctuation\">.</span>viewport<span class=\"token punctuation\">,</span>\r\n    <span class=\"token literal-property property\">userAgent</span><span class=\"token operator\">:</span> pixel2<span class=\"token punctuation\">.</span>userAgent<span class=\"token punctuation\">,</span>\r\n    <span class=\"token literal-property property\">geolocation</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">longitude</span><span class=\"token operator\">:</span> <span class=\"token number\">12.492507</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">latitude</span><span class=\"token operator\">:</span> <span class=\"token number\">41.889938</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\r\n    <span class=\"token literal-property property\">permissions</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> <span class=\"token string-property property\">'https://www.google.com'</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'geolocation'</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">}</span>\r\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n  <span class=\"token keyword\">const</span> page <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> context<span class=\"token punctuation\">.</span><span class=\"token function\">newPage</span><span class=\"token punctuation\">(</span><span class=\"token string\">'https://maps.google.com'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">click</span><span class=\"token punctuation\">(</span><span class=\"token string\">'text=\"Your location\"'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">waitForRequest</span><span class=\"token punctuation\">(</span><span class=\"token regex\"><span class=\"token regex-delimiter\">/</span><span class=\"token regex-source language-regex\">.*pwa\\/net.js.*</span><span class=\"token regex-delimiter\">/</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">screenshot</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">path</span><span class=\"token operator\">:</span> <span class=\"token string\">'colosseum-android.png'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">close</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Note how we had to set the grant the necessary  permission on the context, which means this is exactly what happens when a user browses the page.</p>\n<h3 id=\"accessing-elements-on-page\" style=\"position:relative;\"><a href=\"#accessing-elements-on-page\" aria-label=\"accessing elements on page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Accessing elements on page</h3>\n<p><code class=\"language-text\">ElementHandle</code> represents an in-page DOM element. <code class=\"language-text\">ElementHandles</code> can be created with the <code class=\"language-text\">page.$</code> method, similar to what we’ve been using in DevTools.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"17794428558904052000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`const playwright = require('playwright').chromium;  // Or 'firefox' or 'webkit'.\r\n\r\n(async () => {\r\n  const browser = await playwright.launch();\r\n  const context = await browser.newContext();\r\n  const page = await context.newPage('https://example.com');\r\n  const hrefElement = await page.\\$('a');\r\n  await hrefElement.click();\r\n  // ...\r\n})();`, `17794428558904052000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token keyword\">const</span> playwright <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'playwright'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>chromium<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// Or 'firefox' or 'webkit'.</span>\r\n\r\n<span class=\"token punctuation\">(</span><span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token keyword\">const</span> browser <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> playwright<span class=\"token punctuation\">.</span><span class=\"token function\">launch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> context <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> browser<span class=\"token punctuation\">.</span><span class=\"token function\">newContext</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> page <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> context<span class=\"token punctuation\">.</span><span class=\"token function\">newPage</span><span class=\"token punctuation\">(</span><span class=\"token string\">'https://example.com'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> hrefElement <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token string\">'a'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">await</span> hrefElement<span class=\"token punctuation\">.</span><span class=\"token function\">click</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token comment\">// ...</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h3 id=\"typing-in-text-boxes\" style=\"position:relative;\"><a href=\"#typing-in-text-boxes\" aria-label=\"typing in text boxes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Typing in text boxes</h3>\n<p>You can emulate a user typing into text fields, for example performing a search action:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"43656160253014690000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`const elementHandle = await page.\\$('input');\r\nawait elementHandle.type('Hello'); // Types instantly\r\nawait elementHandle.type('World', {delay: 100}); // Types slower, like a user\r\nawait elementHandle.press('Enter');`, `43656160253014690000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token keyword\">const</span> elementHandle <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span><span class=\"token function\">$</span><span class=\"token punctuation\">(</span><span class=\"token string\">'input'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> elementHandle<span class=\"token punctuation\">.</span><span class=\"token function\">type</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Hello'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Types instantly</span>\r\n<span class=\"token keyword\">await</span> elementHandle<span class=\"token punctuation\">.</span><span class=\"token function\">type</span><span class=\"token punctuation\">(</span><span class=\"token string\">'World'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span><span class=\"token literal-property property\">delay</span><span class=\"token operator\">:</span> <span class=\"token number\">100</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Types slower, like a user</span>\r\n<span class=\"token keyword\">await</span> elementHandle<span class=\"token punctuation\">.</span><span class=\"token function\">press</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Enter'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span></span></pre></div>\n<h3 id=\"what-else\" style=\"position:relative;\"><a href=\"#what-else\" aria-label=\"what else permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What else?</h3>\n<p>You can even play with mouse (pun intended):</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"42486264489102570000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied to clipboard ✅\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`// Using ‘page.mouse’ to trace a 100x100 square.\r\nawait page.mouse.move(0, 0);\r\nawait page.mouse.down();\r\nawait page.mouse.move(0, 100);\r\nawait page.mouse.move(100, 100);\r\nawait page.mouse.move(100, 0);\r\nawait page.mouse.move(0, 0);\r\nawait page.mouse.up();`, `42486264489102570000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                Copy<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-js line-numbers\"><code class=\"language-js\"><span class=\"token comment\">// Using ‘page.mouse’ to trace a 100x100 square.</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">move</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">down</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">move</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">100</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">move</span><span class=\"token punctuation\">(</span><span class=\"token number\">100</span><span class=\"token punctuation\">,</span> <span class=\"token number\">100</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">move</span><span class=\"token punctuation\">(</span><span class=\"token number\">100</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">move</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">await</span> page<span class=\"token punctuation\">.</span>mouse<span class=\"token punctuation\">.</span><span class=\"token function\">up</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<h2 id=\"what-next\" style=\"position:relative;\"><a href=\"#what-next\" aria-label=\"what next permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What next?</h2>\n<p>The list of the available actions and what is available on the <a href=\"https://github.com/microsoft/playwright/blob/master/docs/api.md\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">API documentation page</a>. The list is almost overwhelming, in a good way 😁.</p>\n<h2 id=\"what-browsers-are-supported\" style=\"position:relative;\"><a href=\"#what-browsers-are-supported\" aria-label=\"what browsers are supported permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What browsers are supported?</h2>\n<ul>\n<li><strong>Chromium</strong>: Playwright uses upstream versions of Chromium.</li>\n<li><strong>WebKit</strong>: Playwright makes a number of modifications to WebCore and WebKit2 in order to extend WebKit’s remote debugging capabilities and support the full set of Playwright APIs.</li>\n<li><strong>Firefox</strong>: Playwright makes a number of modifications to Firefox as well. Those are adding support for content script debugging, workers, CSP, emulation, network interception, etc. etc.</li>\n<li><strong>MS Edge</strong>: Since it’s based on Chromium, it’s supported as well.</li>\n</ul>\n<h2 id=\"what-is-the-update-cadence\" style=\"position:relative;\"><a href=\"#what-is-the-update-cadence\" aria-label=\"what is the update cadence permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is the update cadence?</h2>\n<p>The team follow <a href=\"https://semver.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">semver</a>, and the team are trying to keep in sync with Chromium update cycle, possibly once a month.</p>\n<h2 id=\"but\" style=\"position:relative;\"><a href=\"#but\" aria-label=\"but permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>But</h2>\n<p>Playwright is in a stage where there might be breaking changes coming up as it progresses through full support for those browsers. You can find more information around this on their <a href=\"https://aslushnikov.github.io/isplaywrightready/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Is Playwright Ready?</a> page.</p>\n<p>So go have fun and enjoy this awesome emerging web technology 👍🏼. I will be exploring this on a couple of my side projects too, so stay tuned for more posts.</p>","timeToRead":4,"frontmatter":{"unformattedDate":"2020-01-24T00:00:00.000Z","date":"January 24, 2020","title":"If you consider Puppeteer cool, then Playwright is awesomeness 😍","subtitle":null,"id":null,"author":"Yaser Adel Mehraban","gravatar":null,"canonical_url":null,"tags":["webdev","showdev","testing","playwright"],"thumbnail":null,"cover":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAACAUlEQVR42h3QW2/aMBgG4PzmSfsTu57Um932Ytq0TVu7VWsp0BaSgAMUaA4kOElzIAfbScjJTgudmfTolaVP7yfrE5Yu0aJKi0ojrm3cPpPW4zLqktbhMA0LFu5pmNMgp3HBeDqoDvgoKQQlLEzyYuJuGeRPuz1ELUyrzS6HqDZ2hZXw997FrZ/xjTVEJUzKsDyg5uiTRhj7+SKlakrv1vD8onc1frwYSJ8vbq5G88vh9Nufwffru2tx8VdeDvuTh5+3o6etX7xE1cFFtSD6OUhaJW41zETVuZms+jO1P11LqiOrdl9R7x/NwUy/nRtLbRtZ0G/fYMY25EWLeDnIlbgBbg5gtgqbDeqc/NUrD0F1iJtj3L555dGrjjzt/cEsXm3CTNLpuFvvSkHcpgrMpiYBdg6cYuoUM2e/8spN0lqIWohtUqojqhOmY6YjppNukzGDdKtdJYh6PLezxRYDu5AsPDaSkR5P7GLqlhxwK/BcgaAGCVVQN0Od7DERUhXzcilI22wy4gf5MYOkN7d/S9ovUR1ZSPEqwPn/86QEQbPA9Pxr9+796/0zU6K9wL962RPPPp7JVnriZLJDJIgVr1b86sSrlKBWwhp49WPafBl0Hz51csAkJxMe1v7YSIdaIllI5LZI5GUzkfSdZESSxjMWIRZtcmKhiYNAgGVI7rXoH3l0ClcMCAIEAAAAAElFTkSuQmCC"},"backgroundColor":"transparent","images":{"fallback":{"src":"/static/8054ac3f5d98f5cf4bf6b36d2f58a14f/a2195/socialpreview.png","srcSet":"/static/8054ac3f5d98f5cf4bf6b36d2f58a14f/cadb4/socialpreview.png 750w,\n/static/8054ac3f5d98f5cf4bf6b36d2f58a14f/a2195/socialpreview.png 800w","sizes":"(min-width: 800px) 800px, 100vw"},"sources":[{"srcSet":"/static/8054ac3f5d98f5cf4bf6b36d2f58a14f/11ba1/socialpreview.webp 750w,\n/static/8054ac3f5d98f5cf4bf6b36d2f58a14f/5f042/socialpreview.webp 800w","type":"image/webp","sizes":"(min-width: 800px) 800px, 100vw"}]},"width":800,"height":400}}},"img":null,"socialPreview":{"publicURL":"/static/8054ac3f5d98f5cf4bf6b36d2f58a14f/socialpreview.png"}}}},"pageContext":{"title":"If you consider Puppeteer cool, then Playwright is awesomeness 😍","postPath":"/blog/2020/01/24/playwright","nextPost":"/blog/2020/02/09/marquee","previousPost":"/blog/2020/01/09/clipboard-api"}},"staticQueryHashes":[],"slicesMap":{}}