UNPKG

uiv

Version:

Bootstrap 3 components implemented by Vue.

602 lines (570 loc) 21.1 kB
import { createWrapper, sleep, triggerEvent } from '../../__test__/utils'; describe('Popover', () => { beforeEach(() => { document.body.style.display = 'flex'; document.body.style.justifyContent = 'center'; document.body.style.alignItems = 'center'; document.body.style.paddingTop = '200px'; }); afterEach(() => { document.body.style.display = ''; document.body.style.justifyContent = ''; document.body.style.alignItems = ''; document.body.style.paddingTop = ''; }); it('should be ok to render if no trigger present', async () => { const wrapper = createWrapper( '<popover v-model="show" title="123"><button data-role="trigger"></button></popover>', { show: true, } ); const vm = wrapper.vm; await vm.$nextTick(); }); it('should clear all timeouts before destroy', async () => { const wrapper = createWrapper( '<popover ref="popover" v-model="show" title="123"></popover>', { show: false } ); const vm = wrapper.vm; vm.$refs.popover.hideTimeoutId = 1; vm.$refs.popover.showTimeoutId = 2; vm.$refs.popover.transitionTimeoutId = 3; vm.$refs.popover.autoTimeoutId = 4; await vm.$nextTick(); wrapper.unmount(); await vm.$nextTick(); expect(vm.$refs.popover).toBeNull(); }); it('should be able to show popover on init', async () => { const wrapper = createWrapper( '<popover v-model="show" title="123"><button data-role="trigger"></button></popover>', { show: true, } ); const vm = wrapper.vm; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); }); it('should hide popover while enable set to false', async () => { const wrapper = createWrapper( '<popover v-model="show" title="123" :enable="enable"><button data-role="trigger"></button></popover>', { show: true, enable: true, } ); const vm = wrapper.vm; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); vm.enable = false; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should hide popover while all content become empty', async () => { const wrapper = createWrapper( '<popover v-model="show" :title="title" :content="content"><button data-role="trigger"></button></popover>', { show: true, content: '123', title: '321', } ); const vm = wrapper.vm; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); vm.content = ''; vm.title = ''; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to use custom string append-to', async () => { const wrapper = createWrapper( `<div id="test"> <popover append-to="#test" v-model="show" title="123"> <button data-role="trigger"></button> </popover> </div>`, { show: true, } ); const vm = wrapper.vm; await sleep(300); expect(document.querySelectorAll('#test .popover').length).toEqual(1); }); it('should be able to use custom element append-to', async () => { const wrapper = createWrapper( `<div id="test" ref="el"> <popover v-if="appendTo" :append-to="appendTo" v-model="show" title="123"> <button data-role="trigger"></button> </popover> </div>`, { show: true, appendTo: null, } ); const vm = wrapper.vm; await vm.$nextTick(); vm.appendTo = vm.$refs.el; await vm.$nextTick(); await sleep(300); expect(document.querySelectorAll('#test .popover').length).toEqual(1); }); it('should be able to use custom component append-to', async () => { const wrapper = createWrapper( `<div id="test" ref="el"> <popover v-if="appendTo" :append-to="appendTo" v-model="show" title="123"> <button data-role="trigger"></button> </popover> </div>`, { show: true, appendTo: null, } ); const vm = wrapper.vm; await vm.$nextTick(); vm.appendTo = vm; await vm.$nextTick(); await sleep(300); expect(document.querySelectorAll('#test .popover').length).toEqual(1); }); it('should be able to use popover directive', async () => { const wrapper = createWrapper('<btn v-popover="msg"></btn>', { msg: { title: 'title', content: 'content' }, }); const vm = wrapper.vm; await vm.$nextTick(); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); let popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.querySelector('.popover-title').textContent).toEqual( 'title' ); expect(popover.querySelector('.popover-content').textContent).toEqual( 'content' ); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); // this should work vm.msg = { title: 'title2', content: 'content2' }; await vm.$nextTick(); await vm.$nextTick(); triggerEvent(trigger, 'click'); await sleep(300); popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.querySelector('.popover-title').textContent).toEqual( 'title2' ); expect(popover.querySelector('.popover-content').textContent).toEqual( 'content2' ); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); // this should not work vm.msg.title = 'title3'; await vm.$nextTick(); triggerEvent(trigger, 'click'); await sleep(300); popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.querySelector('.popover-title').textContent).toEqual( 'title2' ); expect(popover.querySelector('.popover-content').textContent).toEqual( 'content2' ); }); it('directive with invalid modifiers should be ok', async () => { // invalid modifier should be ok const wrapper = createWrapper('<btn v-popover.test1.test2="msg"></btn>', { msg: { title: 'title', content: 'content' }, }); const vm = wrapper.vm; await vm.$nextTick(); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); const popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.querySelector('.popover-title').textContent).toEqual( 'title' ); expect(popover.querySelector('.popover-content').textContent).toEqual( 'content' ); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should not show popover with no title and content', async () => { const wrapper = createWrapper( '<popover v-model="show"><button data-role="trigger"></button></popover>', { show: true, } ); const vm = wrapper.vm; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to use custom target', async () => { const wrapper = createWrapper( '<div><button ref="btn" type="button">btn</button><popover :target="btn" trigger="focus" title="123"></popover></div>', { btn: null }, { mounted() { this.btn = this.$refs.btn; }, } ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); triggerEvent(vm.btn, 'focus'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); }); it('should be able to show popover on click', async () => { const wrapper = createWrapper(` <div> <btn type="primary" id="btn">Popover</btn> <popover title="Title" target="#btn"> <template slot="popover"> <h1>Hello world!</h1> </template> </popover> </div> `); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); triggerEvent(vm.$el.querySelector('button'), 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(vm.$el.querySelector('button'), 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change trigger to manual', async () => { const wrapper = createWrapper( ` <section> <popover title="Title" trigger="manual" v-model="show"> <btn>You Can't Trigger Popover Here...</btn> <template slot="popover"> <p>Popover content</p> </template> </popover> <hr/> <btn type="primary" @click="show = !show">Toggle Popover</btn> </section> `, { show: false } ); const vm = wrapper.vm; expect(document.querySelectorAll('.popover').length).toEqual(0); vm.show = true; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); vm.show = false; await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able change trigger to hover-focus', async () => { const wrapper = createWrapper( '<btn v-popover.hover-focus="{title:\'Title\', content:\'Popover content\'}" type="primary">Hover-Focus</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); // matches don't work in here const savedMatches = Element.prototype.matches; Element.prototype.matches = jest.fn(() => true); const trigger = vm.$el; triggerEvent(trigger, 'focus'); await sleep(300); expect(Element.prototype.matches).toBeCalled(); Element.prototype.matches = jest.fn((e) => false); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(trigger, 'blur'); await sleep(400); expect(Element.prototype.matches).toBeCalledTimes(2); expect(document.querySelectorAll('.popover').length).toEqual(0); Element.prototype.matches = savedMatches; }); it('should be able to change trigger to click', async () => { const wrapper = createWrapper( '<btn v-popover.click="{title:\'Title\', content:\'Popover content\'}" type="primary">Click</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change trigger to hover', async () => { const wrapper = createWrapper( '<btn v-popover.hover="{title:\'Title\', content:\'Popover content\'}" type="primary">Hover</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); const trigger = vm.$el; triggerEvent(trigger, 'mouseenter'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(trigger, 'mouseleave'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to toggle correctly on fast click', async () => { const wrapper = createWrapper( '<btn v-popover.click="{title:\'Title\', content:\'Popover content\'}" type="primary">Click</btn>' ); const vm = wrapper.vm; const button = vm.$el; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); triggerEvent(button, 'click'); triggerEvent(button, 'click'); triggerEvent(button, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(button, 'click'); triggerEvent(button, 'click'); triggerEvent(button, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change trigger to outside-click', async () => { const wrapper = createWrapper( '<btn v-popover="{title:\'Title\', content:\'Popover content\'}" type="primary">Outside-Click (Default)</btn>' ); const vm = wrapper.vm; const button = vm.$el; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); triggerEvent(button, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); document.body.click(); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to disable', async () => { const wrapper = createWrapper(` <popover title="Title" :enable="false"> <btn type="primary">Disabled Popover</btn> <template slot="popover"> <h1>Hello world!</h1> </template> </popover> `); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); triggerEvent(vm.$el.querySelector('button'), 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to hide title', async () => { const wrapper = createWrapper( '<btn v-popover="{content:\'Popover without a title\'}" type="primary">Popover</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); const trigger = vm.$el; expect(document.querySelectorAll('.popover').length).toEqual(0); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); // console.log(document.querySelector('.popover').innerHTML) expect(document.querySelector('.popover .popover-title')).toBeNull(); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change placement to top', async () => { const wrapper = createWrapper( '<btn v-popover.top="{title:\'Title\', content:\'Popover on top\'}" type="primary">Top</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); const popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.className).toContain('top'); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change placement to bottom', async () => { const wrapper = createWrapper( '<btn v-popover.bottom="{title:\'Title\', content:\'Popover on bottom\'}" type="primary">Bottom</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); const popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.className).toContain('bottom'); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change placement to left', async () => { const wrapper = createWrapper( '<btn v-popover.left="{title:\'Title\', content:\'Popover on left\'}" type="primary">Left</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); const popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.className).toContain('left'); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change placement to right', async () => { const wrapper = createWrapper( '<btn v-popover.right="{title:\'Title\', content:\'Popover on right\'}" type="primary">Right</btn>' ); const vm = wrapper.vm; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(0); const trigger = vm.$el; triggerEvent(trigger, 'click'); await sleep(300); const popover = document.querySelector('.popover'); expect(popover).toBeDefined(); expect(popover.className).toContain('right'); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change trigger in runtime', async () => { const wrapper = createWrapper( '<popover title="123" :trigger="trigger"><button data-role="trigger"></button></popover>', { trigger: 'focus', } ); const vm = wrapper.vm; expect(document.querySelectorAll('.popover').length).toEqual(0); await vm.$nextTick(); const trigger = vm.$el.querySelector('button'); triggerEvent(trigger, 'focus'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); vm.trigger = 'click'; await vm.$nextTick(); triggerEvent(trigger, 'blur'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to change content in runtime', async () => { const wrapper = createWrapper( '<popover :content="msg" trigger="click"><btn>123</btn></popover>', { msg: 'text', } ); const vm = wrapper.vm; expect(document.querySelectorAll('.popover').length).toEqual(0); await vm.$nextTick(); vm.msg = 'text2'; await vm.$nextTick(); await vm.$nextTick(); const trigger = vm.$el.querySelector('button'); triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(1); expect(document.querySelector('.popover-content').textContent).toEqual( 'text2' ); const topBefore = document.querySelector('.popover').style.top; vm.msg = ` This is a very very long text. This is a very very long text. This is a very very long text This is a very very long text. This is a very very long text. This is a very very long text This is a very very long text. This is a very very long text. This is a very very long text This is a very very long text. This is a very very long text. This is a very very long text This is a very very long text. This is a very very long text. This is a very very long text `; await vm.$nextTick(); expect(document.querySelectorAll('.popover').length).toEqual(1); expect(document.querySelector('.popover-content').textContent).toContain( 'This is a very very long text' ); await vm.$nextTick(); const topAfter = document.querySelector('.popover').style.top; // TODO // expect(topAfter).not.toEqual(topBefore) triggerEvent(trigger, 'click'); await sleep(300); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to show/hide on specified delay', async function () { const wrapper = createWrapper( '<popover :showDelay="300" :hideDelay="400" trigger="hover" title="123"><button></button></popover>' ); const vm = wrapper.vm; await vm.$nextTick(); const trigger = vm.$el.querySelector('button'); triggerEvent(trigger, 'mouseenter'); await sleep(150); // not shown yet expect(document.querySelectorAll('.popover').length).toEqual(0); await sleep(150); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(trigger, 'mouseleave'); await sleep(300); // not hidden yet expect(document.querySelectorAll('.popover').length).toEqual(1); await sleep(400); expect(document.querySelectorAll('.popover').length).toEqual(0); }); it('should be able to show even when hideDelay < showDelay < transition ', async function () { const wrapper = createWrapper( '<popover :hideDelay="1" :showDelay="100" :transition="500" trigger="hover" title="123"><button></button></popover>' ); const vm = wrapper.vm; await vm.$nextTick(); const trigger = vm.$el.querySelector('button'); triggerEvent(trigger, 'mouseenter'); await sleep(200); expect(document.querySelectorAll('.popover').length).toEqual(1); triggerEvent(trigger, 'mouseleave'); await sleep(200); triggerEvent(trigger, 'mouseenter'); await sleep(600); expect(document.querySelectorAll('.popover').length).toEqual(1); }); });