Skip to content

Guide on how to to configure puppeteer with a default (non-ejected) react app in order to test individual react components.

License

Notifications You must be signed in to change notification settings

TomaszRewak/react-app-puppeteer-component-testing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About

This repository explains how to configure puppeteer with a default (non-ejected) react app in order to test individual react components.

describe("MyComponentOne", () => {
    it("should render with text",
        () => {
            return <MyComponentOne text="Hello World!" />;
        },
        async page => {
            await page.waitForSelector(".my-component-one");
            const text = await page.$eval(".my-component-one", el => el.innerHTML);
            expect(text).toBe("Hello World!");
        });
});

Please note that this repo is not a library. It's simply a guide on how to configure puppeteer with your own react application (without any additional dependencies).

Why?

The default react testing library allows you to test individual components based on their DOM structure. In most cases it's enough, but sometimes you might want to write regression tests that compare the actual component's appearance with a reference image. This is especially useful when creating components that heavily rely on the HTML5 canvas element.

Setup

1. Create a new react app (or use an existing one)

npx create-react-app my-app
cd my-app

2. Install puppeteer

Install the puppeteer that's compatible with your version of react-scripts (in this case: 18.1.0) and other test dependencies you may need.

npm install --save-dev puppeteer@18.1.0
npm install --save-dev jest-image-snapshot

3. Create the test environment in you project root

Copy over the test-env folder from this repo to your project root (just next to the src folder).

├ public
├ src
├ test-env                     << Just copy it here
│ ├ public
│ ├ src
│ └ package.json
└ package.json

4. Copy the test utilities file into your project

Copy over the src/utils/puppeteer-testing.js file from this repo into your project.

├ public
├ src
│ ├ utils
│ │ └ puppeteer-testing.js     << Just copy it here
│ └ index.js
├ test-env
└ package.json

5. Import the test utilities file into your react component test files

They will override the default jest functions.

import { describe, it, beforeAll } from "../utils/puppeteer-testing";

6. Define your test cases

describe("MyComponentOne", () => {
    beforeAll(async () => {
        const { toMatchImageSnapshot } = await import(["jest-image-snapshot"][0]);
        expect.extend({ toMatchImageSnapshot });
    });

    it("should render with text",
        () => {
            return <MyComponentOne text="World Hello!" />;
        },
        async page => {
            await page.waitForSelector(".my-component-one");
            const screenshot = await page.screenshot({ clip: { x: 0, y: 0, width: 200, height: 80 } });
            expect(screenshot).toMatchImageSnapshot();
        });

    it("should render without text",
        () => {
            return <MyComponentOne />;
        },
        async page => {
            await page.waitForSelector(".my-component-one");
            const screenshot = await page.screenshot({ clip: { x: 0, y: 0, width: 200, height: 80 } });
            expect(screenshot).toMatchImageSnapshot();
        });
});

7. Run your tests

npm test

8. View your test results

Good to know

  • The provided code works only within the linux environment (including WSL). It can be adjusted to work with other operating systems by editing the prestart script in the test-env/package.json file (though it has not been tested).
  • Your test files will be run both in the node environment and in the browser. In practice, the first callback of each test will be run in the browser, while the second one will be run in the node environment.
  • It's good to avoid importing any node-specific modules in the global scope of your test files (as it will cause errors in the browser environment).
  • It's best to obfuscate any imports that are not to be included in the browser environment (for example: await import(["jest-image-snapshot"][0])). This will prevent the browser from pre-fetching them.

About

Guide on how to to configure puppeteer with a default (non-ejected) react app in order to test individual react components.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published