Skip to content

[RFC] Remove custom router/vuex management for Vue 3 #205

Closed
@afontcu

Description

@afontcu
  • Target Major Version: 6.x (VTL version for Vue 3)

Summary

Remove custom integrations for Vue Router and Vuex, and leave it to users to configure them as they'd do with any other plugin.

Currently, VTL for Vue 3 offers basic support for Router and Vuex, similar to VTL for Vue 2. It requires router/vuex library if the appropriate render option is provided, creates the plugin and adds it to global.plugins. See source.

Basic example

VTL would remove support for store and routes keys on render:

render(Component, {
  props: { ... },
-  store: {},
-  routes: {}
})

in favor of VTU' global.plugins (docs).

import { render } from '@testing-library/vue'
import Component from './Component'
import myStore from './store'
import myRoutes from './routes'
import { createRouter, createWebHistory } from 'vue-router'

const store = createStore(myStore)

// Assume myRoutes contains an array with routes.
const router = createRouter({
  history: createWebHistory(),
  myRoutes
})

test('test with router and vuex', () => {
  render(Component, {
    global: {
      plugins: [store, router]
    }
  })  
})

This is the suggested way to install Router/Vuex in VTU 2.x, too (see here and here).

Strictly speaking, removing integration with Vuex is not needed. However, it would be weird to only support one of the official Vue plugins, and treat the other one as a regular plugin.

Motivation

This RFC is motivated by the discussion in #195. In short:

Vue Router is now async, so it needs special treatment when it comes to navigating (simple – just use waitFor or findByXXX queries), but also if user needs to assert something related to first navigation (Router exposes a router.isReady() helper). This makes an out-of-the-box management from VTL a bit… weird.

Detailed design

There's not much to do on VTL. VTU 2.x offers a comfortable way to install global plugins to vue 3 app through global.plugins, so this is way simpler than Vue 2 (where we needed to use a local Vue instance).

We're already installing anything provided through globals.plugins, so we should good to go. It's just a matter of docs + removing routes/store options.

The change would make users responsible for setting up router/vuex properly. This is the exact same thing React Testing Library users have to do (see an example for React Router and another one for Reach Router).

Drawbacks

  • Users need to initialize router/vuex. This is not the case with VTL for Vue 2, where we import the libraries when needed and attach them to the local vue instance.

Alternatives

  • Keep handling Router/Vuex the best way we can. In the original issue I outlined some alternatives that involved making render async or exposing a isRouterReady helper method. Both of the alternatives help us hide some of the complexity, but not all of it.

Adoption strategy

We're still in beta here, so any breaking change is undesirable but expected.

People would need to:

  1. Remove routes and store keys from their tests.
  2. Wrap routes with VueRouter.createRouter (and potentially register a history method.
  3. Wrap store with Vuex.createStore.
  4. Move both variables down to global.plugins.

We could display a warning message to make people aware of why router/vuex tests start failing:

function render(
  Component,
  {
    store = null,
    routes = null,
    // ...
  },
) {
  if (store || routes) {
    console.warning(`Using store/routes options is now deprecated.
      Please provide them as plugins through 'global.plugins' parameter.
      See here an example of how to integrating them into VTL: (add link)`)
  }
}

The message would be removed before marking VTL for Vue 3 as stable.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions