jsdom

Jest by default makes available an instance of jsdom, A JavaScript implementation of the WHATWG DOM and HTML standards, for use with node.js.

Window and Document Object

are available in the global scope

test('window', () => {
  expect(window).toBeDefined() // true
  expect(window).not.toBeNull() // true
})
test('document', () => {
  expect(document).toBeDefined() // true
  expect(document).not.toBeNull() // true
})
test('body', () => {
  expect(document.body).toBeDefined() // true
  expect(document.body).not.toBeNull() // true
})

Using Web APIs

test('change document title', () => {
  expect(document.title).toBe('')

  document.title = 'my title'

  expect(document.title).toBe('my title')
  expect(document.querySelector('head > title').innerHTML).toBe('my title')
})

Manipulating the DOM

We can manipulate the DOM as we were in the browser and make assertions of the results using common Web APIs

test('button element in jsdom', () => {
  const button = document.createElement('button')
  button.innerText = 'click me'
  document.body.appendChild(button)
  const buttons = document.querySelectorAll('button')

  expect(buttons).toHaveLength(1) // true
  expect(buttons[0].innerText).toBe('click me') // true
})

Interacting with the DOM

test('click button element in jsdom', () => {
  const button = document.createElement('button')
  button.innerText = 'click me'
  document.body.appendChild(button)
  const buttons = document.querySelectorAll('button')

  expect(buttons).toHaveLength(1) // true
  expect(buttons[0].innerText).toBe('click me') // true

  buttons[0].addEventListener('click', e => {
    e.target.innerText = 'clicked'
  })

  expect(buttons[0].innerText).not.toBe('clicked') //true

  buttons[0].dispatchEvent(new MouseEvent('click', { bubbles: true }))

  expect(buttons[0].innerText).toBe('clicked') // true
})

this is the foundation of testing using libraries such as react-dom/test-utils and react-testing-library that expect to have a DOM available.

Things to be aware of

  • every file have a different jsdom instance
  • the same jsdom instance (so the Window) is shared by all tests in a file, this can cause some tests to behave differently when run in isolation of after other tests that manipulate the DOM

Author: Jaga Santagostino

results matching ""

    No results matching ""