Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This document is a starting/reference guide for writing unit tests for the UI modules within ERM. 

...

Before moving on to an example, queries are an important ascpect of testing and choosing the right query within your tests is crucial.

Queries are the methods that RTL gives you to find elements on the page. There are a number of ways in which we can grab an element on a page. 

The following table describes the selectors that you need to use as a priority.

Image Modified

Priority should be give according to the priorities listed here.

...

           To grab a button by the label Save & close, you can either use:

     1) getByRole('button', { name: 'Save & close' })
2) getBylabelText('Save & close')
     Note: You might be tempted to pass data-testid to an element and find an element using the getByTestId query. This attribute is 
provided by RTL only as an escape hatch and should be avoided wherever possible. The attribute is going to eventualy end up
on the dom and we do not want to pollute the dom with avoidable attributes.

...

const onAdd = jest.fn();
const onSubmit = jest.fn();

const basketSelectorProps = {
'addButtonLabel':'add button',
'autoFocus':true,
'basket':[{
'id':'5650325f-52ef-4ac3-a77a-893911ccb666',
'class':'org.olf.kb.Pkg',
'name':'Edward Elgar:Edward Elgar E-Book Archive in Business & Management, Economics and Finance:Nationallizenz',
'suppressFromDiscovery':false,
'label': 'basketSelector'
}]
};

describe('BasketSelector', () => {
test('renders add To Basket button', () => {
const { getByText } = renderWithIntl(
<TestForm onSubmit={onSubmit}>
<BasketSelector {...basketSelectorProps}/>
</TestForm>
);

   expect(getByLabelText(/basketSelector/i)).toBeInTheDocument();
userEvent.click(getByText('add button'));
expect(onAdd.mock.calls.length).toBe(1);
});
});

...

Idealy we would like to have 100% coverage on all the components. Sometimes it feels too trivial to cover certain cases, i.e. the effort in writing the test outweighs the condition you are checking for and that decision is left to the developer.

Using Interactors:

One of the advantages of having a custom design system and component library within FOLIO is that we don't start from scratch when writing tests that target an application using it. We know very precisely what the structure the DOM will take, and we can use that knowledge to our advantage when it comes to writing tests, both for manipulating the UI and also for making assertions against it.

Interactors provide us an abstraction between the HTML of our tests, so that not only are tests easy to write, but as the underlying components change and evolve, the tests do not need to change. 

Refer the documentation for interactors to find the list of all the interactors currently available.

           I think a good way to understand how tests need to be structured/written using the interactors is to differentiate between the traditional RTL approach and the interactors way.

           So, imagine  Imagine we are writing a test to assert that a button (rendered via the stripes component Button component) with a specific label is rendered.

           RTL approach:
expect(getByLabelText(/Add Button/)).toBeInTheDocument;

Using Interactors:
await Button('Add Button').exists();

...

The Button interactor here targets the Stripes component Button under the hood via a css selector which we dont have to worry about while writing the test and can just be confident that if there is a button in the 

...

       dom with a label Add Button the interactor will catch that button.

           The EresourceSections have a good set of tests that currently use the MCL, KeyValue, Button and TextField interactors. The documentation for the interactors as pointed above list all the different types of filters,                      actions and locators that the interactor accepts.

...