[RFC] Remove custom router/vuex management for Vue 3
See original GitHub issue- 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 https://github.com/testing-library/vue-testing-library/issues/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.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:9
- Comments:10 (6 by maintainers)
Top GitHub Comments
The RFC has received several positive comments and no hard pushbacks. I’ll leave the PR open for another week and then merge it 😃
I agree about leaving the wrapper as thin as possible, leaving the responsibility to the end user as it is really simple to create a custom wrapper including your own setup with vuex, router and any other plugin that you would normally need in most of the projects.
Breaking compatibilty is not ideal but showing the warning and documenting how to migrate/create your own
custom render
with vuex/router setup should not be a problem IMO.TBH I always found problematic to pass
store
as a parameter fromVTU 2.x
as the devoloper could think thatrender
is expecting a real instance of the store (new Vuex.Store(storeDefinition
) instead of the storeDefinition that VTU internally uses to instanciate the store.TL;DR:
Thanks for this amazing library! 🤟