Search code examples
javascriptunit-testingtestingdomembedded-resource

How to test DOM methods in embed js script library?


I am working in a Javascript library to embed in the browser.

The thing is that I was started the project from https://github.com/krasimir/webpack-library-starter and I would to test my library but I have a problem with the DOM because my proyect hasn't got html so, I don't know how I should to test the DOM methods.

The library is to embed in to our clients websites, the idea is to make a embed script like google maps, analytics sdk, etc.

I am using chai and mocha to test but maybe I should to change to ava or something like.

I know that in React for example you have tools to simulate the DOM but it is in vanilla JS so... help please.

Example of my library class:

export class MyClass {
  constructor(htmlElement) {
   this.clientWebsiteHTMLElement = htmlElement;
   this.addChild();
  }

  addChild() {
   let child = document.createElement('div');
   this.clientWebsiteHTMLElement.appendChild(child);
  }
}

Example of my-lib.js

import { MyClass } from './my-class.js'


if (window && document) {
  (function (window, document){
    let container = document.getElementById('container');
    let myClass = new MyClass(container);

    window.myLib = myClass;
  })(window, document) 
}

Example of entry point (In to the client website, is not in the same project):

<html>
  <head></head>
  <body>
   <div id="container"></div>

  <script src="http://myserver.com/to/serve/embed/scripts/myLib-bundle.js"></script>
  </body>
<html>

Really is more complex than this, but the solution are the same.

How I can test that for example?

Thanks! :D


Solution

  • The problem is that Mocha tests are executed with Node.js, meaning by default, there is no browser available that can provide a DOM that provides APIs like document or window.

    A popular tool to provide a DOM for these tests is JSDOM.

    Here's a simple example how you could test your class MyClass:

    import { MyClass } from '../modules/MyClass';
    import { JSDOM } from 'jsdom';
    
    const dom = new JSDOM(
      '<!DOCTYPE html><html><head></head><body><div id="root"></div></body></html>'
    );
    
    global.document = dom.window.document;
    
    describe('My class', () => {
      it('adds an element to the HTML element passed to its constructur', () => {
        const htmlElement = document.getElementById('root');
        const myClass = new MyClass(htmlElement);
        expect(htmlElement.children.length).toBe(1);
      });
    });
    

    Note: Since you're already considering switching your testing library, may I suggest switching to Jest? It comes with JSDom pre-installed.