React Testing Library (Rtl): Test a Responsive Design

React Testing Library (RTL): test a responsive design

TLDR; You will not be able to test media-queries with current setup (jest-dom).

After debugging and going through github repository of jest-dom, it seems it will be pretty hard to test what responsive design.

There are couple of issue with the way, jest-dom (which uses jsdom) library renders component and calculates style.

To begin with, it doesn't attach/compute styles from attached stylesheet. This came with surprise to me as I am used to test UI with Angular setup. As mentioned in the attached link, you can try to overcome this issue by manually creating style element

const style = document.createElement('style')
style.innerHTML = `
@media screen and (min-width: 500px) {
.title .adjectives {
display: none;
color: red;
}
}
`;
document.body.appendChild(style)

or use helper function to do that as suggested in this bug.

After this change, I assumed it would work but to my surprise, it FAILED!, I checked with non-media query style and it was attaching style perfectly and that's when I discovered this TODO comment in jsdom, which makes sense as media-query styles are not working.

To conclude, it will not be possible to test media-query at the moment with react-testing-library. I haven't checked if it is working with enzyme setup, but it might who knows!

on you can use end to end testing framework such as Cypress.

React Testing Library - Failing to test Window Resize React Hook

I think there are a few things you have to change to make your test working again:

  • You haven't waited to your debounce function work which is the main problem. So you can use either mock the timer or wait until your debounce function getting called.
// Make your test as `async` in case of wanting to wait
test("should return new values on window resize", async () => {
// If you go for mocking timer, uncomment this & below advance the timer
// jest.useFakeTimers();
const { result } = renderHook(() => useViewportSize());

act(() => {
window.resizeTo(500, 500);
//fireEvent(window, new Event("resize"));
});

// jest.advanceTimersByTime(251) // you can also use this way
await mockDelay(debounceDelay); // `await` 300ms to make sure the function callback run

expect(result.current.width).toBe(500);
expect(result.current.height).toBe(500);
});

  • You might refine your implementation code by changing to use your mock value instead:
const debouncedHandleResize = debounce(() => {
setViewportSize({
// using your mock values
width: window.innerWidth,
height: window.innerHeight
});
}, debounceTime);

PS: I also edited your codesandbox based on the async way: https://codesandbox.io/s/useviewportsize-forked-pvnc1?file=/src/use-viewport-size.test.tsx

ant design v4 breaks react testing library tests for Select and Autocomplete

After losing 2 days on this, here is the problem and solution:

Problem

In antd v3 it used to be possible to open a Select by doing selectHtmlElement.click(). You can test in the chrome dev tools console. In v4 this does not work.

This means that RTL which uses JSDOM under the hood will have the same behaviour. When you do fireEvent.click(selectElement); nothing happens !

Solution

This put me on the right track: https://github.com/ant-design/ant-design/issues/22074

The event you need to trigger is not a click() but a mouseDown() on the first child of the select.

const elt = getByTestId('your-select-test-id').firstElementChild;
fireEvent.mouseDown(elt); // THIS WILL OPEN THE SELECT !

Now at this point you probably want to select an option from the list but there is an animation going on so the following code (that used to work in v3) will also fail.

expect(getByText('Option from Select')).toBeVisible(); // FAILS !

You have 2 options, use toBeInTheDocument() or wait for the animation to be over by using waitFor(...)

Option 1: Faster but not totally accurate, I prefer to use this for simple use cases as it makes the tests faster and synchronous

expect(getByText('Option from Select')).toBeInTheDocument(); // WORKS !

Option 2: Slower as you need to wait for the animation to finish but more accurate for complex cases

await waitFor(() => expect(getByText('Option from Select')).toBeVisible()); // WORKS !

react-testing-library - Screen vs Render queries

The latest recommended option by the react-testing-library author Kent C. Dodds himself is to use screen.

The benefit of using screen is you no longer need to keep the render call destructure up-to-date as you add/remove the queries you need. You only need to type screen. and let your editor's magic autocomplete take care of the rest.

The only exception to this is if you're setting the container or baseElement which you probably should avoid doing (I honestly can't think of a legitimate use case for those options anymore and they only exist for historical reasons at this point).

Source: https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen



Related Topics



Leave a reply



Submit