import { mount } from '@vue/test-utils'; import { asyncExpect } from '@/tests/utils'; import Menu from '..'; import { InboxOutlined, PieChartOutlined } from '@ant-design/icons-vue'; import mountTest from '../../../tests/shared/mountTest'; jest.mock('mutationobserver-shim', () => { global.MutationObserver = function MutationObserver() { this.observe = () => {}; this.disconnect = () => {}; }; }); const { SubMenu } = Menu; function $$(className) { return document.body.querySelectorAll(className); } describe('Menu', () => { mountTest({ render() { return ( ); }, }); beforeEach(() => { document.body.innerHTML = ''; // jest.useFakeTimers() }); afterEach(() => { // jest.useRealTimers() }); it('If has select nested submenu item ,the menu items on the grandfather level should be highlight', async () => { mount( { render() { return ( Option 1 Option 2 Option 3 Option 4 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-submenu-selected').length).toBe(1); }); }); it('should accept defaultOpenKeys in mode horizontal', async () => { mount( { render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }); }); it('should accept defaultOpenKeys in mode inline', async () => { mount( { render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }); }); it('should accept defaultOpenKeys in mode vertical', async () => { mount( { render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }); }); it('horizontal', async () => { const wrapper = mount( { props: { openKeys: { type: Array, default() { return ['1']; }, }, }, render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }); wrapper.setProps({ openKeys: [] }); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); }, 0); wrapper.setProps({ openKeys: ['1'] }); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }, 0); }); it('inline', async () => { const wrapper = mount( { props: { openKeys: { type: Array, default() { return ['1']; }, }, }, render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].style.display).not.toBe('none'); }); wrapper.setProps({ openKeys: [] }); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].style.display).toBe('none'); }, 0); wrapper.setProps({ openKeys: ['1'] }); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].style.display).not.toBe('none'); }, 0); }); it('vertical', async () => { const wrapper = mount( { props: { openKeys: { type: Array, default() { return ['1']; }, }, }, render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }); wrapper.setProps({ openKeys: [] }); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); }, 0); wrapper.setProps({ openKeys: ['1'] }); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }, 0); }); // https://github.com/ant-design/ant-design/pulls/4677 // https://github.com/ant-design/ant-design/issues/4692 // TypeError: Cannot read property 'indexOf' of undefined it('pr #4677 and issue #4692', () => { const wrapper = mount( { render() { return ( menu1 menu2 ); }, }, { attachTo: 'body', sync: false }, ); wrapper.vm.$forceUpdate(); // just expect no error emit }); it('should always follow openKeys when mode is switched', async () => { const wrapper = mount( { props: { mode: { type: String, default: 'inline', }, }, render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); }); wrapper.setProps({ mode: 'vertical' }); await asyncExpect(() => { expect($$('ul.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); }, 0); wrapper.setProps({ mode: 'inline' }); await asyncExpect(() => { expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); }, 0); }); it('should always follow openKeys when inlineCollapsed is switched', async () => { const wrapper = mount( { props: { inlineCollapsed: { type: Boolean, default: false, }, }, render() { return ( Option Option Option ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect( wrapper .findAll('ul.ant-menu-sub') .at(0) .classes(), ).toContain('ant-menu-inline'); expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); }, 0); wrapper.setProps({ inlineCollapsed: true }); await asyncExpect(() => { // 动画完成后的回调 wrapper.vm.$refs.menu.switchModeFromInline = false; wrapper.vm.$forceUpdate(); }); await asyncExpect(() => { wrapper.trigger('transitionend', { propertyName: 'width' }); }); await asyncExpect(() => { expect( wrapper .findAll('ul.ant-menu-root') .at(0) .classes(), ).toContain('ant-menu-vertical'); expect(wrapper.findAll('ul.ant-menu-sub').length).toBe(0); }, 0); wrapper.setProps({ inlineCollapsed: false }); await asyncExpect(() => { expect( wrapper .findAll('ul.ant-menu-sub') .at(0) .classes(), ).toContain('ant-menu-inline'); expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); }, 0); }); it('inlineCollapsed should works well when specify a not existed default openKeys', async () => { const wrapper = mount( { props: { inlineCollapsed: { type: Boolean, default: false, }, }, render() { return ( Option Option Option ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect(wrapper.findAll('.ant-menu-sub').length).toBe(0); }); wrapper.setProps({ inlineCollapsed: true }); await asyncExpect(() => { // 动画完成后的回调 wrapper.vm.$refs.menu.switchModeFromInline = false; wrapper.vm.$forceUpdate(); }); await asyncExpect(() => { wrapper.trigger('transitionend', { propertyName: 'width' }); }); await asyncExpect(() => { wrapper .findAll('.ant-menu-submenu-title') .at(0) .trigger('mouseenter'); }); await asyncExpect(() => { expect( wrapper .findAll('.ant-menu-submenu') .at(0) .classes(), ).toContain('ant-menu-submenu-vertical'); expect( wrapper .findAll('.ant-menu-submenu') .at(0) .classes(), ).toContain('ant-menu-submenu-open'); expect($$('ul.ant-menu-sub')[0].className).toContain('ant-menu-vertical'); expect($$('ul.ant-menu-sub')[0].style.display).not.toBe('none'); }, 300); }); describe('open submenu when click submenu title', () => { beforeEach(() => { document.body.innerHTML = ''; }); const toggleMenu = (wrapper, index, event) => { wrapper .findAll('.ant-menu-submenu-title') .at(index) .trigger(event); }; it('inline', async () => { const wrapper = mount( { render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub').length).toBe(0); toggleMenu(wrapper, 0, 'click'); }, 0); await asyncExpect(() => { expect($$('.ant-menu-sub').length).toBe(1); expect($$('.ant-menu-sub')[0].style.display).not.toBe('none'); toggleMenu(wrapper, 0, 'click'); }, 500); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].style.display).toBe('none'); }, 500); }); it('vertical', async () => { const wrapper = mount( { render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub').length).toBe(0); toggleMenu(wrapper, 0, 'mouseenter'); }, 0); await asyncExpect(() => { expect($$('.ant-menu-sub').length).toBe(1); expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); toggleMenu(wrapper, 0, 'mouseleave'); }, 500); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); }, 500); }); it('horizontal', async () => { const wrapper = mount( { render() { return ( Option 1 Option 2 menu2 ); }, }, { attachTo: 'body', sync: false }, ); await asyncExpect(() => { expect($$('.ant-menu-sub').length).toBe(0); toggleMenu(wrapper, 1, 'mouseenter'); }, 0); await asyncExpect(() => { expect($$('.ant-menu-sub').length).toBe(1); expect($$('.ant-menu-sub')[0].parentElement.style.display).not.toBe('none'); toggleMenu(wrapper, 1, 'mouseleave'); }, 500); await asyncExpect(() => { expect($$('.ant-menu-sub')[0].parentElement.style.display).toBe('none'); }, 500); }); }); it('inline title', async () => { const wrapper = mount( { render() { return ( Option 1 test ); }, }, { sync: false, attachTo: 'body' }, ); wrapper.find('.ant-menu-item').trigger('mouseenter'); await asyncExpect(() => { const text = $$('.ant-tooltip-inner')[0].textContent; expect(text).toBe('bamboo lucky'); }, 500); }); });