I am working on a browser based react app, and have a problem that occurs in test code but not in the browser.
I have a requirement to scroll to an element within a scrollable div. The project I'm working on already uses react-scroll, and implementing the requirement seemed straightforward, and all works as expected in the browser.
However, when testing the component, if I carry out any action that prompts scrolling behaviour the test fails with Seems containerElement is not an ancestor of the Element
A simple minimum reducible example is
import {Element, scroller} from 'react-scroll';
import {useEffect} from 'react';
export default function Scroll() {
const scrollToBottomElement = () => {
scroller.scrollTo('atTheBottom', {
containerId: 'containerElement',
smooth: true,
duration: 300,
});
};
useEffect(scrollToBottomElement, []);
return (
<div>
<Element
name="container"
id="containerElement"
style={{
position: 'relative',
height: '100px',
overflow: 'scroll',
marginBottom: '100px',
}}
>
<Element
name="atTheTop"
style={{
marginBottom: '300px',
}}
>
top
</Element>
<Element
name="atTheBottom"
>
bottom
</Element>
</Element>
</div>
);
}
with a failing test:
import { render } from '@testing-library/react';
import Scroll from "./Scroll";
describe('Scroll', () => {
it('should render scroll without error', async () => {
render(<Scroll />);
});
});
The problem occurs when the react-scroll
library attempts to add up offsets between the scroll target and any interim elements up to the container. When we get to this line, element is the scroll target, and the value of its offsetParent
is null
(debugging in the browser on the other hand shows that the offsetParent is populated as expected).
According to MDN, there are just 3 conditions that cause offsetParent
to be null. I guess that the DOM tree as implemented by the render function in @testing-library/react
is different to that implemented by the browser, but assuming that it complies with the contract of HTMLElement
I'm not sure which of the 3 conditions might be causing the null offsetParent
.
I'm pretty new to React and Javascript, after a long time as a Java/Kotlin engineer, so I'm hoping I'm just making a silly mistake somewhere.
Below is a relevant screenshot of a debug session, with a breakpoint in the react-scroll code.