Open-source project
argos-ci/jest-puppeteer avatar
argos-ci/jest-puppeteer

jest-puppeteer's preset replaces your test environment, its debug helper wants a 5 minute timeout, and its newest release is from December 2024

GitHub describes it as Run tests using Jest & Puppeteer 🎪✨. The repository metadata lists TypeScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

3,543 stars286 forksTypeScriptMIT

At a glance

What is it?
argos-ci/jest-puppeteer is an MIT-licensed Jest preset that gives browser end-to-end tests a global page object, custom matchers, automatic server management and an optional Firefox target, with the last push on 2026-03-26. The version gap and the configuration ownership are what to read before adopting it.
Who is it for?
jest-puppeteer is a good fit if you want browser tests written in Jest's own style rather than in a separate runner, since the page object is global and the matchers remove most of the verbose waiting. Two things to check before you adopt it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The preset replaces your test environment and you have to remove yours

The basic setup section is short and contains the one instruction most likely to cause a bad first hour.

Adding the preset to your Jest configuration is a single key:

json
{
  "preset": "jest-puppeteer"
}

Then comes the warning: remove any conflicting test environment settings that might be present in your existing configuration, because the preset manages the environment for you.

That is the real contract of a Jest preset. Setting it does not add to your configuration, it supplies the test environment, which means if you already chose an environment, node or jsdom, the two settings are in the same slot and one of them has to go.

For a project that adopted this late, that is an architectural change rather than a line of configuration, because the environment is what decides what globals a test file sees. The preset also injects the page object globally, which is the whole point of the library and the reason it has to own the environment.

The README does not show a before-and-after for a project that already had an environment set, which is the case where the warning actually applies.

The modern Jest globals import is not supported, and two type stubs were dropped

The TypeScript section has three numbered steps, and two of them are about removing things.

The first note is that TypeScript is natively supported from version 8.0.0 of the preset.

The first step says that if you upgraded to version 10.1.2 or above, you should uninstall the old type packages:

bash
npm uninstall --save-dev @types/jest-environment-puppeteer @types/expect-puppeteer

Two community-maintained stub packages were dropped at that version, so the types now ship with the packages themselves. That is the correct direction, and it means an upgrade from a version before 10.1.2 leaves two dead dev dependencies behind unless you remove them.

The second step carries the limitation, stated in parentheses and easy to miss:

bash
npm install --save-dev @types/jest

with the note that the preset does not support the globals import from Jest.

So the documented TypeScript path is the classic ambient-types model, where types are discovered from the type package rather than imported into each file. If your codebase has adopted the newer per-file globals import, this preset does not work with it as written, and the file does not offer a workaround beyond installing the older type package.

That is a real adoption constraint and it is the sort of thing that only shows up when someone writes the first test file in a modern setup.

The debugging helper pauses the run, so the timeout has to go to five minutes

Debugging browser tests is hard for a specific reason: the browser is headless and you cannot see it. The preset ships a helper for that.

js
await jestPuppeteer.debug();

It pauses test execution and opens the browser for manual inspection, which is the right tool for stepping through an interaction or checking the page state.

The file then tells you what it costs. To prevent the test from timing out, increase Jest's timeout:

js
jest.setTimeout(300000); // 5 minutes

That recommendation has a consequence worth naming. The timeout is set per file rather than per test, so adding a debug pause to one test file means every test in it can now hang for five minutes instead of the default. In a suite that runs serially, which this project's own does, that is a long tail on a failing run.

The rest of the recipes section is more conventional and worth reading as a set. The matchers cover asserting on text content, clicking a button matched by its text, and filling a form by selector with a value object. Server management starts a process before the tests and stops it after, configured with a command and a port, which removes the usual manual dance around an app server in tests.

The table of contents promises six sections the file does not contain

The table of contents has three levels and about twenty entries. The visible body stops partway through the recipes.

Listed but not present in what is visible: the Jest-Puppeteer configuration section, the API reference, troubleshooting, acknowledgements, and the body of the recipe on global setup and teardown. The file ends mid-word at the heading for that recipe.

That is a documentation gap rather than a design problem, and it is worth mapping because the missing pieces are the ones you need when something breaks. The configuration section would be where the server, launch and context options are all collected; the API reference would be where the matcher list is authoritative; and troubleshooting is where a headless CI failure gets addressed.

What is visible covers the happy path thoroughly. Installation is one command adding three packages. The first test imports the matcher library and uses the global page object. There are recipes for each matcher, for debugging, for server management, for customising the browser instance including switching to Firefox, for a custom setup file, and for extending the environment class.

The custom setup recipe is the one that quietly changes the earlier example. The first test imports the matcher library inside the test file; the setup recipe moves that import into a file registered through Jest's after-environment hook, so the import can be done once for the suite instead of in every file.

Two identical npm badges, and the maintainer's own product is in the README

The badge row has two entries and both point at the same npm package page.

There is no build badge, no licence badge and no coverage badge, which for a project that automates releases and publishes canaries is an unusual amount of signalling in a header.

The other thing about the header is the organisation name. This repository lives under the account of a commercial visual testing service, and the README contains a section promoting that service. It describes visual testing as a way to track visual changes introduced by each pull request, explains that integrating it with this preset lets you capture and compare screenshots, and then sends you to the vendor's own quickstart guide for Puppeteer.

The relationship is not hidden, which is to its credit. It is also not balanced: the section is four sentences and an outbound link, and it is the only place in the file that mentions screenshots as a use case at all.

So there are two audiences being served by one README. The preset is genuinely useful without the vendor, and a reader who is not shopping for visual regression testing will find that section is skippable. A reader who is evaluating the project's independence has one more thing to weigh.

Its own test script runs serially, and there is a documented incognito mode

The package manifest is the root of a monorepo rather than the published package, and its scripts describe how the project tests itself.

The test script runs Jest in band, which means one worker. For browser tests that is usually the right default, because a dozen headless browsers competing for memory is its own failure mode. It also means the suite gets slower linearly as it grows.

Next to it is a second test script that sets an environment variable before running the same thing. The variable switches the browser into an incognito context, which is how the library verifies that its behaviour holds when no cookies or storage are carried between tests.

That is a good thing to have and an unusual thing to see wired as a named script, because it means the incognito path is exercised deliberately rather than only by hand.

The release scripts are worth reading too. Publishing builds first, then uses the monorepo tool to publish from conventional commits, then runs a separate tool to write the release notes. A canary variant publishes under a canary dist-tag. And the release notes tool is invoked with a preset named for a different project entirely, which suggests the note format was inherited rather than chosen.

Two monorepo configuration files sit in the root

The root listing includes both a configuration file for one monorepo tool and a configuration file for another.

The build scripts invoke the first tool directly, filtering by workspace and by a package name from the environment, so that is the one in use. The second tool's configuration file is present alongside it, which in practice means the project has one orchestration tool and the configuration for another, either left over from a migration or kept for a capability the first does not cover.

Other root files describe the toolchain more clearly. There is a config for the compiler used to transform tests, plus the Jest transformer that consumes it, which together mean the test suite does not go through TypeScript's own compiler to run. There is a lint ignore file and a lint configuration, a formatting ignore file, and a formatting configuration, so linting is a formatting check followed by a static analysis check rather than the reverse order most projects use.

There is also a Jest configuration and a separate config file for the Puppeteer side, plus a server directory and a resources directory in the repository root. The server directory is what the project's own integration tests start, and the resources directory is presumably where screenshot expectations live.

The release notes tool has its own context file at the root as well, which is how it knows what to write about a release.

Editorial conclusion

jest-puppeteer is a good fit if you want browser tests written in Jest's own style rather than in a separate runner, since the page object is global and the matchers remove most of the verbose waiting. Two things to check before you adopt it. Read the upgrade notes, because the type stub packages were removed in 10.1.2 and the modern Jest globals import is explicitly unsupported, so a TypeScript setup needs work. And accept that the preset owns your test environment, which is the one configuration line most likely to collide with something already in your project.

Frequently asked questions

What is jest-puppeteer used for?

It is a Jest preset for end-to-end testing in a browser. Installing it gives every test file a global page object for driving the browser, plus matcher functions for asserting on text, clicking elements and filling forms.

How do I set up jest-puppeteer?

Install the preset, Puppeteer and Jest as dev dependencies, then add the preset to your Jest configuration. You must remove any testEnvironment setting you already have, because the preset manages the environment itself.

Does jest-puppeteer support TypeScript?

Natively from version 8.0.0. If you upgraded to 10.1.2 or later you should uninstall the two old community type stub packages, and the preset does not support Jest's newer per-file globals import, so the classic ambient types package is the documented path.

Can jest-puppeteer run Firefox instead of Chrome?

Yes, through the launch configuration, where the browser is set and headless mode is toggled from an environment variable. The same file also accepts browser options and context setup.

How do I debug a failing browser test in jest-puppeteer?

Call the preset's debug helper, which pauses execution and opens the browser for inspection. Because of the pause you also need to raise Jest's timeout, and the README suggests setting it to five minutes per file.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/argos-ci-jest-puppeteer.svg)](https://hysenlabs.com/projects/argos-ci-jest-puppeteer)