diff --git a/components/menu/__tests__/demo.test.js b/components/menu/__tests__/demo.test.js new file mode 100644 index 000000000..ad45d6588 --- /dev/null +++ b/components/menu/__tests__/demo.test.js @@ -0,0 +1,3 @@ +import demoTest from '../../../tests/shared/demoTest'; + +demoTest('menu'); diff --git a/components/menu/__tests__/index.test.js b/components/menu/__tests__/index.test.js new file mode 100644 index 000000000..ed370bc10 --- /dev/null +++ b/components/menu/__tests__/index.test.js @@ -0,0 +1,542 @@ +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'; + +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'); + }, 500); + + 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'); + }, 500); + 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')[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')[0].classes()).toContain('ant-menu-vertical'); + // expect(wrapper.findAll('ul.ant-menu-sub').length).toBe(0); + // }, 500); + wrapper.setProps({ inlineCollapsed: false }); + await asyncExpect(() => { + expect(wrapper.findAll('ul.ant-menu-sub')[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(() => { + // $$('.ant-menu-submenu-title')[0].dispatchEvent(new MouseEvent('mouseenter')); + // }); + // await asyncExpect(() => { + // expect(wrapper.findAll('.ant-menu-submenu')[0].classes()).toContain( + // 'ant-menu-submenu-vertical', + // ); + // expect(wrapper.findAll('.ant-menu-submenu')[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'); + // }, 500); + }); + + describe('open submenu when click submenu title', () => { + beforeEach(() => { + document.body.innerHTML = ''; + }); + + const toggleMenu = (wrapper, index, event) => { + wrapper.findAll('.ant-menu-submenu-title')[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'); + }, 100); + 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); + }); +});