35

I am new to react-testing-library / jest and attempting to write a test to see if the navigation of routes (using react-router-dom) is performed correctly. So far I have been following the README and this tutorial on how to use.

One of my components uses scrollIntoView in a local function and this causes the test to fail.

TypeError: this.messagesEnd.scrollIntoView is not a function

  45 |
  46 |     scrollToBottom = () => {
> 47 |         this.messagesEnd.scrollIntoView({ behavior: "smooth" });
     |                          ^
  48 |     }
  49 |
  50 | 

This is the function in my chatbot component:

componentDidUpdate() {
    this.scrollToBottom();
}

scrollToBottom = () => {
    this.messagesEnd.scrollIntoView({ behavior: "smooth" });
}

And this is a sample of the tests that fail:

test('<App> default screen', () => {

    const { getByTestId, getByText } = renderWithRouter(<App />)

    expect(getByTestId('index'))

    const leftClick = {button: 0}
    fireEvent.click(getByText('View Chatbot'), leftClick) <-- test fails

    expect(getByTestId('chatbot'))

})

I have tried to use a mock function, however the error still remains.

This is where this.messageEnd is assigned:

    <div className="chatbot">
        <div className="chatbot-messages">
            //render messages here
        </div>
        <div className="chatbot-actions" ref={(el) => { this.messagesEnd = el; }}>
            //inputs for message actions here
        </div>
    </div>

I referenced code from this stack overflow question: How to scroll to bottom in react?

SOLUTION

test('<App> default screen', () => {

    window.HTMLElement.prototype.scrollIntoView = function() {};

    const { getByTestId, getByText } = renderWithRouter(<App />)

    expect(getByTestId('index'))

    const leftClick = {button: 0}
    fireEvent.click(getByText('View Chatbot'), leftClick)

    expect(getByTestId('chatbot'))

})
Charklewis
  • 1,971
  • 2
  • 15
  • 40

2 Answers2

51

scrollIntoView is not implemented in jsdom. Here's the issue: link.

You might get it working by manually adding it:

window.HTMLElement.prototype.scrollIntoView = function() {};
Giorgio Polvara - Gpx
  • 12,268
  • 5
  • 53
  • 55
23

If we want to unit test 'scrollIntoView' function in a react application using react testing library then we can mock the function using 'jest'.

window.HTMLElement.prototype.scrollIntoView = jest.fn()
Kriti
  • 981
  • 8
  • 11
  • 3
    It's like we are mocking scrollIntoView function. – Kriti Feb 14 '20 at 13:56
  • @Kriti. Please explain how this code helps the OP solve their issue in the answer itself. Please read [this article](https://stackoverflow.com/help/how-to-answer) to get a better understanding of what an answer is. Please also go through the site [tour](https://stackoverflow.com/tour) – Suit Boy Apps Feb 14 '20 at 19:28
  • just an observation, correct would be to use without immediate invocation. So, instead of `jest.fn ()`, use `jest.fn` without parentheses. – darkziul Feb 20 '21 at 13:25
  • Problem with mocking scrollIntoView is that, although we can make the mock function to call another function, we can never be sure that the scrolling will trigger that other function in a real case. Let's take an infinite scroll, I can still pass the test and my InfiniteScroller component does not trigger a load more in real case. – KeitelDOG Mar 07 '21 at 13:19