Intelligence Community Design System ICDS Get started Accessibility Styles Components Patterns Community
Show navigation section

Testing with Jest and React Testing Library

About Jest

Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly.

These instructions have been written with JavaScript in mind. Jest also supports TypeScript. Further instructions on how to set up Jest for TypeScript can be found on their 'Getting Started' page.

More information on setting up Jest can be found on Jest’s Getting Started page .

Testing with React components

The@ukic/react package will need to be transformed before you can use these components in Jest tests.

Add atransformIgnorePatterns field with the value["/node_modules/(?!@ukic/react)"] to your Jest config.

About React Testing Library

React Testing Library (RTL) provides a set of utility functions, which interrogate the DOM tree, in order to build maintainable React tests. The recommended approach with RTL is to test React components based on how the users view the components rather than the implementation of the component. For example, a user wouldview a button by the label 'Add', so the library provides a method called getByText() to facilitate that.

Shadow DOM Testing Library

It is not possible to exclusively use RTL to test @ukic/react components as they are React-wrapped web components, which use the shadow DOM (<ShadowRoot> ). RTL does not provide utility functions that traverse beyond the shadow DOM. With the addition of Shadow DOM Testing Library , elements within the shadow DOM can be selected and then interacted with by using methods provided by RTL. Shadow DOM Testing Library provides functions with 'Shadow' prefixed to the query type (for example,getByShadowText() ).

// DOM tree for IcAlert.
<ic-alert class="dark hydrated" message="Foo" role="alert"><ShadowRoot>
    ...
    <ic-typography class="ic-typography-body hydrated"><ShadowRoot><slot /></ShadowRoot>
      Foo
    </ic-typography>
    ...
  </ShadowRoot></ic-alert>

Example: Testing multiple components

Below is an example of testing@ukic/react components within an ICDS ‘test app’ using RTL, Jest and Shadow DOM Testing Library.

jest.test.tsx Component.tsx types.ts constants.ts methods.ts
it('fills out values on the chooseCoffee page, tests for an error, and submits',async()=>{
container.addEventListener("icChange", callbackFn);
// Check the current form step
const stepOne = container.querySelector('ic-step[heading="Choose coffee"]')asHTMLIcStepElement;
expect(stepOne.type).toBe(stepStates.current);
// Select radio-option from ic-radio-group
const coffeeRadio = container.querySelector(
'ic-radio-option[value="house"]'
)asHTMLIcRadioOptionElement;
await user.click(coffeeRadio);
expect(callbackFn).toHaveBeenCalled();
expect(coffeeRadio.selected).toBe(true);
// Try submitting to see error state
const coffeeSubmit = screen.getByShadowTestId("coffee-submit-btn")asHTMLIcButtonElement;
await user.click(coffeeSubmit);
// ic-alert should be visible
const alert = container.querySelector('ic-alert')asHTMLIcAlertElement;
expect(alert).not.toBeNull();
// Select size from ic-select
const sizeSelect = container.querySelector('ic-select[label="Size"]')asHTMLIcSelectElement;
// await user.click(sizeSelect);
// find ic-menu in the shadowRoot of ic-select
const sizeMenuOption =awaitfindByShadowLabelText(sizeSelect,"250g")
await user.click(sizeMenuOption);
expect(callbackFn).toHaveBeenCalled();
// Submit first page of form
await user.click(coffeeSubmit);
expect(logSpy).toHaveBeenNthCalledWith(2,filledForm());
});

Last reviewed 16 December 2024 .
Navigated to Testing with Jest and React Testing Library - Intelligence Community Design System