I’m switching from CasperJS to Jest with Puppeteer for my testing setup. When I put all tests in one file, it works perfectly:
beforeAll(async () => {
// initialize browser and page objects
});
describe('First test suite', () => {
// run tests here
});
describe('Second test suite', () => {
// run tests here
});
afterAll(async () => {
// cleanup browser
});
The issue is I want to split my tests into separate files for better organization and to run individual test suites when needed.
I tried using Jest’s setupScript configuration but it creates a new browser instance for each test file, which is slow. I need one browser instance shared across all test files.
I also considered this approach:
// main runner file
await require('firstTestSuite')(browserInstance, pageInstance, settings);
await require('secondTestSuite')(browserInstance, pageInstance, settings);
This works for sharing the browser but I lose the ability to run individual test files.
I looked into custom testEnvironment but the documentation is unclear about whether it creates one instance per file or per entire test run.
What’s the best way to share a single Puppeteer browser instance across multiple Jest test files while keeping them separate?
Here’s how I share a single Puppeteer browser across multiple Jest test files: create a browser manager module with the singleton pattern. Make a browser-manager.js file that exports functions to get or create the browser instance. Import this manager in each test file and call getBrowser() in your beforeAll hooks. The browser gets created once and reused everywhere. You can also use Jest’s setupFilesAfterEnv to spin up the browser before tests run, then grab it through your manager module. This keeps test files separate but avoids spinning up multiple browser instances. Don’t forget cleanup in afterAll hooks or use global teardown to close the browser when everything’s done.
Same issue here when I switched from Selenium. Fixed it by making a separate browser.js file that exports a singleton. Export an object with an async getBrowser() method - it checks if the browser exists, creates one if it doesn’t. Then import it in each test file and call getBrowser() in beforeAll. Works perfectly and lets you keep tests in different files while sharing the same browser instance.
I encountered a similar challenge and resolved it by utilizing a global setup file for Puppeteer. In your jest.config.js, you can define globalSetup to specify the path to your setup script, where youinitialize the browser and attach it to globalThis. This allows access to the shared browser in your tests via globalThis.browser within beforeAll hooks. Keep in mind that you should run Jest with --maxWorkers=1 for this to function correctly. While this setting prevents parallel execution, it significantly speeds up your tests since it avoids launching multiple browsers. Ensure to implement proper cleanup in globalTeardown as well.