import { mount } from '@vue/test-utils' import { afterEach, describe, expect, it, vi } from 'vitest' import { nextTick } from 'vue' import Select from '../Select.vue' vi.mock('vue-i18n', async () => { const actual = await vi.importActual('vue-i18n') return { ...actual, useI18n: () => ({ t: (key: string) => key }), } }) afterEach(() => { document.body.innerHTML = '' vi.restoreAllMocks() }) describe('Select dropdown viewport constraints', () => { it('limits the teleported dropdown to the available viewport width', async () => { Object.defineProperty(window, 'innerWidth', { configurable: true, value: 320, }) vi.spyOn(HTMLElement.prototype, 'getBoundingClientRect').mockReturnValue({ x: 220, y: 20, top: 20, right: 300, bottom: 60, left: 220, width: 80, height: 40, toJSON: () => ({}), }) const wrapper = mount(Select, { props: { modelValue: null, options: [ { value: 'example', label: 'very-long-unbroken-option-value-that-must-not-overflow', }, ], }, }) await wrapper.get('button').trigger('click') await nextTick() const dropdown = document.body.querySelector('.select-dropdown-portal') expect(dropdown).not.toBeNull() expect(dropdown?.style.left).toBe('220px') expect(dropdown?.style.minWidth).toBe('80px') expect(dropdown?.style.maxWidth).toBe('92px') wrapper.unmount() }) })