Every unit spec builds its own i18n instance to mount a component
Almost every unit spec that mounts a component starts by building its own vue-i18n instance: import createI18n, call it with legacy: false and locale: "en", decide whether to pass messages, then hand it to mount through global.plugins. Across ui, the design system, topology and ui-ee that is 164 specs doing the same setup with small variations, and none of the packages has a shared mount helper.
That has a cost beyond the noise. When a design-system component started using $t, the specs that mounted it without an i18n plugin failed with _ctx.$t is not a function, which reads like a component bug rather than missing test setup. A shared helper makes that mistake impossible.
What to do:
- Add one mount helper per package, next to the existing test setup:
i18nMountandi18nShallowMount. It installs i18n in English, takesmessagesfor the keys a spec cares about orlocalesfor a whole translation file, and merges anything passed inglobalover the defaults. The design-system version also installs the design-system plugin, since every spec there needs it. - Topology and
ui-eereuse the OSS helper, the way the translation tooling and the test setup already do, instead of getting a copy. - Convert the specs to it and delete the local
createI18ncalls and duplicated plugin lists. No test assertion changes: a spec that asserted on raw keys keeps empty messages, a spec that loadeden.jsonkeeps loading it.
Two config fixes belong with it. ui-ee has to pin @vue/test-utils and vue-i18n to its own node_modules, as it already does for vue, otherwise the shared helper mounts through a second copy of test-utils that never sees the global stubs and router set up in setup.ts. And the topology package's vitest config needs the same Node 26 localStorage line the other packages already have, which is why its Duration spec fails locally today.
Source: kestra-io/kestra