Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run jest unit tests in real browser environment with window access using puppeteer

What i want

My code widely depends on global window object (and it's methods) which isn't fully implemented by jsdom, but available in real browser environment. So i want to run unit tests inside puppeteer page context environment so covered code (and it's dependencies) can access real window object.

Problem

The main problem is that puppeteer designed to run e2e tests outside of page context. I find no way to execute concrete test suit inside page context as jsdom does without running whole build though it's public interface / GUI (which kills whole unit test idea).

What i tried

I tried to write custom test environment to run each test suite inside puppeteer page.evaluate context that could access window object:

const PuppeteerEnvironment = require('jest-environment-puppeteer');

module.exports = class TestEnvironment extends PuppeteerEnvironment {
  constructor(config) {
    super(config);
  }

  async runScript(script){
   if(this.global.page){
     return await this.global.page.evaluate((runner, script)=>{
       return runner(script);
     }, super.runScript, script)
   } else{
     return null;
   }
  }
};

but it seems that puppeteer serializes evaluate arguments so i can't find a way to make runScript call inside it's context.

I also tried to clone evaluate window object into globals but without any luck by same reason (serialization issue)

 async setup(config){
   const setupResult = await super.setup(config);
   const window = await this.global.page.evaluate( () => window)
   this.globals.window = window;
   return setupResult;
  }
};
like image 522
user3388811 Avatar asked Oct 19 '18 12:10

user3388811


People also ask

How do I run Jest test cases in Chrome?

open Chrome and go to chrome://inspect. click on "Open Dedicated DevTools for Node" click on the address displayed in the terminal (usually something like localhost:9229) Chrome Developer Tools will be displayed, and a breakpoint will be set at the first line of the Jest CLI script.

Is Jest faster than Jasmine?

🐛 Bug Report We've been using Jest alongside Jasmine for the same test suite for about a year now. We love Jest because it's developer experience is superb, however, on our very large monorepo with ~7000+ test specs, Jest runs about 7 times slower than Jasmine.


1 Answers

I think it's worth reconsidering your assumptions...

My code widely depends on global window object (and it's methods) which isn't fully implemented by jsdom, but available in real browser environment.

Which methods from the window scope are you using that aren't in jsdom? Can you just provide a simple mock window object that contains mocked versions of these methods?

So i want to run unit tests inside puppeteer page context environment so covered code (and it's dependencies) can access real window object. ... (which kills whole unit test idea)

Once you start running your code in a browser, you may be crossing the line between unit tests and integration or end-to-end tests. I'd take a look at your code and see if you can abstract-out the logic that depends on the window scope, and concentrate on testing the non-window-dependent code.

like image 68
Luke Avatar answered Sep 20 '22 11:09

Luke