Running, debugging and changing the JS tests - alphagov/notifications-manuals GitHub Wiki

Running, debugging and changing the JS tests (admin app)

Folder structure

  • tests/javascripts/ contains JS test files and the config file for Jest
  • tests/javascripts/support/ contains:
    • scripts to be run before and after a test run
    • polyfills for features not included in JSDOM
    • the helpers.js module, which exports all the helper functions/classes from tests/javascripts/support/helpers/
  • tests/javascripts/support/helpers/ contains the code for all the helper functions/classes

Jest

We use the Jest framework to help write our JS tests and its CLI to run them.

Simulating the browser environment

The JS we write assumes it will run in a web browser and so have access to all the global variables and APIs available in that environment.

That includes things like

  • globals (like window.location)
  • the Document Object Model (DOM) (like document.querySelector)
  • the various Web APIs (like window.MutationObserver or window.fetch)

Our JS tests run in a NodeJS process and use JSDOM to simulate most of this but sometimes we need to stub out APIs or mock objects when they're not provided by JSDOM. For example, tests/javascripts/support/helpers/globals.js contains a helper class that mocks window.location.

We also provide helper methods to simplify more complex parts of this. For example, tests/javascripts/support/polyfills.js provides implementations of methods available on Element.prototype in most browsers but not yet added to JSDOM.

Running the tests

What follows are the most common ways to run the tests. For a full list of all the options for the jest command, see https://jestjs.io/docs/cli#options.

Running all the tests

Use the npx command to run jest on all the tests by pointing it at the test folder:

npx jest tests/javascripts/

This will just show if each testsuite (files in tests/javascripts/ ending in test.js) passes. Use the --verbose flag for output related to the tests in a testsuite.

Running a single test

You can also target a single test like so:

npx jest tests/javascripts/[name of test]

For example:

npx jest tests/javascripts/errorBanner.test.js

Debugging a test

Because the tests run in a NodeJS process, you can use the NodeJS debugger to debug your tests, and the code they test, in Chrome devtools by following these steps:

  1. insert a debugger; statement in your code where you want a breakpoint
  2. run
node --inspect-brk node_modules/.bin/jest --runInBand --config tests/javascripts/jest.config.js tests/javascripts/[name of test with breakpoint in]
  1. go to chrome://inspect in Chrome and click on the 'inspect' link below the path to open a new devtools window for debugging
  2. the debugger will stop at the first line of the Jest CLI script so press the 'play' button to advance to your first breakpoint

This is a quick version of this guide to troubleshooting jest tests.

The structure of tests

The basic structure of a JS test is:

  1. mock or stub any parts of the browser environment the JS you're testing expects to be present, if not already in JSDOM or if you need to track calls to them
  2. add the HTML to the DOM that the JS you're testing expects to be in the page when it loads
  3. import any helpers used and set up any variables used globally
  4. run your test
  5. tidy up

The following articles should help with the detail of that: