1import { config } from '@vue/test-utils'; 2import { vi } from 'vitest'; 3 4// Make Math.random deterministic for stable snapshots (e.g., IDs in components) 5vi.spyOn(Math, 'random').mockReturnValue(0.123456789); 6 7// Stub SVG component imports to avoid verbose path data in snapshots 8const SvgStub = { 9 template: '<svg data-testid="svg-stub"><title>SVG Stub</title></svg>', 10}; 11vi.mock('@/assets/images/logo-header.svg?component', () => ({ 12 default: SvgStub, 13})); 14vi.mock('@/assets/images/login-company-logo.svg?component', () => ({ 15 default: SvgStub, 16})); 17vi.mock('@/assets/images/built-on-openbmc-logo.svg?component', () => ({ 18 default: SvgStub, 19})); 20 21// Mock vue-router - provide a minimal API for tests that import it 22vi.mock('vue-router', () => ({ 23 createRouter: () => ({}), 24 createMemoryHistory: () => ({}), 25 useRouter: () => ({ 26 push: vi.fn(), 27 replace: vi.fn(), 28 }), 29 useRoute: () => ({ 30 params: {}, 31 query: {}, 32 meta: { title: '' }, 33 }), 34})); 35 36// Use the real i18n instance - Vite's import.meta.glob works natively 37import i18n from '@/i18n'; 38 39// Provide default global mocks/stubs 40config.global.mocks = { 41 $t: (k) => k, 42 $route: { meta: { title: '' } }, 43 $eventBus: { 44 on: () => {}, 45 off: () => {}, 46 emit: () => {}, 47 $on: () => {}, 48 $off: () => {}, 49 $emit: () => {}, 50 }, 51}; 52 53// Stubs with single root elements to properly inherit attributes like data-test-id 54config.global.stubs = { 55 'router-link': { template: '<a><slot/></a>' }, 56 'b-navbar': { template: '<nav><slot/></nav>' }, 57 'b-navbar-brand': { template: '<div><slot/></div>' }, 58 'b-navbar-nav': { template: '<div><slot/></div>' }, 59 'b-dropdown': { template: '<div><slot/></div>' }, 60 'b-dropdown-item': { template: '<div><slot/></div>' }, 61 'b-nav': { template: '<ul class="nav mb-4 flex-column"><slot/></ul>' }, 62 'b-nav-item': { template: '<li><slot/></li>' }, 63 'b-collapse': { template: '<ul><slot/></ul>' }, 64 'b-button': { template: '<button><slot/></button>' }, 65 'b-input-group': { template: '<div class="input-group"><slot/></div>' }, 66 'b-input-group-prepend': { 67 template: '<div class="input-group-prepend"><slot/></div>', 68 }, 69 'b-input-group-text': { 70 template: '<span class="input-group-text"><slot/></span>', 71 }, 72 'b-form-group': { template: '<div class="form-group mb-2"><slot/></div>' }, 73 'b-form-input': { template: '<input class="form-control search-input" />' }, 74 'b-form-checkbox': { template: '<div class="form-check"><slot/></div>' }, 75 'b-form-radio': { template: '<div class="form-check"><slot/></div>' }, 76 'b-form-select': { template: '<select><slot/></select>' }, 77 'b-progress': { template: '<div class="progress"><slot/></div>' }, 78 'b-progress-bar': { template: '<div class="progress-bar"></div>' }, 79 'b-modal': { template: '<div class="modal"><slot/></div>' }, 80 'b-tooltip': { template: '<div><slot/></div>' }, 81}; 82 83// Provide plugins - i18n for useI18n() support, and $root helpers 84config.global.plugins = [ 85 i18n, 86 { 87 install(app) { 88 app.config.globalProperties.$root = 89 app.config.globalProperties.$root || {}; 90 if (!app.config.globalProperties.$root.$on) { 91 app.config.globalProperties.$root.$on = () => {}; 92 } 93 if (!app.config.globalProperties.$root.$emit) { 94 app.config.globalProperties.$root.$emit = () => {}; 95 } 96 app.mixin({ 97 beforeCreate() { 98 const r = this.$root; 99 if (r && !r.$on) r.$on = () => {}; 100 if (r && !r.$emit) r.$emit = () => {}; 101 }, 102 }); 103 }, 104 }, 105]; 106 107// Stub bootstrap-vue directives 108config.global.directives = { 109 'b-tooltip': () => {}, 110 'b-toggle': () => {}, 111}; 112