import { nextTick } from 'vue' import { mount } from '@vue/test-utils' import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, } from 'vitest' import { usePopperContainer } from '@element-plus/hooks' import { genTooltipProvides } from '../test-helper/provides' import ElTooltipContent from '../src/content.vue' import { TOOLTIP_INJECTION_KEY } from '../src/tokens' const AXIOM = 'rem is the best girl' describe('', () => { const { controlled, id, open, trigger, onOpen, onClose, onToggle, onShow, onHide, onBeforeShow, onBeforeHide, } = genTooltipProvides() const defaultProvide = { [TOOLTIP_INJECTION_KEY as symbol]: { controlled, id, open, trigger, onOpen, onClose, onToggle, onShow, onHide, onBeforeShow, onBeforeHide, }, } let unmount const createComponent = (props = {}, provides = {}) => { const wrapper = mount( { components: { ElTooltipContent, }, template: ``, setup() { usePopperContainer() }, }, { props, global: { provide: { ...defaultProvide, ...provides, }, stubs: ['ElPopperContent'], }, slots: { default: () => [AXIOM], }, attachTo: document.body, } ) unmount = () => wrapper.unmount() return wrapper.findComponent(ElTooltipContent) } let wrapper: ReturnType const OLD_ENV = process.env.NODE_ENV beforeAll(() => { process.env.NODE_ENV = 'test' }) afterAll(() => { process.env.NODE_ENV = OLD_ENV }) afterEach(() => { open.value = false controlled.value = false trigger.value = 'hover' unmount?.() document.body.innerHTML = '' }) describe('rendering', () => { it('should render nothing initially when not controlled', async () => { wrapper = createComponent() await nextTick() expect(wrapper.text()).toBe('') }) describe('persistent content', () => { it('should be able to inherit style', async () => { const customStyle = { position: 'absolute', } wrapper = createComponent({ style: customStyle, }) await nextTick() expect(wrapper.vm.contentStyle).toEqual(customStyle) }) }) describe('content rendering', () => { it('should not show the content when disabled', async () => { wrapper = createComponent({ disabled: true, }) await nextTick() expect(wrapper.vm.shouldShow).toBe(false) }) }) describe('events', () => { beforeEach(async () => { wrapper = createComponent() await nextTick() open.value = true await nextTick() await nextTick() }) it('should be able to enter trigger', async () => { const { vm } = wrapper expect(onOpen).not.toHaveBeenCalled() const enterEvent = new MouseEvent('mouseenter') vm.onContentEnter(enterEvent) expect(onOpen).toHaveBeenCalled() const leaveEvent = new MouseEvent('mouseleave') expect(onClose).not.toHaveBeenCalled() vm.onContentLeave(leaveEvent) expect(onClose).toHaveBeenCalled() }) it('should not trigger close event when the trigger is not hover', async () => { const { vm } = wrapper trigger.value = 'click' await nextTick() const leaveEvent = new MouseEvent('mouseleave') expect(onClose).not.toHaveBeenCalled() vm.onContentLeave(leaveEvent) expect(onClose).not.toHaveBeenCalled() }) it('should be able to stop triggering when controlled', async () => { controlled.value = true await nextTick() const { vm } = wrapper expect(onOpen).not.toHaveBeenCalled() const enterEvent = new MouseEvent('mouseenter') vm.onContentEnter(enterEvent) expect(onOpen).not.toHaveBeenCalled() const leaveEvent = new MouseEvent('mouseleave') expect(onClose).not.toHaveBeenCalled() vm.onContentLeave(leaveEvent) expect(onClose).not.toHaveBeenCalled() }) describe('onCloseOutside', () => { beforeEach(() => { // Have to mock this ref because we are not going to render the content in this component wrapper.vm.contentRef = { popperContentRef: document.createElement('div'), } as any }) it('should not close the content after click outside when trigger is hover', async () => { document.body.click() await nextTick() expect(onClose).not.toHaveBeenCalled() }) it('should not close the content after click outside when controlled', async () => { controlled.value = true trigger.value = 'click' await nextTick() document.body.click() await nextTick() expect(onClose).not.toHaveBeenCalled() }) it('should close component after click outside', async () => { trigger.value = 'click' document.body.click() await nextTick() expect(onClose).toHaveBeenCalled() }) }) }) it('should append to', async () => { const el = document.createElement('div') const id = 'test_id' el.id = id document.body.appendChild(el) wrapper = createComponent({ appendTo: `#${id}`, }) await nextTick() expect(el.children).toHaveLength(1) expect(el.querySelector('[aria-hidden="true"]')).not.toBeNull() }) }) })