1 of 13

Unit testing native Web Components

2 of 13

Hello!

I am Andy Desmarais

Social Media: @terodox

Website: terodox.tech

2

3 of 13

Web Components

DOM native components, no framework

3

4 of 13

Basics of Web Components

4

Attach �shadow

Define new �custom element

Extend HTMLElement

class WebComponentExample extends HTMLElement {

constructor() {

super();

this.attachShadow({ mode: 'open' });

}

}

customElements.define(

'web-component-example-tag-name',

WebComponentExample);

5 of 13

What’s the problem?

We need DOM native functionality for testing,

but starting a browser is slow.

5

6 of 13

jsdom is missing some pieces

Web Components need

  • HTMLElement
  • customElements
  • Shadow DOM

These are not available in jsdom (yet)

6

7 of 13

Invert control

Inject the window!?

  • import { HTMLElement, customElements } from ‘window’;

7

8 of 13

Webpack - use externals

  • module.exports = {� …� externals: { window: ‘window’ }�};

8

9 of 13

Rollup - use globals

  • export default {� …� output: {� ...� globals: { window: ‘window’ }� }�};

9

10 of 13

ESM - Create a window.mjs

  • export const HTMLElement = window.HTMLElement;

export const customElements = window.customElements;

10

11 of 13

WE HAVE A SEAM

Testing is now REALLY straight forward

11

12 of 13

Fake it ‘til you make it

const window = {

HTMLElement: class HTMLElement {

attachShadow() {

this.shadowRoot = document.createElement('div');

}

},

customElements: {

define: () => {}

}

};

Object.freeze(window);

module.exports = window;

12

13 of 13

Examples on github

https://github.com/terodox/dotjs2019

13