Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I want to update Vue to the latest version for a couple of reasons, but the latest Vue seems to require a later version of Vue Test Utils (VTU) than what we're using. I tried updating VTU to the latest, but I ran into a separate issue. This PR resolves that issue and updates VTU to the latest. Once this PR is merged, I'll update Vue itself.
The issue I ran into has to do with access to global properties. Many tests make assertions about or otherwise reference global properties, specifically
$route
and$router
. However, it looks like when they're accessed from thevm
property of the VTU wrapper, global properties areundefined
. For example, in a test that makes an assertion aboutapp.vm.$route.path
, I see this error:This issue seems to be specific to global properties. Other properties of the
vm
property are accessible, including properties passed todefineExpose()
and properties passed to themocks
option of the VTUmount()
function. Evenvm.$i18n
is accessible: it looks likevm.$i18n
isn't a global property and instead is defined by a global mixin. However,$route
and$router
are global properties.Central Frontend only defines a single global property of its own:
$tcn
. If I logvm.$tcn
in testing, I can see that$tcn
is also nowundefined
. So it really seems to be all global properties that are affected.To be clear, components themselves don't seem to be throwing errors. Components appear to be able to access global properties. It's just the
vm
property of the VTU wrapper that no longer provides access to those properties.Searching issues in the VTU repo, vuejs/test-utils#2008 sounds very similar. Based on that discussion, it's possible that this issue will go away once we upgrade some of our Frontend infrastructure, including by moving to Vite (#671). However, it'd be great to upgrade Vue and VTU before making the move to Vite. It's also not completely clear from the issue what the solution ended up being (though I've now asked). I did try just updating to the latest Vue (updating
vue
and@vue/compiler-sfc
in addition to@vue/test-utils
), but that didn't help.vuejs/test-utils#1869 also came up in my search, but I don't think it's related. That issue pointed specifically to Options API components with a
setup()
function, but in Central Frontend,vm.$route
seems to beundefined
for all components. The issue also highlighted global properties whose names start with$
. However, even if I rename the$tcn
global property totcn
,vm.tcn
isundefined
.I considered a few different workarounds for this issue. Since
app.vm.$container
is still accessible (since it's a VTU mock), I could have replaced all instances ofvm.$route
withvm.$container.router.currentRoute.value
. However, I wanted to avoid changing a lot of tests, andvm.$route
is nice and short. I also didn't want to change how things work in production.Ultimately, I was able to resolve the issue by modifying our
mount()
function.mount()
will now make$route
and$router
accessible by shadowing them with computed properties that reference$container
. The Vue docs about global properties imply that shadowing is allowed. The values of the computed properties should be exactly the same as the global properties, but because they're computed properties on the component (injected by a global mixin), they're accessible fromvm
. This strategy is similar to how Vue I18n is set up, as Vue I18n is able to avoid global properties by using a global mixin.Besides working on this issue, I did a quick search of VTU release notes for other breaking changes. I didn't see anything, and once the issue here was resolved, tests started passing again. 🎉 I also confirmed that tests continue to pass after updating to the latest Vue (but I'll do that update in a follow-up PR).
Before submitting this PR, please make sure you have:
npm run test
andnpm run lint
and confirmed all checks still pass OR confirm CircleCI build passes