Create Playwright tests in jest

This is a brief guide into setting up Playwright so that it integrates with your existing Jest testing suite. The aim is to get you using Playwright quickly and easily so that you can test the frontend of your web applications. Playwright is an incredibly versatile testing tool and is incredibly easy to set up as a standalone testing tool, but it can be even more useful once it's integrated with Jest.

This guide assumes that you already have Jest setup and working.

Setup Playwright

We begin by adding Playwright to our existing setup:

yarn add -D playwright

Create a test suite

Create a test following your normal test pattern or path eg. __tests__ or index.test.js. In my case I am going to write a test for my home page.

Begin by importing the browser of your choice (chromium, firefox or webkit).

// __tests__/journeys/home.js

const { chromium } = require("playwright");

Next we need to setup a test suite for our tests and declare a few variables we're going to keep track of throughout the tests. We need to put them at the root of our suite so that we can access them in the scope.

const { chromium } = require("playwright");

describe("Home Page", () => {
    let response;
    let browser;
    let page;
});

Now we need to setup the browser for our tests. Because we will have more than one test in the suite it makes sense to save some boiler plate code so we will create a beforeAll and afterAll setup just to save the repetition.

const { chromium } = require("playwright");

describe("Home Page", () => {
    let response;
    let browser;
    let page;

    beforeAll(async () => {
        // Create a browser instance
        browser = await chromium.launch();

        // Create a page instance
        page = await browser.newPage();

        // Start browsing! 
        // I am testing locally on Gatsby so my URL is localhost:8000
        response = await page.goto("http://localhost:8000/");
    });

    afterAll(async () => {
        // Close the browser
        await browser.close();
    });
});

Add a test

Finally we can write a test! To start with lets just check that the page is loading, before we move onto more interesting things

const { chromium } = require("playwright");

describe("Home Page", () => {
    let response;
    let browser;
    let page;

    beforeAll(async () => {
        browser = await chromium.launch();
        page = await browser.newPage();
        response = await page.goto("http://localhost:8000/");
    });

    afterAll(async () => {
        await browser.close();
    });

    test("The page loads successfully", async () => {
        // Get the HTTP status code of the response. A 200 means it loaded successfully!
        expect(response.status()).toBe(200);
    });
});

Run the test

Now all we need to do is run the normal jest command. Mine is in my package file so I just run yarn test. You should see something like:

>  yarn test
$ jest
PASS  __tests__/journeys/home.js

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        4.298 s

Great! Now lets update the original test and add another simple test. For the sake of brevity I am going to leave out everything but the tests in my suite... You will still need everything else.

Add more tests

describe("Home Page", () => {
    // ... the rest of the setup

    test("The page loads successfully", async () => {
        // Our original test!

        // Let's take a screenshot too
        await page.screenshot({ path: `./screenshots/home.png` });

        expect(response.status()).toBe(200);
    });

    test("The page title is set and correct", async () => {
        // Get the inner text of the page <title> element
        const titleElText = await page.innerText("title");

        // Check that it's correct
        expect(titleElText).toEqual("My super page!");
    });

});

A word of note here. If you write a test for every simple thing you will load a new browser for every since test. The may be resource heavy so you may want to consider grouping some tests together where it logically makes sense. It may also be appropriate to group tests when testing a journey where a page can only be visited once.