Jest-Puppeteer Template
A template project for writing end-to-end tests using Jest and Puppeteer.
Setup
Run the tests locally.
-
Install packages.
$ npm install
-
Run the tests.
$ # Run the tests in headless mode. $ npm test $ # Run the tests visually on web browser. $ CS_DEBUG=1 npm test
Run the tests in Docker - great for CI and running it in the Cloud.
-
Build the Docker image.
$ docker-compose build
-
Run the Docker image.
$ docker-compose up
Notes
Jest-Puppeteer
If you are just using puppeteer for the e2e testing, you would typically write your test this way:
describe('Google', () => {
it('should display Google', async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://google.com');
await expect(page.title()).resolves.toMatch('Google');
await browser.close();
}, 30000);
});
This project leverages jest-puppeteer, which allows us to declare configurations in our config files. When jest runs the tests, the package will initializes some global variables at runtime according to the declared configurations.
We also use the package expect-puppeteer for better test assertion handling.
Set up jest-puppeteer and expect-puppeteer this way:
In jest-puppeteer.config.js
:
const debug = process.env.CS_DEBUG === 'true';
// Use slowMo to slow things down just abit to observe the automation better.
module.exports = {
launch: {
headless: !debug,
slowMo: (debug) ? 50 : 0,
args: [
'--disable-dev-shm-usage',
'--disable-gpu',
],
},
};
In jest.config.json
:
{
"globalSetup": "jest-environment-puppeteer/setup",
"globalTeardown": "jest-environment-puppeteer/teardown",
"testEnvironment": "jest-environment-puppeteer",
"setupFilesAfterEnv": ["expect-puppeteer"]
}
Now that browser
object is initialized and exposed at runtime, our test code can be rewritten as:
describe('Google', () => {
it('should display Google', async () => {
await page.goto('https://google.com');
await expect(page.title()).resolves.toMatch('Google');
}, 30000);
});
Docker
Running Puppeteer in Docker can be problematic at times. Here are some troubleshooting tips.
- If you see
Failed to move to new namespace
error message when running the Docker image, read here on running Chromium headless as a non-privileged user. The easiest way to resolve this is to pass the--cap-add=SYS_ADMIN
option to Docker. - Be careful when launching Chromium with the
-—no-sandbox
parameter. Make sure you understand its implications especially for websites, with which you are not familiar. - By default, Docker container is configured with
/dev/shm
of 64MB of shared memory. This isn't enough for Chromium to run. To run the Docker jest-puppeeter container properly, we pass the--disable-dev-shm-usage
, which directs Chromium to use/tmp
to write shared memory files. See here for details. - Alpine is a great Linux base image for Docker container due to its small size. By default, puppeteer installs chromium as part of its installation. However, only Chromium version 77+ works on Alpine. So if we are installing older versions of puppeteer on Linux, we may want to tell puppeteer to not install the bundled Chromium and let us instead chromium ourselves. If you were to install your own version of Chromium, be mindful of the recommended version of Chromium needed by a specific version of Puppeteer. See all corresponding Chromium and Puppeteer versions.
- If you see
mkdir: can't create directory '/tmp/jest_rs': No space left on device
when running the Docker container, it usually means that Docker system has limited space left. Run this commanddocker system prune --all --force
to free up some resources.