Description
- 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 aisRouterReady
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:
- Remove
routes
andstore
keys from their tests. - Wrap
routes
withVueRouter.createRouter
(and potentially register ahistory
method. - Wrap
store
withVuex.createStore
. - 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.