DEV Community

Yaser Adel Mehraban
Yaser Adel Mehraban

Posted on • Originally published at yashints.dev

If you consider Puppeteer cool, then playwright is awesomeness 😍

If you've ever used Puppeteer, you'd know it enables you to control a Chrome instance (or any other Chrome DevTools 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 Playwright which apparently is their new favourite.

What is Playwright? πŸ€”

Playwright is a Node library which allows you to automate instances of all major browsers - Chrome, Firefox, WebKit, and the new Microsoft Edge - plus the ability to execute actions, run code, interact with page elements, and much more, similar to Puppeteer.

In their own words:

Playwright is focused on enabling cross-browser web automation platform that is ever-green, capable, reliable and fast. 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.

Imagine the possibility of running end to end tests on all major browsers before you ship your any product to your users.

Is is replacing Puppeteer?

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.

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 BrowserContext to enable multi-page scenarios, click waits for the element to be available and visible by default, there is a way to wait for network and other events, etc.

Getting started

You can install Playwright via npm:

npm i playwright
Enter fullscreen mode Exit fullscreen mode

This will install Playwright and its dependencies. Note that it will also download the browser binaries which are quite bulky (~50MB to ~150MB).

Launching a browser

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 example.com page.

const playwright = require('playwright').chromium;  // Or 'firefox' or 'webkit'.

(async () => {
  const browser = await playwright.launch();
  const context = await browser.newContext();
  const page = await context.newPage('http://example.com');
  // other actions...
  await browser.close();
})();
Enter fullscreen mode Exit fullscreen mode

Taking a screenshot of the page

You can execute most of the actions available on DevTools. For example we can take a screenshot of the page like so:

const pw = require('playwright');

(async () => {
  const browser = await pw.webkit.launch(); // or 'chromium', 'firefox'
  const context = await browser.newContext();
  const page = await context.newPage();

  await page.goto('https://www.example.com/');
  await page.screenshot({ path: 'example.png' });

  await browser.close();
})();
Enter fullscreen mode Exit fullscreen mode

Emulate a device

const playwright = require('playwright').firefox;  
const iPhone = playwright.devices['iPhone 11 Pro'];

(async () => {
  const browser = await playwright.launch();
  const context = await browser.newContext({
    viewport: iPhone.viewport,
    userAgent: iPhone.userAgent
  });
  const page = await context.newPage('http://example.com');
  // other actions...
  await browser.close();
})();
Enter fullscreen mode Exit fullscreen mode

Going beyond simple

Playwright allows you to easily emulate geo-location data.

const pw = require('playwright');
const pixel2 = pw.devices['Pixel 2'];

(async () => {
  const browser = await pw.chromium.launch();
  const context = await browser.newContext({
    viewport: pixel2.viewport,
    userAgent: pixel2.userAgent,
    geolocation: { longitude: 12.492507, latitude: 41.889938 },
    permissions: { 'https://www.google.com': ['geolocation'] }
  });

  const page = await context.newPage('https://maps.google.com');
  await page.click('text="Your location"');
  await page.waitForRequest(/.*pwa\/net.js.*/);
  await page.screenshot({ path: 'colosseum-android.png' });
  await browser.close();
})();
Enter fullscreen mode Exit fullscreen mode

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.

Accessing elements on page

ElementHandle represents an in-page DOM element. ElementHandles can be created with the page.$ method, similar to what we've been using in DevTools.

const playwright = require('playwright').chromium;  // Or 'firefox' or 'webkit'.

(async () => {
  const browser = await playwright.launch();
  const context = await browser.newContext();
  const page = await context.newPage('https://example.com');
  const hrefElement = await page.$('a');
  await hrefElement.click();
  // ...
})();
Enter fullscreen mode Exit fullscreen mode

Typing in text boxes

You can emulate a user typing into text fields, for example performing a search action:

const elementHandle = await page.$('input');
await elementHandle.type('Hello'); // Types instantly
await elementHandle.type('World', {delay: 100}); // Types slower, like a user
await elementHandle.press('Enter');
Enter fullscreen mode Exit fullscreen mode

What else?

You can even play with mouse (pun intended):

// Using β€˜page.mouse’ to trace a 100x100 square.
await page.mouse.move(0, 0);
await page.mouse.down();
await page.mouse.move(0, 100);
await page.mouse.move(100, 100);
await page.mouse.move(100, 0);
await page.mouse.move(0, 0);
await page.mouse.up();
Enter fullscreen mode Exit fullscreen mode

What next?

The list of the available actions and what is available on the API documentation page. The list is almost overwhelming, in a good way 😁.

What browsers are supported?

  • Chromium: Playwright uses upstream versions of Chromium.
  • WebKit: 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.
  • Firefox: 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.
  • MS Edge: Since it's based on Chromium, it's supported as well.

What is the update cadence?

The team follow semver, and the team are trying to keep in sync with Chromium update cycle, possibly once a month.

But

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 Is Playwright Ready? page.

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.

Top comments (17)

Collapse
 
fredericbonnet profile image
FrΓ©dΓ©ric Bonnet

Awesome work! I'm already in love with Playwright. What I really appreciate as a developer is the seamless integration with Firefox and WebKit and not just Chromium, with no extra step to integrate or configure anything. WebDriver can be tedious on these points.

I have a pet project of mine called Instakittens that serves as a playground for testing frameworks (think TodoMVC, but for tests). I already have several test suites that use Puppeteer for browser automation, with Jest, Mocha and Cucumber as test runners. When I saw the announcement for Playwright on Twitter I had the urge to give it a try. Incredibly enough, it took me only a few hours to port the Puppeteer-based suites to Playwright with almost zero compatibility issue: apart from the initialization, I only had to replace {visible: true} / {hidden: true} to {visibility: 'visible'|'hidden'} in selectors.

Collapse
 
yashints profile image
Yaser Adel Mehraban

Awesome work, I’ll check out your repo for sure, will save me a few hours at least πŸ™‚

Collapse
 
evanplaice profile image
Evan Plaice

Does playwrite download its own version of the browser like Puppeteer, or can it use an existing install?

Collapse
 
arjunattam profile image
Arjun Attam

You can use it with an existing install, and avoid the binaries from getting downloaded. Check out the playwright-core NPM package, which does not install the binaries. We want to ensure your tests run fast and if your setup does not need the browser to be downloaded, you shouldn't have to wait.

Collapse
 
evanplaice profile image
Evan Plaice

Awesome! Thank you πŸ™

Collapse
 
yashints profile image
Yaser Adel Mehraban

It downloads the binaries from official channels, not sure you can use an existing or not, will look it up

Collapse
 
evanplaice profile image
Evan Plaice

Thanks. That's my biggest issue with E2E testing FWs.

I'd like to be able to npx playwright and have the tests run instantly. Rather than wait 5 min for a download.

Thread Thread
 
yashints profile image
Yaser Adel Mehraban

Might happen, it’s open source, check the issues and see if something exists. Up vote or create one πŸ™‚. Even better create a PR if that’s your thing

Collapse
 
skhmt profile image
Mike πŸˆβ€β¬›

Can you use Playwright to create an Electron-like system, but with Firefox instead of Chromium?

Collapse
 
yashints profile image
Yaser Adel Mehraban

It’s a bit early to be sure, but I see the potential

Collapse
 
julienverkest profile image
Julien Verkest

Great tool!

Collapse
 
mikeborozdin profile image
Mike Borozdin

How does it address flakiness in E2E tests though? If it's true than it could be as good as Cypress (little flakiness) and Selenium (multiple browser support) combined.

Collapse
 
yashints profile image
Yaser Adel Mehraban

I’ll be exploring this further as I mentioned, if you have a codebase with e2e tests, do try it out and give feedback as well

Collapse
 
gabbersepp profile image
Josef Biehler

How does Playwright communicate with the browsers?

Chromium is accessed via CDP as far as I know. But for the rest I found nothing.

Collapse
 
yashints profile image
Yaser Adel Mehraban

Have a look at connect method on this file for example

github.com/microsoft/playwright/bl...

Collapse
 
nicoandmee profile image
Nico Kokonas

Yes I am extremely excited to start using this library

Collapse
 
endtest_io profile image
endtest

We built a cloud platform where anyone can create, manage and execute automated tests for Web and Mobile Applications.

We would love to get some unbiased feedback from your side.

endtest.io