jestjsjest-puppeteer

Jest/puppeteer test fails when importing helper function


I'm bumping into an issue importing a helper function, which calls Puppeteer methods, into a test file. I've created a simplified example of my problem.

I have a test in a file called my-test.test.js:

import { setUpTest } from "./set-up-test.js"
test('dummy test', async () => {
  await setUpTest()
})

I’m importing a helper function setUpTest, which is in the file set-up-test.js:

export async function setUpTest () {
  await page.goto('http://localhost:3333/index.html')
  await page.setViewport({ width: 1280, height: 800 })
  await page.waitForFunction('window.doSomething')
  page.on('console', message =>
      console.log(`${message.type().substring(0, 3).toUpperCase()} ${message.text()}`))
  await page.evaluate(() => {
    console.log('set up')
  })
}

When I run my test, I get the following error:
ReferenceError: cov_1kbir0kkub is not defined

The problem has something to do with configuring test coverage collection. In my jest.config.js file, I set collectCoverage to true. If I get rid of this property, my tests run fine. Here’s my jest.config.js file:

/** @type {import('jest').Config} */
const config = {
  verbose: true,
  collectCoverage: true,
  preset: "jest-puppeteer",
};
module.exports = config;

It's the combination of setting collectCoverage to true, importing setUpTest into my test file, and calling page.evaluate inside of setUpTest that leads to the error. If I omit coverage collection from my test, define setUpTest inside of my test file, or comment out calling page.evaluate in setUpTest, the test runs fine.

I would like to get coverage reports for my tests and also be able to place helper functions for my tests (like setUpTest) in a separate file. I appreciate any suggestions.

Here's also my index.html that puppeteer goes to during the test:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Random Page</title>

  <script type="module">
    import { doSomething } from 'http://localhost:3333/index.js'
    window.doSomething = doSomething
  </script>
</head>
<body>
</body>
</html>

And index.js...

export function doSomething () {
  console.log('something')
}

Solution

  • I found a solution to the problem by omitting JS files in my test folder from being included in the Jest coverage reports. This can be done by setting the collectCoverageFrom configuration property in my jest.config.cjs file:

      collectCoverageFrom: [
        "!./**/*.{js,jsx}", // exclude JS files inside of the unit test folder
      ]
    

    By doing this, I can freely create JS files in my test folder that contain any helper functions I need for my tests.

    Coverage collection is performed by Jest in the node context. The helper function setUpTest that I wanted to keep in a separate JS file performs Puppeteer operations that are in the browser context. Because I directly import my helper function into my test files, Jest was trying to collect coverage information from it during my tests and was not able to do so. In this case, Jest uses the variable cov_1kbir0kkub during coverage collection, but it only exists within the node context, not within the browser context when setUpTest is calling functions like page.evaluate. Hence the reference error.