IntersectionObserver
The @archibald/testing package provides a set of functions to work with IntersectionObserver object.
import {
mockIntersectionObserver,
resetIntersectionObserver,
triggerMockIntersection,
unmockIntersectionObserver,
intersectionMockInstance
} from '@archibald/testing';
// Mock global IntersectionObserver instance.
mockIntersectionObserver();
// Reset global IntersectionObserver instance to default one.
unmockIntersectionObserver();
// Reset internal instance, observation maps and spies.
// It preserve mocked global IntersectionObserver instance.
resetIntersectionObserver();
// Change the intersection state of an element
triggerMockIntersection(ELEMENT, true / false);
// Get IntersectionObserver instance of any observed DOM element.
intersectionMockInstance(ELEMENT);
Example
Let's have a look at the following example.
function TestComponent() {
const { setRef, isVisible } = useIsVisible({ multiple: true });
return (
<div ref={setRef} data-testid="area">
{isVisible ? 'Area visible' : 'Area not visible'}
</div>
);
}
export default TestComponent;
In this example useIsVisible hook from @archibald/client package is used to register an intersection observer. The hook is used with the option multiple set to true. This means that the intersection observe can be triggered multiple times.
A test for this component could look like following:
// Other imports
import { act, mockIntersectionObserver, render, triggerMockIntersection, unmockIntersectionObserver } from '@archibald/testing';
const areaVisibleText = 'Area visible';
const areaNotVisibleText = 'Area not visible';
describe('<TestComponent /> component', () => {
beforeAll(() => {
mockIntersectionObserver();
});
afterAll(() => {
unmockIntersectionObserver();
});
it('should render', async () => {
const component = render(<TestComponent />);
const areaEl = await component.findByTestId('area');
expect(areaEl).toHaveTextContent(areaNotVisibleText);
act(() => {
triggerMockIntersection(areaEl, true);
});
expect(areaEl).toHaveTextContent(areaVisibleText);
act(() => {
triggerMockIntersection(areaEl, false);
});
expect(areaEl).toHaveTextContent(areaNotVisibleText);
});
});
In this test following is done:
mockIntersectionObserverfunction is registered to be called inbeforeAllfunction to register a mockedIntersectionObserverinstance before all tests start.unmockIntersectionObserverfunction is registered to be called inafterAllfunction to restore originalIntersectionObserverinstance after all tests are finished.- In the
it-block:TestComponentcomponent is rendered.- Intersection is enabled using
triggerMockIntersectionfunction. - Intersection is disabled using
triggerMockIntersectionfunction.