#19331·kestra

Every unit spec builds its own i18n instance to mount a component

Author: Piyush-r-bhaskarCreated Sep 10, 2026Updated Sep 17, 2026
Labelsarea/frontendkind/cooldown

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: i18nMount and i18nShallowMount. It installs i18n in English, takes messages for the keys a spec cares about or locales for a whole translation file, and merges anything passed in global over the defaults. The design-system version also installs the design-system plugin, since every spec there needs it.
  • Topology and ui-ee reuse 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 createI18n calls and duplicated plugin lists. No test assertion changes: a spec that asserted on raw keys keeps empty messages, a spec that loaded en.json keeps 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.