Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform unit tests for custom elements in Jest using JSDom

I realise that this question has been asked on a number of occasions, though the environment has changed since those questions where asked: notably, JSDom now supports custom elements.

These other questions revolved around seeking alternatives (such as using Happy Dom) as JSDom did not support custom elements at that time. However, now that JSDom does support custom elements, does anyone have any information that can solve the following error?

TypeError: Class constructor HTMLElement cannot be invoked without 'new'

  1 | export default class Foo extends HTMLElement {
  2 |   constructor() {
> 3 |     super();
    |     ^
  4 | 
  5 |     this._clicker = 2;
  6 |   }

at new Foo (__tests__/fooclass.js:3:5)     
at Object.<anonymous> (__tests__/fooclass.test.js:7:13)

Current setup:

A reference repo is available here (now fixed):

Custom element example

class Foo extends HTMLElement {
  constructor() {
    super();

    this._clicker = 2;
  }

  connectedCallback() {
    this.textContent = 'My Foo Bar Element';
  }

  get testCallback() {
    return 'hello world!';
  }

  set clicker(num) {
    this._clicker = Number(num);
  }

  get clicker() {
    return this._clicker;
  }
}

packages.json

{
  "scripts": {
    "test": "jest --env=jest-environment-jsdom-sixteen"
  },
  "jest": {
    "verbose": true
  },
  "devDependencies": {
    "@babel/preset-env": "^7.8.4",
    "babel-plugin-transform-builtin-classes": "^0.6.1",
    "jest": "^25.1.0",
    "jest-environment-jsdom-sixteen": "^1.0.2"
  }
}

.babelrc

{
  "presets": ["@babel/preset-env"]
}
like image 877
Oliver Avatar asked Feb 26 '20 13:02

Oliver


People also ask

How does Jest use Jsdom?

Thanks to JSDOM, you can run your tests in Jest, which, as I have mentioned, can only run in Node. By using passing the value "jsdom" to Jest's testEnvironment option, you can make it set up a global instance of JSDOM which you can use when running your tests.

Does Jest come with Jsdom?

Jest actually ships with jsdom and the environment already configured. You can override it with the testEnvironment setting. If you need to set up more aspects of the environment though, you can use the setupTestFrameworkScriptFile setting to point to a file that executes before all of your tests run.

What is Jest environment Jsdom?

jsdom is a pure JavaScript implementation of the DOM and browser APIs that runs in node. If you're not using Jest and you would like to run your tests in Node, then you must install jsdom yourself. There's also a package called global-jsdom which can be used to setup the global environment to simulate the browser APIs.

Can we test Web components using Jest?

TLDR It is possible to test web components with Jest. Don't use JSDOM but run your tests in a browser environment instead. But first things first, let's set up our project and see the component which we are going to test.


1 Answers

NOTE: As of May 2020, Jest supports JSDom 16.* by default, rendering the below no longer necessary or relevant

Solution

Jest runs with JSDom ^15.1.1 by default (as of Feb 17th, 2020) so you will need to update manually to use JSDom 16.2.0 installing jest-environment-jsdom-sixteen.

First, install the latest JSDom environment for Jest

npm i jest-environment-jsdom-sixteen --save-dev

And change your package.json to include:

"scripts": {
  "test": "jest --env=jest-environment-jsdom-sixteen"
},

This will ensure that Jest is running the correct environment.

You will also need to ensure that Babel correctly handles built-in classes (e.g. class HTMLElement {}) by installing babel-plugin-transform-builtin-classes, like so:

npm i babel-plugin-transform-builtin-classes --save-dev

And added to your .babelrc the following

"plugins": [
  ["babel-plugin-transform-builtin-classes", {
    "globals": ["Array", "Error", "HTMLElement"]
  }]
]

Do not install babel-plugin-transform-es2015-classes as this already forms part of the Babel 7 core, as per this issue

Working reduced test case available here.

like image 118
Oliver Avatar answered Oct 12 '22 21:10

Oliver