Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

165
Views
How to test an arbitrary es6 module in Puppeteer `page` with Jest?

I have an es6 module that looks like this

// MyModulue.js
import MySubModule from '../my-sub-module';

const MyFunction => {
    // accesses various DOM elements
    const element = document.querySelector("#whatever");
    
    // accesses various DOM api's
    const styles = window.getComputedStyle(element)

    // uses some other imported module
    const result = MySubModule.someMethod(styles)

    // a ton of other business logic
    // ...
    
    return someResult;
}

export default MyFunction;

I want to test MyModule.js inside of the context of a Puppeteer page (i.e. a browser tab).

Here is what I have:

await page.setContent(input);
await page.addScriptTag({
      path: 'path/to/function/MyModule.js',
      type: 'module',
});
const actualFieldLabel = await page.evaluate(async (selector) => {
     const field = document.querySelector(selector);
     const result = await MyFunction(field); // <=== How can I do this??
     return result;
}
expect(actualFieldType).toBe(output);

How can I get this to work? No matter what I've tried result is either undefined or an exception gets thrown.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

There are some problems that you come across that you just don't want anyone else to have to suffer through. For me this was one of them. Here is the solution to my situation I hope it can help you too:

Puppeteer is not kidding in their documentation when they say the pageFunction callback is executed in the page context. However, a far more helpful way of saying this is that pageFunction is executed inside the current HTML document and has in the window / global scope whatever you have added - and is thus missing whatever you have not provided.

There were two fixes that needed to be made:

// MyModulue.js
import MySubModule from '../my-sub-module';

const MyFunction => {
    // accesses various DOM elements
    const element = document.querySelector("#whatever");

    // accesses various DOM api's
    const styles = window.getComputedStyle(element)

    // uses some other imported module
    const result = MySubModule.someMethod(styles)

    // a ton of other business logic
    // ...

    return someResult;
}

export default MyFunction;

// Problem #1: export default didn't expose MyFunction to the global 
// scope so it was not accessible from the page.evaluate(() => {...})
// You can fix this by exposing it on the window global like so:
window.MyFunction = MyFunction;

The second problem was that MyModule.js dependes on another module, MySubModule.js which was simply non-existent inside page because I had only called

await page.addScriptTag({
  path: 'path/to/function/MyModule.js',
  type: 'module',
});

instead of something like this:

await page.addScriptTag({
  path: 'path/to/function/MyModule.js',
  type: 'module',
});
await page.addScriptTag({
  path: 'path/to/function/my-sub-module.js',
  type: 'module',
});

However, I must say in my case MyModule.js had a giant dependency tree with many imported modules and many of those modules importing other modules. As a result, I had to piggy-back off my existing webpack.config to add another entry point and output chunk. So my final solution was to import a webpack bundle for the entire dependency tree of MyModule something like my-module.bundle.js, see below:

await page.setContent(input);
await page.addScriptTag({
    type: 'module',

    // this is the output of webpack creating a bundle of the dependency tree 
    // starting at MyBundle.js
    path: 'build/my-module.bundle.js', 
});
const actualFieldLabel = await page.evaluate(async (selector) => {
     const field = document.querySelector(selector);
     const result = await MyFunction(field); // <=== How can I do this??
     return result;
}
expect(actualFieldType).toBe(output);

This worked like a charm because the bundle had all the depencies and page.addScriptTag inserted them right into page!

Very greatful that jest-puppeteer worked so nicely with jest out of the box!

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!