testing-library / vue-testing-library

🦎 Simple and complete Vue.js testing utilities that encourage good testing practices.
http://testing-library.com/vue
MIT License
1.08k stars 110 forks source link

Navigation failure for dynamic route #196

Closed calebbergman closed 3 years ago

calebbergman commented 3 years ago

Describe the bug Navigation fails to occur when attempting to navigate to a dynamic route.

This issue may be related to Issue 130, the difference here being I'm not trying to set the initial route, but trying to perform the route navigation by clicking a link present on the page.

To Reproduce Steps to reproduce the behavior: Demo

The test ❌ fails if the route is dynamic. The test βœ… passes if the route is static.

Expected behavior βœ… Test passes

Actual behavior ❌ Test fails

Additional context Original issue reported on Discord

afontcu commented 3 years ago

Hi! Since the navigation now requires the component to load dynamically, you need to wait until the change has indeed happened. Following is a passing test:

  it('Should navigate to /about, a dynamic route, when the link is clicked', async () => {
    render(Component, {
      routes: [  // unrelated, but you can use the `routes` option to create a vue router instead of using the vue instance
        {
          path: '/',
          name: 'Home',
          component: Home,
        },
        {
          path: '/about',
          component: () => import('./components/Router/About.vue'),
        },
      ],
    })
    const route = screen.getByTestId('route')
    expect(route.textContent).toBe('/')
    const link = screen.getByText('About')
    await fireEvent.click(link)

    // wait until route.textContent has changed
    await waitFor(() => expect(route.textContent).toBe('/about'))
  })
calebbergman commented 3 years ago

Hey! πŸ˜„

That definitely makes sense and fixes the problem in my contrived demo.

I originally had run across this issue in production code. Coming back to it after having some vacation time, I think I discovered my issue was compounded by a couple of other mistakes of mine:

  1. I was silly and forgot to assign a component to the route altogether that I was testing πŸ€¦β€β™‚οΈ
  2. I was attempting to test routing by mounting a component ( render(Home) ) for which said component was the component for the route ( { path: '/Home', component: Home } ), instead of its containing component (i.e. App.vue) that has the <router-view /> tag...if that makes sense.

After moving the data-testid=route div to App.vue and the test to App.spec.ts (from Home.vue and Home.spec.ts) , I was able to get the test to pass using await waitFor().

I am still having issues getting to render what I'm expecting via routing, but that's not related to this issue of dynamic routing, so this can be closed 😊

Thanks so much @afontcu!

calebbergman commented 3 years ago

While moving stuff around in my production tests I realized I had written const router = new VueRouter(routes) instead of const router = new VueRouter({ routes }), wrapping routes in an options object (οΌβ€Έαƒš) Rending the route components works great now, go figure πŸ˜…

afontcu commented 3 years ago

Vacation time does always help! πŸ˜„ Glad to hear you worked it out.