Automate your testing with Playwright
Tags: testing, selenium, javascript, tutorial
Published: 2021-12-04 01:06:29

I've test been hearing a lot of buzz about [Playwright](https://playwright.dev/) lately, a relatively new E2E test automation framework.  With all the hype,  I figure it's in my best interest to find out what the talk is about.  So let's get started!

## Introduction

Playwright actually began as a fork from of [Puppeteer](https://github.com/puppeteer/puppeteer), a NodeJS automation framework created by Google to support Chromium automation. Playwright was introduced by Microsoft in 2020 as is an open source NodeJS library that supports automation on Chromium, Firefox, and WebKit through a single API. 

## Key facts and features

| Feature        | Description           |
| ------------- |:-------------:|
| supported operating systems      | MacOS, Linux, Windows | 
| supported languages |  The Playwright API is available in JavaScript, TypeScript, Java, Python, and .NET C# |
|cross browser support | Playwright allows you to test across all modern browsers, with support for Chromium, Firefox, and WebKit|
| auto waits | When your code interacts with the DOM, Playwright auto-waits for the elements to be ready for the interaction |
| parallelization | parallel testing with browser context |
|mobile| Emulating mobile devices (does not support real devices)|

Let's take a look at some code to see how this works.

## Installing 
Of course step 1 is installing Playwright.

You'll need Node installed as a prerequisite.  After that, installing Playwright is as simple as:
`npm i -D playwright`

You can also install the supported browsers with:
`npx playwright install`

The test runner can be installed with:
`npm i -D @playwright/test`

## Sample Code
Time for some sample code! All these examples are JavaScript, and we'll be testing this [sample website] (https://phptravels.com/demo/).  

###The Basics

Let's start with the basics.  Create `tests\sample1.spec.js` with the following content:
```javascript
const { test, expect } = require('@playwright/test');

test('title test', async ({ page }) => {
    await page.goto('https://phptravels.com/demo/');
    const name = await page.title()
    expect(name).toBe('Demo Script Test drive - PHPTRAVELS');
  })
  ;
```
It's likely obvious what's going on here, we're navigating to a web page and verifying the title.

Go ahead and run this test from the command line:
`npx playwright test`

If things go as they should you will see something like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hw3yw4d002zb9l0ym9dj.png)

Notice there was no visible browser started.  All  Playwright tests run headless by default.  Let's run a headed test:

`npx playwright test --headed`

This time you should see Chrome open briefly as the test quickly runs.  Let's run the test in Firefox.

`npx playwright test --headed --browser=firefox`

Same concept as the previous test, you should see Firefox open as the test runs.

How about some parallel testing with all 3 browsers?

`npx playwright test --headed --browser=all`

Not too shabby.  we've got a cross-browser test running with our 3 browsers, and it's taken us about 5 minutes:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsxzousch9xalezu1y1y.png)

### Auto Waits
Depending on the responsiveness of the page you are testing, you may find that the page is not ready to accept the action you want to take.  For example, the script might be ready to click a link, but the page might not be fully rendered with the link clickable.  In other automation frameworks that might result in a failing test, or the need to add additional code to deal with waits, delays, retries, etc. 

Let's see how this works in Playwright.  The following test opens the home page, clicks a link, and then verifies some text on the resulting page.

```javascript
test('pricing page test', async ({ browser }) => {
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://phptravels.com/demo');
    await page.click('text=Pricing');
    expect(await page.innerText('.plan-type')).toBe('Plans and Prices');
  });
```
 
Playwright employs an auto-wait strategy to simplify test creation and increase test reliability.  For example, before Playwright tries to click on the link, it will wait for the element to be attached, visible, stable, enabled, and ready to receive events.  This means less automation code for YOU to write, and more reliable and less flaky tests.

### Screenshots
Of course screenshots can be useful when troubleshooting, and that's easy enough with Playwright.
- Capture the entire page:  
```javascript
    await page.screenshot({ path: './screenshots/whole_page.png' });
```
- Capture a section of the page, by locator:  
```javascript
    await page.locator('.templates-page').screenshot({ path: './screenshots/partial_page.png' });
```

## Wrap-up
So there you go, a brief overview of Playwright.  In my next post I want to look at how Playwright deals with other features, such as visual testing, reporting, and mobile emulation.  After that we'll look at adding these automated tests to a CI pipeline, so stay tuned!  


<a href="https://dev.to/leading-edje">
  ![Smart EDJE Image](https://dev-to-uploads.s3.amazonaws.com/i/5uo60qforg9yqdpgzncq.png)
</a>