Skip to content

Routing broken (documented use case fails) #869

Closed
@blerchin

Description

@blerchin
  • @testing-library/react version: 11.2.3
  • Testing Framework and version: jest 26.6.3
  • DOM Environment: jsdom 16.4.0

Relevant code or config:

This is directly copypasta'd from:
https://testing-library.com/docs/example-react-router/

// app.test.js
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {createMemoryHistory} from 'history'
import React from 'react'
import {Router} from 'react-router-dom'

import '@testing-library/jest-dom/extend-expect'

import {Link, Route, Switch, useLocation} from 'react-router-dom'

const About = () => <div>You are on the about page</div>
const Home = () => <div>You are home</div>
const NoMatch = () => <div>No match</div>

export const LocationDisplay = () => {
  const location = useLocation()

  return <div data-testid="location-display">{location.pathname}</div>
}

export const App = () => (
  <div>
    <Link to="/">Home</Link>

    <Link to="/about">About</Link>

    <Switch>
      <Route exact path="/">
        <Home />
      </Route>

      <Route path="/about">
        <About />
      </Route>

      <Route>
        <NoMatch />
      </Route>
    </Switch>

    <LocationDisplay />
  </div>
)

test('full app rendering/navigating', () => {
  const history = createMemoryHistory()
  render(
    <Router history={history}>
      <App />
    </Router>,
  )
  // verify page content for expected route
  // often you'd use a data-testid or role query, but this is also possible
  expect(screen.getByText(/you are home/i)).toBeInTheDocument()

  const leftClick = {button: 0}
  userEvent.click(screen.getByText(/about/i), leftClick)

  // check that the content changed to the new page
  expect(screen.getByText(/you are on the about page/i)).toBeInTheDocument()
})

test('landing on a bad page', () => {
  const history = createMemoryHistory()
  history.push('/some/bad/route')
  render(
    <Router history={history}>
      <App />
    </Router>,
  )

  expect(screen.getByText(/no match/i)).toBeInTheDocument()
})

test('rendering a component that uses useLocation', () => {
  const history = createMemoryHistory()
  const route = '/some-route'
  history.push(route)
  render(
    <Router history={history}>
      <LocationDisplay />
    </Router>,
  )

  expect(screen.getByTestId('location-display')).toHaveTextContent(route)
})

What you did:

Using React Testing Library to test react-router rendering after route change. Per docs, I provide a Router context with my own history object from createMemoryHistory.
After changing the route by clicking a link with userEvent I expect the corresponding Route to be rendered.

What happened:

The route change is reflected by the original page
subscribing components (eg. location retrieved by useLocation). However code inside the newly-matching route is not rendered. In this use case, the "You are on the about page" text never appears.

Unable to find an element with the text: /you are on the about page/i. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

<body>
  <div>
    <div>
      <a
        href="/"
      >
        Home
      </a>
      <a
        href="/https/github.com/about"
      >
        About
      </a>
      <div>
        No match
      </div>
      <div
        data-testid="location-display"
      />
    </div>
  </div>
</body>

Reproduction:

https://codesandbox.io/s/musing-http-rohnt?file=/src/docs.test.js

Problem description:

Cannot test full-app routing using testing library. Examples on the documentation site appear to be broken.

Suggested solution:

None at this point, but willing to work on a fix if someone can isolate the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions