Using Puppeteer and Jest for End-to-End Testing

Using Puppeteer and Jest for End-to-End Testing

In this tutorial, we will learn how to use the Google-built Puppeteer library to control an instance of headless Chrome and the Facebook-built Jest JavaScript testing library to write and run end-to-end testing suites. End-to-end testing is an important because it helps ensure your application is working properly from the perspective of your users.

Prerequisites

  1. Basic JavaScript knowledge is needed. If you need a refresher, check out our class on JavaScript.

Installing Node and NPM

To install the npm module we need for our bot, we will first need Node.js, a JavaScript runtime.

  1. Visit the official Node.js website to get the installer.
  2. After it downloads, run the installer until the end.
  3. Restart your computer to ensure the changes can take effect.
The Node.js installer.
The Node.js installer.

The Node.js installer should have also installed NPM for you. To confirm that you have installed both properly, you'll need to open Windows Command Prompt if you're on Windows, or Terminal if you're on Mac or Linux.

To check if you installed node:

	
    node -v
	

To check if you installed NPM:

	
    npm -v
	

If both of these commands return a version number, you're good to go.

Installing Puppeteer, Jest, and Jest-Puppeteer

Installing all three packages is as simple as running the npm install command:

	
    npm install puppeteer jest jest-puppeteer --save-dev
	

If you do not already have a package.json file, create it by running this command:

	
    npm init
	

Now that we have our libraries installed, let's configure them both.

Configuring Jest

To configue Jest, create a file named jest.config.js in your root folder.

Inside that file, add:

	
    module.exports = {
        preset: "jest-puppeteer",
        globals: {
            URL: "https://sabe.io"
        },
        testMatch: [
            "**/test/**/*.test.js"
        ],
        verbose: true
    }
	

This tells Jest to use the jest-puppeteer preset that we installed, defines the base URL that we want our test to run against, in this case, https://sabe.io, and then the directory to find our tests in.

Create a folder named src, and then inside it another folder named test. This folder is where all of our tests are going to reside inside.

Configuring Jest-Puppeteer

Now can move on to configuring our jest-puppeteer preset. Create a file named jest-puppeteer.config.js in your root folder and place this inside that file:

	
    module.exports = {
        launch: {
            headless: true,
            slowMo: false,
            devtools: true
        }
    }
	

This configuration turns headless on so that a browser does not actually launch to perform the test, and turns slowMo off. However, you are free to set these values to whatever you like.

Configuring Scripts

The last thing we need to do is add a script to run all our tests when we are ready to run them. Open your package.json file and make sure that you have something similar to this inside:

	
    "scripts": {
        "test": "jest || exit 0"
    }
	

This makes it so that Jest is called when we want to run our tests and I personally like to exit with a code of 0 no matter what because my logs are cleaner however if you want to let the default behavior run instead, remove the || exit 0 part.

Writing our End-to-End Tests

Now we have everything set up and configured, we can move on writing our very first test suite. Inside your test folder, create a file named homepage.test.js. For the sake of this tutorial, we will be testing two things, a page's title and h1 tag contents. Place this code inside:

	
    const timeout = 10000;

    beforeAll(async () => {
        await page.goto(URL, { waitUntil: "domcontentloaded" });
    });

    describe("Test title and header of the homepage", () => {
        test("Title of the page", async () => {
            const title = await page.title();

            expect(title).toBe("Learn Web Development with free Classes and Tutorials ← Sabe.io");
        }, timeout);

        test("Header of the page", async () => {
            const h1Handle = await page.$("h1");
            const html = await page.evaluate(h1Handle => h1Handle.innerHTML, h1Handle);

            expect(html).toBe("Supercharged Web Development");
        }, timeout);
    });
	

The awesome thing about both Puppeteer and Jest is that the resulting code for a test is pretty straightforward and readable. There's a function named beforeAll that, as the name suggests, performs some kind of action before any of the tests are run. In this case, we are simply telling Puppeteer to go to the defined URL and wait until the content has loaded so that the tests can begin.

Then we are defining a test suite to test the title and header of the homepage. Inside the suite is a test that checks the title of the page, and another that checks the content in the page's h1 tags.

In both tests, we are using Puppeteer to get the values, then using Jest to confirm that they are what we expect them to be. Finally, we had a timeout value just in case the test takes particularly long.

We are now ready to run these tests!

Running our End-to-End Tests

Running the tests we just wrote is dead simple. Because of the script we defined in our package.json file, simply open command prompt/terminal at your root folder and run:

	
    npm run test
	

After a few seconds, you should see something very similar to this:

The results of running our end-to-end Jest tests.
The results of running our end-to-end Jest tests.
	
    PASS  src/test/homepage.test.js
    Test title and header of the homepage
      √ Title of the page (28ms)
      √ Header of the page (101ms)

    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        1.999s, estimated 6s
    Ran all test suites.
	

Conclusion

The combination of Puppeteer and Jest make for a powerful testing enviornment that can perform and test basically any operation that a normal user can do. The two make writing and running end-to-end tests a breeze and help ensure that our application or website is functioning as we intend it to.

Resources

If you learned from this tutorial, please consider supporting us! Follow us on Facebook, Twitter and LinkedIn! 😊 Also, join the conversation over at our official forum!