From ba1986d7093cfcde20729de324371040deeaceac Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 11:27:20 -0300 Subject: [PATCH 01/59] Create dropdown-divider.spec.js --- .../dropdown/dropdown-divider.spec.js | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/components/dropdown/dropdown-divider.spec.js diff --git a/src/components/dropdown/dropdown-divider.spec.js b/src/components/dropdown/dropdown-divider.spec.js new file mode 100644 index 00000000000..110a66da145 --- /dev/null +++ b/src/components/dropdown/dropdown-divider.spec.js @@ -0,0 +1,45 @@ +import Divider from './dropdown-divider' +import { mount } from '@vue/test-utils' + +describe('dropdown > dropdown-divider', () => { + it('works', async () => { + const wrapper = mount('Divider') + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-divider') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toEqual('separator') + expect(wrapper.text()).toEqual('') + }) + + it('renders custom root element when prop tag set', async () => { + const wrapper = mount('Divider', { + propsData: { + tag: 'span' + } + }) + + expect(wrapper.is('span')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-divider') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toEqual('separator') + expect(wrapper.text()).toEqual('') + }) + + it('does not render default slot content', async () => { + const wrapper = mount('Divider', { + slots: { + default: 'foobar' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-divider') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('role')).toBeDefined() + expect(wrapper.attributes('role')).toEqual('separator') + expect(wrapper.text()).toEqual('') + }) +}) From c7bf97a2ff354455975a04bf6085d2b6d3d08dea Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 11:30:57 -0300 Subject: [PATCH 02/59] Update dropdown-divider.spec.js --- src/components/dropdown/dropdown-divider.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/dropdown/dropdown-divider.spec.js b/src/components/dropdown/dropdown-divider.spec.js index 110a66da145..671185b85c7 100644 --- a/src/components/dropdown/dropdown-divider.spec.js +++ b/src/components/dropdown/dropdown-divider.spec.js @@ -3,7 +3,7 @@ import { mount } from '@vue/test-utils' describe('dropdown > dropdown-divider', () => { it('works', async () => { - const wrapper = mount('Divider') + const wrapper = mount(Divider) expect(wrapper.is('div')).toBe(true) expect(wrapper.classes()).toContain('dropdown-divider') @@ -14,7 +14,7 @@ describe('dropdown > dropdown-divider', () => { }) it('renders custom root element when prop tag set', async () => { - const wrapper = mount('Divider', { + const wrapper = mount(Divider, { propsData: { tag: 'span' } @@ -29,7 +29,7 @@ describe('dropdown > dropdown-divider', () => { }) it('does not render default slot content', async () => { - const wrapper = mount('Divider', { + const wrapper = mount(Divider, { slots: { default: 'foobar' } From 674c29798ea5d4dff21605cd83e07d61de2db863 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 11:36:15 -0300 Subject: [PATCH 03/59] Create dropdown-header.spec.js --- .../dropdown/dropdown-header.spec.js | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/components/dropdown/dropdown-header.spec.js diff --git a/src/components/dropdown/dropdown-header.spec.js b/src/components/dropdown/dropdown-header.spec.js new file mode 100644 index 00000000000..302ab2d65d9 --- /dev/null +++ b/src/components/dropdown/dropdown-header.spec.js @@ -0,0 +1,55 @@ +import Header from './dropdown-header' +import { mount } from '@vue/test-utils' + +describe('dropdown > dropdown-header', () => { + it('works', async () => { + const wrapper = mount(Header) + + expect(wrapper.is('h6')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-header') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('id')).not.toBeDefined() + expect(wrapper.text()).toEqual('') + }) + + it('renders custom root element when prop tag set', async () => { + const wrapper = mount(Header, { + propsData: { + tag: 'h2' + } + }) + + expect(wrapper.is('h2')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-header') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('id')).not.toBeDefined() + expect(wrapper.text()).toEqual('') + }) + + it('user supplied id when prop id set', async () => { + const wrapper = mount(Header, { + propsData: { + id: 'foo' + } + }) + + expect(wrapper.is('h6')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-header') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.attributes('id')).toBeDefined() + expect(wrapper.attributes('id')).toEqual('foo') + }) + + it('renders default slot content', async () => { + const wrapper = mount(Header, { + slots: { + default: 'foobar' + } + }) + + expect(wrapper.is('h6')).toBe(true) + expect(wrapper.classes()).toContain('dropdown-header') + expect(wrapper.classes().length).toBe(1) + expect(wrapper.text()).toEqual('foobar') + }) +}) From 6ba2399fe0802533225024ce78e21c8b136fa3bd Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 11:38:15 -0300 Subject: [PATCH 04/59] Rename dropdown.spec.js to dropdown.legacy.spec.js --- .../dropdown/{dropdown.spec.js => dropdown.legacy.spec.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/dropdown/{dropdown.spec.js => dropdown.legacy.spec.js} (100%) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.legacy.spec.js similarity index 100% rename from src/components/dropdown/dropdown.spec.js rename to src/components/dropdown/dropdown.legacy.spec.js From d633749ef4a646fc983b495222fd29699f5e23f4 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 11:59:41 -0300 Subject: [PATCH 05/59] Create dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/components/dropdown/dropdown.spec.js diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js new file mode 100644 index 00000000000..f04befac305 --- /dev/null +++ b/src/components/dropdown/dropdown.spec.js @@ -0,0 +1,49 @@ +import Dropdown from './dropdown' +import { mount } from '@vue/test-utils' + +describe('dropdown', () => { + it('has expected default structure', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true + }) + + expect(wrapper.is('div')).toBe(true) + + // Wait for auto ID to be generated + await wrapper.$nextTick() + + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes()).toContain('b-dropdown') + expect(wrapper.classes().length).toBe(3) + expect(wrapper.attributes('id')).toBeDefined() + const wrapperId = wrapper.attributes('id') + + expect(wrapper.findAll('button').length).toBe(1) + const $button = wrapper.find('button') + expect($button.classes()).toContain('btn') + expect($button.classes()).toContain('btn-secondary') + expect($button.classes()).toContain('dropdown-toggle') + expect($button.classes().length).toBe(3) + expect($button.attributes('aria-haspopup')).toBeDefined() + expect($button.attributes('aria-haspopup')).toEqal('true') + expect($button.attributes('aria-expanded')).toBeDefined() + expect($button.attributes('aria-expanded')).toEqal('false') + expect($button.attributes('id')).toBeDefined() + expect($button.attributes('id')).toEqual(`${wrapperId}_BV_toggle_`) + expect($button.text()).toEqual('') + + expect(wrapper.findAll('.dropdown-menu').length).toBe(1) + const $menu = wrapper.find('.dropdown-menu') + expect($menu.classes().length).toBe(1) + expect($menu.attributes('role')).toBeDefined() + expect($menu.attributes('role')).toEqual('menu') + expect($menu.attributes('tabindex')).toBeDefined() + expect($menu.attributes('tabindex')).toEqual('-1') + expect($menu.attributes('aria-labelledby')).toBeDefined() + expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}_BV_toggle_`) + expect($menu.text()).toEqual('') + + wrapper.destroy() + }) +}) From be29fc71ccb9f5602173b6a6d476b4a3d1e56d10 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:01:53 -0300 Subject: [PATCH 06/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index f04befac305..30b58b8ba11 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -8,9 +8,10 @@ describe('dropdown', () => { }) expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) // Wait for auto ID to be generated - await wrapper.$nextTick() + await wrapper.vm.$nextTick() expect(wrapper.classes()).toContain('dropdown') expect(wrapper.classes()).toContain('btn-group') From 45550c8b633a6cb22548cb4e0dcfec62224c48db Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:07:49 -0300 Subject: [PATCH 07/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 62 +++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 30b58b8ba11..af92fddcb1f 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -27,9 +27,9 @@ describe('dropdown', () => { expect($button.classes()).toContain('dropdown-toggle') expect($button.classes().length).toBe(3) expect($button.attributes('aria-haspopup')).toBeDefined() - expect($button.attributes('aria-haspopup')).toEqal('true') + expect($button.attributes('aria-haspopup')).toEqual('true') expect($button.attributes('aria-expanded')).toBeDefined() - expect($button.attributes('aria-expanded')).toEqal('false') + expect($button.attributes('aria-expanded')).toEqual('false') expect($button.attributes('id')).toBeDefined() expect($button.attributes('id')).toEqual(`${wrapperId}_BV_toggle_`) expect($button.text()).toEqual('') @@ -47,4 +47,62 @@ describe('dropdown', () => { wrapper.destroy() }) + + it('split mode has expected default structure', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + split: true + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + // Wait for auto ID to be generated + await wrapper.vm.$nextTick() + + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('btn-group') + expect(wrapper.classes()).toContain('b-dropdown') + expect(wrapper.classes().length).toBe(3) + expect(wrapper.attributes('id')).toBeDefined() + const wrapperId = wrapper.attributes('id') + + expect(wrapper.findAll('button').length).toBe(2) + const $buttons = wrapper.findAll('button') + const $split = $buttons.at(0) + const $toggle = $buttons.at(1) + + expect($split.classes()).toContain('btn') + expect($split.classes()).toContain('btn-secondary') + expect($split.attributes('id')).toBeDefined() + expect($split.attributes('id')).toEqual(`${wrapperId}_BV_button_`) + expect($split.text()).toEqual('') + + expect($toggle.classes()).toContain('btn') + expect($toggle.classes()).toContain('btn-secondary') + expect($toggle.classes()).toContain('dropdown-toggle') + expect($toggle.classes().length).toBe(3) + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($toggle.attributes('id')).toBeDefined() + expect($toggle.attributes('id')).toEqual(`${wrapperId}_BV_toggle_`) + expect($toggle.text()).toEqual('') + + expect(wrapper.findAll('.dropdown-menu').length).toBe(1) + const $menu = wrapper.find('.dropdown-menu') + expect($menu.classes().length).toBe(1) + expect($menu.attributes('role')).toBeDefined() + expect($menu.attributes('role')).toEqual('menu') + expect($menu.attributes('tabindex')).toBeDefined() + expect($menu.attributes('tabindex')).toEqual('-1') + expect($menu.attributes('aria-labelledby')).toBeDefined() + expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}_BV_toggle_`) + expect($menu.text()).toEqual('') + + wrapper.destroy() + }) }) From c30a5a87f6698134349e36d9c348b11b37cf8f67 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:10:33 -0300 Subject: [PATCH 08/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index af92fddcb1f..20c02024369 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -31,7 +31,7 @@ describe('dropdown', () => { expect($button.attributes('aria-expanded')).toBeDefined() expect($button.attributes('aria-expanded')).toEqual('false') expect($button.attributes('id')).toBeDefined() - expect($button.attributes('id')).toEqual(`${wrapperId}_BV_toggle_`) + expect($button.attributes('id')).toEqual(`${wrapperId}__BV_toggle_`) expect($button.text()).toEqual('') expect(wrapper.findAll('.dropdown-menu').length).toBe(1) @@ -42,7 +42,7 @@ describe('dropdown', () => { expect($menu.attributes('tabindex')).toBeDefined() expect($menu.attributes('tabindex')).toEqual('-1') expect($menu.attributes('aria-labelledby')).toBeDefined() - expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}_BV_toggle_`) + expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}__BV_toggle_`) expect($menu.text()).toEqual('') wrapper.destroy() @@ -77,7 +77,7 @@ describe('dropdown', () => { expect($split.classes()).toContain('btn') expect($split.classes()).toContain('btn-secondary') expect($split.attributes('id')).toBeDefined() - expect($split.attributes('id')).toEqual(`${wrapperId}_BV_button_`) + expect($split.attributes('id')).toEqual(`${wrapperId}__BV_button_`) expect($split.text()).toEqual('') expect($toggle.classes()).toContain('btn') @@ -89,7 +89,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') expect($toggle.attributes('id')).toBeDefined() - expect($toggle.attributes('id')).toEqual(`${wrapperId}_BV_toggle_`) + expect($toggle.attributes('id')).toEqual(`${wrapperId}__BV_toggle_`) expect($toggle.text()).toEqual('') expect(wrapper.findAll('.dropdown-menu').length).toBe(1) @@ -100,7 +100,7 @@ describe('dropdown', () => { expect($menu.attributes('tabindex')).toBeDefined() expect($menu.attributes('tabindex')).toEqual('-1') expect($menu.attributes('aria-labelledby')).toBeDefined() - expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}_BV_toggle_`) + expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}__BV_toggle_`) expect($menu.text()).toEqual('') wrapper.destroy() From 7c0310a4509491426f82188a2f859cd901261e84 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:11:41 -0300 Subject: [PATCH 09/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 20c02024369..1f80af2ab06 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -100,7 +100,7 @@ describe('dropdown', () => { expect($menu.attributes('tabindex')).toBeDefined() expect($menu.attributes('tabindex')).toEqual('-1') expect($menu.attributes('aria-labelledby')).toBeDefined() - expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}__BV_toggle_`) + expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}__BV_button_`) expect($menu.text()).toEqual('') wrapper.destroy() From 9ed03a3fda71858d46f2fc8a1d2e0b8bf1bd1e98 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:15:32 -0300 Subject: [PATCH 10/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 1f80af2ab06..29a846c73c0 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -1,4 +1,5 @@ import Dropdown from './dropdown' +// import DropdownItem from './dropdown-item' import { mount } from '@vue/test-utils' describe('dropdown', () => { @@ -83,7 +84,8 @@ describe('dropdown', () => { expect($toggle.classes()).toContain('btn') expect($toggle.classes()).toContain('btn-secondary') expect($toggle.classes()).toContain('dropdown-toggle') - expect($toggle.classes().length).toBe(3) + expect($toggle.classes()).toContain('dropdown-toggle-split') + expect($toggle.classes().length).toBe(4) expect($toggle.attributes('aria-haspopup')).toBeDefined() expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() From dd2d0c36999f899493c6ff9779914dbbd532f9b7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:19:23 -0300 Subject: [PATCH 11/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 29a846c73c0..ba452f557f2 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -92,7 +92,9 @@ describe('dropdown', () => { expect($toggle.attributes('aria-expanded')).toEqual('false') expect($toggle.attributes('id')).toBeDefined() expect($toggle.attributes('id')).toEqual(`${wrapperId}__BV_toggle_`) - expect($toggle.text()).toEqual('') + expect($toggle.findAll('span.sr-only').length).toBe(1) + expect($toggle.find('span.sr-only').text()).toEqual('Toggle Dropdown') + expect($toggle.text()).toEqual('Toggle Dropdown') expect(wrapper.findAll('.dropdown-menu').length).toBe(1) const $menu = wrapper.find('.dropdown-menu') From f6fdd57f47e65c932a5cc0b3705ad818d1aee433 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:23:36 -0300 Subject: [PATCH 12/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index ba452f557f2..3f62b05f532 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -37,6 +37,7 @@ describe('dropdown', () => { expect(wrapper.findAll('.dropdown-menu').length).toBe(1) const $menu = wrapper.find('.dropdown-menu') + expect($menu.is('div')).toBe(true) expect($menu.classes().length).toBe(1) expect($menu.attributes('role')).toBeDefined() expect($menu.attributes('role')).toEqual('menu') @@ -98,6 +99,7 @@ describe('dropdown', () => { expect(wrapper.findAll('.dropdown-menu').length).toBe(1) const $menu = wrapper.find('.dropdown-menu') + expect($menu.is('div')).toBe(true) expect($menu.classes().length).toBe(1) expect($menu.attributes('role')).toBeDefined() expect($menu.attributes('role')).toEqual('menu') @@ -109,4 +111,22 @@ describe('dropdown', () => { wrapper.destroy() }) + + it('renders default slot inside menu', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + slots: { + default: 'foobar' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.dropdown-menu').length).toBe(1) + const $menu = wrapper.find('.dropdown-menu') + expect($menu.text()).toEqual('foobar') + + wrapper.destroy() + }) }) From 635833aaef8f9232eee43dcc70ef3748ee16e4d7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:26:39 -0300 Subject: [PATCH 13/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 3f62b05f532..78ceb917cd6 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -129,4 +129,31 @@ describe('dropdown', () => { wrapper.destroy() }) + + it('has user supplied ID', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + id: 'test' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.attributes('id')).toBeDefined() + expect(wrapper.attributes('id')).toEqual('test') + const wrapperId = wrapper.attributes('id') + + expect(wrapper.findAll('button').length).toBe(1) + const $button = wrapper.find('button') + expect($button.attributes('id')).toEqual(`${wrapperId}__BV_toggle_`) + + expect(wrapper.findAll('.dropdown-menu').length).toBe(1) + const $menu = wrapper.find('.dropdown-menu') + expect($menu.attributes('aria-labelledby')).toBeDefined() + expect($menu.attributes('aria-labelledby')).toEqual(`${wrapperId}__BV_toggle_`) + + wrapper.destroy() + }) }) From a5bd29dfa75b8f5cddc461c97a002e60ecd53c69 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:36:41 -0300 Subject: [PATCH 14/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 32 +++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 78ceb917cd6..c839c1fe811 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -1,6 +1,6 @@ import Dropdown from './dropdown' // import DropdownItem from './dropdown-item' -import { mount } from '@vue/test-utils' +import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' describe('dropdown', () => { it('has expected default structure', async () => { @@ -156,4 +156,34 @@ describe('dropdown', () => { wrapper.destroy() }) + + it('dropdown opens and closes', async () => { + const localVue = new CreateLocalVue() + const App = localVue.extend({ + render(h) { + return h( + 'div', + {}, + [h( + Dropdown, + { props: { id: 'test' } }, + [h(DropdownItem, {}, 'item')] + )] + ) + } + }) + + const wrapper = mount(App, { + attachToDocument: true + }) + + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.dropdown').length).toBe(1) + expect(wrapper.findAll('.dropdown-toggle').length).toBe(1) + expect(wrapper.findAll('.dropdown-menu').length).toBe(1) + expect(wrapper.findAll('.dropdown-menu .dropdown-item').length).toBe(1) + + wrapper.destroy() + }) }) From 0865541c0056fd011c856d241ddcbc3da6912599 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:38:26 -0300 Subject: [PATCH 15/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index c839c1fe811..d013969126f 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -1,5 +1,5 @@ import Dropdown from './dropdown' -// import DropdownItem from './dropdown-item' +import DropdownItem from './dropdown-item' import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' describe('dropdown', () => { From ca00e844f72ea38f87ea97d84f9a85fa89afe747 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:50:29 -0300 Subject: [PATCH 16/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 49 +++++++++++++++++++----- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index d013969126f..2b412d3cbea 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -161,15 +161,7 @@ describe('dropdown', () => { const localVue = new CreateLocalVue() const App = localVue.extend({ render(h) { - return h( - 'div', - {}, - [h( - Dropdown, - { props: { id: 'test' } }, - [h(DropdownItem, {}, 'item')] - )] - ) + return h('div', {}, [h(Dropdown, { props: { id: 'test' } }, [h(DropdownItem, {}, 'item')])]) } }) @@ -184,6 +176,45 @@ describe('dropdown', () => { expect(wrapper.findAll('.dropdown-menu').length).toBe(1) expect(wrapper.findAll('.dropdown-menu .dropdown-item').length).toBe(1) + const $dropdown = wrapper.find('.dropdown') + const $toggle = wrapper.find('.dropdown-toggle') + const $menu = wrapper.find('.dropdown-menu') + const $item = wrapper.find('.dropdown-item') + + expect($dropdown.isVueInstance()).toBe(true) + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Open menu by clicking toggle + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('true') + + // Close menu by clicking toggle again + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Open menu again + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('true') + wrapper.destroy() }) }) From c88d955f2ab9c565a0b752807037a37a3f721dd7 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 12:58:39 -0300 Subject: [PATCH 17/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 2b412d3cbea..ad9cd03951d 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -2,6 +2,22 @@ import Dropdown from './dropdown' import DropdownItem from './dropdown-item' import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' +// Mock Popper so that tests will work +jest.mock('popper.js', () => { + const PopperJS = jest.requireActual('popper.js') + + return class { + static placements = PopperJS.placements + + constructor() { + return { + destroy: () => {}, + scheduleUpdate: () => {} + } + } + } +}) + describe('dropdown', () => { it('has expected default structure', async () => { const wrapper = mount(Dropdown, { From 3d16cb3b44946c073e32095c5c41fa8a4ffbd270 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:03:30 -0300 Subject: [PATCH 18/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index ad9cd03951d..26b815748a0 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -6,16 +6,15 @@ import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' jest.mock('popper.js', () => { const PopperJS = jest.requireActual('popper.js') - return class { - static placements = PopperJS.placements - - constructor() { - return { - destroy: () => {}, - scheduleUpdate: () => {} - } + const Popper = () => { + return { + destroy: () => {}, + scheduleUpdate: () => {} } } + Popper.placements = PopperJS.placements + + return Popper }) describe('dropdown', () => { From 29598b183302024da03adc0d2925d0ce478cacdc Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:03:57 -0300 Subject: [PATCH 19/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 26b815748a0..5fda25f8a76 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -193,8 +193,8 @@ describe('dropdown', () => { const $dropdown = wrapper.find('.dropdown') const $toggle = wrapper.find('.dropdown-toggle') - const $menu = wrapper.find('.dropdown-menu') - const $item = wrapper.find('.dropdown-item') + // const $menu = wrapper.find('.dropdown-menu') + // const $item = wrapper.find('.dropdown-item') expect($dropdown.isVueInstance()).toBe(true) From 786a54614a6fd55440bd96bdcb7a8595ead7c835 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:06:58 -0300 Subject: [PATCH 20/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 5fda25f8a76..1fad7bf9b5d 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -7,10 +7,9 @@ jest.mock('popper.js', () => { const PopperJS = jest.requireActual('popper.js') const Popper = () => { - return { - destroy: () => {}, - scheduleUpdate: () => {} - } + this.destroy = () => {} + this.scheduleUpdate = () => {} + return this } Popper.placements = PopperJS.placements From c98267ee967ff07adfe93778fa237fa6bebce922 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:14:09 -0300 Subject: [PATCH 21/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 1fad7bf9b5d..aa3df5196ef 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -2,6 +2,7 @@ import Dropdown from './dropdown' import DropdownItem from './dropdown-item' import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' +/* // Mock Popper so that tests will work jest.mock('popper.js', () => { const PopperJS = jest.requireActual('popper.js') @@ -15,8 +16,26 @@ jest.mock('popper.js', () => { return Popper }) +*/ describe('dropdown', () => { + const originalCreateRange = document.createRange + + beforeEach(() => { + document.createRange = () => ({ + setStart: () => {}, + setEnd: () => {}, + commonAncestorContainer: { + nodeName: 'BODY', + ownerDocument: document, + }, + }) + }) + + afterEach(() => { + document.createRange = originalCreateRange + }) + it('has expected default structure', async () => { const wrapper = mount(Dropdown, { attachToDocument: true From 1c1ea025524359cb685481479c35c5bd8270b45f Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:17:29 -0300 Subject: [PATCH 22/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 32 ++++++++++-------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index aa3df5196ef..cb6dd30d2eb 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -2,33 +2,18 @@ import Dropdown from './dropdown' import DropdownItem from './dropdown-item' import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' -/* -// Mock Popper so that tests will work -jest.mock('popper.js', () => { - const PopperJS = jest.requireActual('popper.js') - - const Popper = () => { - this.destroy = () => {} - this.scheduleUpdate = () => {} - return this - } - Popper.placements = PopperJS.placements - - return Popper -}) -*/ - describe('dropdown', () => { const originalCreateRange = document.createRange beforeEach(() => { + // https://github.com/FezVrasta/popper.js/issues/478#issuecomment-407422016 document.createRange = () => ({ setStart: () => {}, setEnd: () => {}, commonAncestorContainer: { nodeName: 'BODY', - ownerDocument: document, - }, + ownerDocument: document + } }) }) @@ -212,7 +197,7 @@ describe('dropdown', () => { const $dropdown = wrapper.find('.dropdown') const $toggle = wrapper.find('.dropdown-toggle') // const $menu = wrapper.find('.dropdown-menu') - // const $item = wrapper.find('.dropdown-item') + const $item = wrapper.find('.dropdown-item') expect($dropdown.isVueInstance()).toBe(true) @@ -248,6 +233,15 @@ describe('dropdown', () => { expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') + // Close by clicking dropdown-item + $item.trigger('click') + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + wrapper.destroy() }) }) From f3c22f22dc68b478f21e53928feeb78014cea8c6 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:32:05 -0300 Subject: [PATCH 23/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index cb6dd30d2eb..7f60d92f360 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -196,7 +196,7 @@ describe('dropdown', () => { const $dropdown = wrapper.find('.dropdown') const $toggle = wrapper.find('.dropdown-toggle') - // const $menu = wrapper.find('.dropdown-menu') + const $menu = wrapper.find('.dropdown-menu') const $item = wrapper.find('.dropdown-item') expect($dropdown.isVueInstance()).toBe(true) @@ -214,6 +214,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') + expect(document.activeElement).toBe($menu.element) // Close menu by clicking toggle again $toggle.trigger('click') @@ -223,6 +224,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect(document.activeElement).toBe($toggle.element) // Open menu again $toggle.trigger('click') @@ -232,11 +234,31 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') + expect(document.activeElement).toBe($menu.element) // Close by clicking dropdown-item $item.trigger('click') await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + expect(document.activeElement).toBe($toggle.element) + + // Open menu via .show() method + $dropdown.vm.show() + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('true') + + // Close menu via .hide() method + $dropdown.vm.hide() + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-haspopup')).toBeDefined() expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() From 3c307e5ac146e44241fa2c63b482f4c7d7141367 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:35:19 -0300 Subject: [PATCH 24/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 7f60d92f360..0251a251215 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -224,6 +224,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + await wrapper.vm.$nextTick() expect(document.activeElement).toBe($toggle.element) // Open menu again @@ -244,6 +245,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + await wrapper.vm.$nextTick() expect(document.activeElement).toBe($toggle.element) // Open menu via .show() method From 72d373b9679e91e56996cfb28b119f65c4f5df0e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:38:34 -0300 Subject: [PATCH 25/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 0251a251215..3798617445e 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -7,6 +7,8 @@ describe('dropdown', () => { beforeEach(() => { // https://github.com/FezVrasta/popper.js/issues/478#issuecomment-407422016 + // Hack to make Popper not bork out during tests. + // Note popper still does not do any positiioning claculation in JSDOM though. document.createRange = () => ({ setStart: () => {}, setEnd: () => {}, @@ -224,8 +226,6 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') - await wrapper.vm.$nextTick() - expect(document.activeElement).toBe($toggle.element) // Open menu again $toggle.trigger('click') @@ -245,8 +245,6 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') - await wrapper.vm.$nextTick() - expect(document.activeElement).toBe($toggle.element) // Open menu via .show() method $dropdown.vm.show() From 73980486675755e7b7b9874a9eefe9c6691609c3 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:54:33 -0300 Subject: [PATCH 26/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 3798617445e..b27af750c05 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -177,6 +177,29 @@ describe('dropdown', () => { wrapper.destroy() }) + it('split mode emits click event when split button clicked', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + split: true + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + expect(wrapper.emitted('click')).not.toBeDefined() + + expect(wrapper.findAll('button').length).toBe(2) + const $split = $buttons.at(0) + + $split.trigger('click') + + expect(wrapper.emitted('click')).not.toBeDefined() + expect(wrapper.emitted('click').length).toBe(1) + + wrapper.destroy() + }) + it('dropdown opens and closes', async () => { const localVue = new CreateLocalVue() const App = localVue.extend({ From 006c21f68b5bd1e259aef39ced5e1cea818c3100 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 13:57:54 -0300 Subject: [PATCH 27/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index b27af750c05..b0a347b4b1b 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -190,6 +190,7 @@ describe('dropdown', () => { expect(wrapper.emitted('click')).not.toBeDefined() expect(wrapper.findAll('button').length).toBe(2) + const $buttons = wrapper.findAll('button') const $split = $buttons.at(0) $split.trigger('click') From 5bfa3c26a4d948d32e81de8b6ebaebd5ae5ebb6d Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:04:34 -0300 Subject: [PATCH 28/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 55 +++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index b0a347b4b1b..46448ac10f2 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -195,7 +195,7 @@ describe('dropdown', () => { $split.trigger('click') - expect(wrapper.emitted('click')).not.toBeDefined() + expect(wrapper.emitted('click')).toBeDefined() expect(wrapper.emitted('click').length).toBe(1) wrapper.destroy() @@ -290,4 +290,57 @@ describe('dropdown', () => { wrapper.destroy() }) + + it('preventDefault() forks on show event', async () => { + let prevent = true + const wrapper = mount(Dropdown, { + attachToDocument: true, + listeners: { + show: bvEvt => { + if (prevent) { + bvEvt.preventDefault() + } + } + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + await wrapper.vm.$nextTick() + + expect(wrapper.emitted('show')).not.toBeDefined() + + expect(wrapper.findAll('button').length).toBe(1) + const $toggle = wrapper.find('button') + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Should prevent menu from opening + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect(wrapper.emitted('show')).toBeDefined() + expect(wrapper.emitted('show').length).toBe(1) + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Allow menu to open + prevent = false + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect(wrapper.emitted('show')).toBeDefined() + expect(wrapper.emitted('show').length).toBe(2) + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('true') + + wrapper.destroy() + }) }) From 50771b4b90af5c23bd7a0ac7a98c418cf6cd9490 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:07:12 -0300 Subject: [PATCH 29/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 46448ac10f2..3c01e6b0826 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -340,7 +340,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') - + wrapper.destroy() }) }) From 3bcbb0aa526aad05814936d2a2d5463cf70066e0 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:15:55 -0300 Subject: [PATCH 30/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 3c01e6b0826..ed3772c3f1c 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -288,10 +288,30 @@ describe('dropdown', () => { expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + // Open menu via .show() method again + $dropdown.vm.show() + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('true') + expect(document.activeElement).toBe($menu.element) + + // Close menu by moving focus away from menu + const focusInEvt = new FocusEvent('focusin') + document.body.dispatchEvent(focusInEvt) + await wrapper.vm.$nextTick() + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + wrapper.destroy() }) - it('preventDefault() forks on show event', async () => { + it('preventDefault() works on show event', async () => { let prevent = true const wrapper = mount(Dropdown, { attachToDocument: true, From cdb3b4467948674c4ed0809c2b4fe87734492f20 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:22:37 -0300 Subject: [PATCH 31/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index ed3772c3f1c..29e86e077ae 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -300,7 +300,7 @@ describe('dropdown', () => { // Close menu by moving focus away from menu const focusInEvt = new FocusEvent('focusin') - document.body.dispatchEvent(focusInEvt) + document.dispatchEvent(focusInEvt) await wrapper.vm.$nextTick() expect($toggle.attributes('aria-haspopup')).toBeDefined() From 33882dfab297aec6e28213282d3706213949aeb1 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:30:17 -0300 Subject: [PATCH 32/59] Update dropdown.js --- src/mixins/dropdown.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mixins/dropdown.js b/src/mixins/dropdown.js index 271ff0742b5..e72a65ee42c 100644 --- a/src/mixins/dropdown.js +++ b/src/mixins/dropdown.js @@ -157,7 +157,7 @@ export default { this.whileOpenListen(false) this.removePopper() }, - beforeDestroy() /* istanbul ignore next: not easy to test */ { + beforeDestroy() { this.visible = false this.whileOpenListen(false) this.removePopper() @@ -182,9 +182,9 @@ export default { } // Disable totally Popper.js for Dropdown in Navbar - /* istanbul ignore next: cant test popper in JSDOM */ if (!this.inNavbar) { if (typeof Popper === 'undefined') { + /* istanbul ignore next */ warn('b-dropdown: Popper.js not found. Falling back to CSS positioning.') } else { // for dropup with alignment we use the parent element as popper container @@ -212,18 +212,18 @@ export default { this.$emit('hidden') this.removePopper() }, - createPopper(element) /* istanbul ignore next: cant test popper in JSDOM */ { + createPopper(element) { this.removePopper() this._popper = new Popper(element, this.$refs.menu, this.getPopperConfig()) }, - removePopper() /* istanbul ignore next: cant test popper in JSDOM */ { + removePopper() { if (this._popper) { // Ensure popper event listeners are removed cleanly this._popper.destroy() } this._popper = null }, - getPopperConfig() /* istanbul ignore next: can't test popper in JSDOM */ { + getPopperConfig() { let placement = AttachmentMap.BOTTOM if (this.dropup) { placement = this.right ? AttachmentMap.TOPEND : AttachmentMap.TOP @@ -316,7 +316,9 @@ export default { click(evt) { // Called only in split button mode, for the split button if (this.disabled) { + /* istanbul ignore next */ this.visible = false + /* istanbul ignore next */ return } this.$emit('click', evt) From 35e5670258bbc8250281d4af4592773aee949851 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:43:12 -0300 Subject: [PATCH 33/59] Update dropdown.js --- src/mixins/dropdown.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mixins/dropdown.js b/src/mixins/dropdown.js index e72a65ee42c..a38dadfcce8 100644 --- a/src/mixins/dropdown.js +++ b/src/mixins/dropdown.js @@ -323,7 +323,7 @@ export default { } this.$emit('click', evt) }, - onKeydown(evt) /* istanbul ignore next: not easy to test */ { + onKeydown(evt) { // Called from dropdown menu context const key = evt.keyCode if (key === KeyCodes.ESC) { @@ -331,6 +331,7 @@ export default { this.onEsc(evt) } else if (key === KeyCodes.TAB) { // Close on tab out + /* istanbul ignore next: not used and should be removed */ this.onTab(evt) } else if (key === KeyCodes.DOWN) { // Down Arrow @@ -340,7 +341,7 @@ export default { this.focusNext(evt, true) } }, - onEsc(evt) /* istanbul ignore next: not easy to test */ { + onEsc(evt) { if (this.visible) { this.visible = false evt.preventDefault() From 93431099b2d0e736589161aecb7a659d7899b3e2 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:43:18 -0300 Subject: [PATCH 34/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 49 ++++++++++-------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 29e86e077ae..4e1170bd55a 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -235,7 +235,6 @@ describe('dropdown', () => { // Open menu by clicking toggle $toggle.trigger('click') await wrapper.vm.$nextTick() - expect($toggle.attributes('aria-haspopup')).toBeDefined() expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() @@ -245,56 +244,32 @@ describe('dropdown', () => { // Close menu by clicking toggle again $toggle.trigger('click') await wrapper.vm.$nextTick() - - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') // Open menu again $toggle.trigger('click') await wrapper.vm.$nextTick() - - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') expect(document.activeElement).toBe($menu.element) // Close by clicking dropdown-item $item.trigger('click') await wrapper.vm.$nextTick() - - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') // Open menu via .show() method $dropdown.vm.show() await wrapper.vm.$nextTick() - - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') // Close menu via .hide() method $dropdown.vm.hide() await wrapper.vm.$nextTick() - - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') // Open menu via .show() method again $dropdown.vm.show() await wrapper.vm.$nextTick() - - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') expect(document.activeElement).toBe($menu.element) @@ -302,10 +277,28 @@ describe('dropdown', () => { const focusInEvt = new FocusEvent('focusin') document.dispatchEvent(focusInEvt) await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('false') - expect($toggle.attributes('aria-haspopup')).toBeDefined() - expect($toggle.attributes('aria-haspopup')).toEqual('true') - expect($toggle.attributes('aria-expanded')).toBeDefined() + // Open menu via keydown.down event on toggle button + $toggle.trigger('keydown.down') + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('true') + expect(document.activeElement).toBe($menu.element) + + // Close menu by clicking outside of menu + const clickEvt = new MouseEvent('click') + document.dispatchEvent(clickEvt) + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Open menu via .show() method again + $dropdown.vm.show() + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('true') + + // Close menu by keydown.esc event on dropdown item + $item.trigger('keydown.esc') + await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('false') wrapper.destroy() From f2357181f06b8e73aa1eb0c494aef935b4e1b75a Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:49:23 -0300 Subject: [PATCH 35/59] Update dropdown.js --- src/mixins/dropdown.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mixins/dropdown.js b/src/mixins/dropdown.js index a38dadfcce8..eedf9d7b48e 100644 --- a/src/mixins/dropdown.js +++ b/src/mixins/dropdown.js @@ -276,6 +276,7 @@ export default { hide(refocus = false) { // Public method to hide dropdown if (this.disabled) { + /* istanbul ignore next */ return } this.visible = false @@ -297,10 +298,13 @@ export default { ) ) { // We only toggle on Click, Enter, Space, and Arrow Down + /* istanbul ignore next */ return } if (this.disabled) { + /* istanbul ignore next */ this.visible = false + /* istanbul ignore next */ return } this.$emit('toggle', evt) From 02d67282eca4e5244fd714c6f5cfbe916ba76791 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 14:55:23 -0300 Subject: [PATCH 36/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 4e1170bd55a..186ec8c0297 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -301,6 +301,37 @@ describe('dropdown', () => { await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('false') + // Open menu via .show() method again + $dropdown.vm.show() + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('true') + + // When disabled changes to true, menu should close + $dropdown.setProps({ + disabled: true + }) + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // When disabled, show() wont open menu + $dropdown.vm.show() + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Re enable dropdown and open it + $dropdown.setProps({ + disabled: false + }) + await wrapper.vm.$nextTick() + $dropdown.vm.show() + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('true') + + // Should close on root emit when argument is not self + wrapper.vm.$root.$emit('bv::dropdown::shown', {}) + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('false') + wrapper.destroy() }) From 3e9258b34a5c809d12815dd720f040debf4c7d8c Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 15:14:13 -0300 Subject: [PATCH 37/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 186ec8c0297..7c65fdf51b3 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -4,6 +4,7 @@ import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' describe('dropdown', () => { const originalCreateRange = document.createRange + const origGetBCR = Element.prototype.getBoundingClientRect beforeEach(() => { // https://github.com/FezVrasta/popper.js/issues/478#issuecomment-407422016 @@ -17,10 +18,24 @@ describe('dropdown', () => { ownerDocument: document } }) + // Mock getBCR so that the isVisible(el) test returns true + // In our test below, all pagination buttons would normally be visible + Element.prototype.getBoundingClientRect = jest.fn(() => { + return { + width: 24, + height: 24, + top: 0, + left: 0, + bottom: 0, + right: 0 + } + }) }) afterEach(() => { + // Reset overrides document.createRange = originalCreateRange + Element.prototype.getBoundingClientRect = origGetBCR }) it('has expected default structure', async () => { From 0819fdf0a1f9f8a09abcce6388dc77deb72c0af5 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 15:48:51 -0300 Subject: [PATCH 38/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 81 +++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 7c65fdf51b3..62f67f83f22 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -19,7 +19,7 @@ describe('dropdown', () => { } }) // Mock getBCR so that the isVisible(el) test returns true - // In our test below, all pagination buttons would normally be visible + // Needed for keyboard navigation testing Element.prototype.getBoundingClientRect = jest.fn(() => { return { width: 24, @@ -402,4 +402,83 @@ describe('dropdown', () => { wrapper.destroy() }) + + it('Keyboard navigation works when open', async () => { + const localVue = new CreateLocalVue() + const App = localVue.extend({ + render(h) { + return h('div', {}, [ + h(Dropdown, { props: { id: 'test' } }, [ + h(DropdownItem, {}, 'item'), + h(DropdownItem, {}, 'item'), + h(DropdownItem, { disabled: true }, 'item'), + h(DropdownItem, {}, 'item') + ]) + ]) + } + }) + + const wrapper = mount(App, { + attachToDocument: true + }) + + expect(wrapper.isVueInstance()).toBe(true) + await wrapper.vm.$nextTick() + + expect(wrapper.findAll('.dropdown').length).toBe(1) + expect(wrapper.findAll('.dropdown-toggle').length).toBe(1) + expect(wrapper.findAll('.dropdown-menu').length).toBe(1) + expect(wrapper.findAll('.dropdown-menu .dropdown-item').length).toBe(4) + + const $toggle = wrapper.find('.dropdown-toggle') + const $menu = wrapper.find('.dropdown-menu') + const $items = wrapper.findAll('.dropdown-item') + + // Expect menu to be closed + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + + // Trigger keydown.down on toggle to open menu + $toggle.trigger('keydown.down') + await wrapper.vm.$nextTick() + expect($toggle.attributes('aria-expanded')).toEqual('true') + expect(document.activeElement).toBe($menu.element) + + // Move to first menu item + $menu.trigger('keydown.down') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(0).element) + + // Move to second menu item + $menu.trigger('keydown.down') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(1).element) + + // Move down to next menu item (should skip disabled item) + $menu.trigger('keydown.down') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(3).element) + + // Move down to next menu item (should remain on same item) + $menu.trigger('keydown.down') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(3).element) + + // Move up to previous menu item (should skip disabled item) + $menu.trigger('keydown.up') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(1).element) + + // Move up to previous menu item + $menu.trigger('keydown.up') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(0).element) + + // Move up to previous menu item (should remain on first item) + $menu.trigger('keydown.up') + await wrapper.vm.$nextTick() + expect(document.activeElement).toBe($items.at(0).element) + + wrapper.destroy() + }) }) From d2f2a8f9e6cea5251e9d25d25dc1cd7a802e1b53 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 15:54:51 -0300 Subject: [PATCH 39/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 62f67f83f22..37ac23802b2 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -409,10 +409,10 @@ describe('dropdown', () => { render(h) { return h('div', {}, [ h(Dropdown, { props: { id: 'test' } }, [ - h(DropdownItem, {}, 'item'), - h(DropdownItem, {}, 'item'), - h(DropdownItem, { disabled: true }, 'item'), - h(DropdownItem, {}, 'item') + h(DropdownItem, { id: 'item-1' }, 'item'), + h(DropdownItem, { id: 'item-2' }, 'item'), + h(DropdownItem, { id: 'item-3', disabled: true }, 'item'), + h(DropdownItem, { id: 'item-4' }, 'item') ]) ]) } @@ -450,32 +450,32 @@ describe('dropdown', () => { expect(document.activeElement).toBe($items.at(0).element) // Move to second menu item - $menu.trigger('keydown.down') + $items.at(0).trigger('keydown.down') await wrapper.vm.$nextTick() expect(document.activeElement).toBe($items.at(1).element) // Move down to next menu item (should skip disabled item) - $menu.trigger('keydown.down') + $items.at(1).trigger('keydown.down') await wrapper.vm.$nextTick() expect(document.activeElement).toBe($items.at(3).element) // Move down to next menu item (should remain on same item) - $menu.trigger('keydown.down') + $items.at(3).trigger('keydown.down') await wrapper.vm.$nextTick() expect(document.activeElement).toBe($items.at(3).element) // Move up to previous menu item (should skip disabled item) - $menu.trigger('keydown.up') + $items.at(3).trigger('keydown.up') await wrapper.vm.$nextTick() expect(document.activeElement).toBe($items.at(1).element) // Move up to previous menu item - $menu.trigger('keydown.up') + $items.at(1).trigger('keydown.up') await wrapper.vm.$nextTick() expect(document.activeElement).toBe($items.at(0).element) // Move up to previous menu item (should remain on first item) - $menu.trigger('keydown.up') + $items.at(0).trigger('keydown.up') await wrapper.vm.$nextTick() expect(document.activeElement).toBe($items.at(0).element) From 4466366e06fefa1274d8f3ce3942481ce8111158 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:00:08 -0300 Subject: [PATCH 40/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 37ac23802b2..01fe08ecabd 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -409,10 +409,10 @@ describe('dropdown', () => { render(h) { return h('div', {}, [ h(Dropdown, { props: { id: 'test' } }, [ - h(DropdownItem, { id: 'item-1' }, 'item'), - h(DropdownItem, { id: 'item-2' }, 'item'), - h(DropdownItem, { id: 'item-3', disabled: true }, 'item'), - h(DropdownItem, { id: 'item-4' }, 'item') + h(DropdownItem, { attrs: { id: 'item-1' } }, 'item'), + h(DropdownItem, { attrs: { id: 'item-2' } }, 'item'), + h(DropdownItem, { attrs: { id: 'item-3' }, props: { disabled: true } }, 'item'), + h(DropdownItem, { attrs: { id: 'item-4' } }, 'item') ]) ]) } From 69c6167b018e8d706f69208aed7c26613cae2956 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:07:30 -0300 Subject: [PATCH 41/59] Update dropdown.js --- src/mixins/dropdown.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mixins/dropdown.js b/src/mixins/dropdown.js index eedf9d7b48e..3b723355bf5 100644 --- a/src/mixins/dropdown.js +++ b/src/mixins/dropdown.js @@ -171,6 +171,7 @@ export default { }, showMenu() { if (this.disabled) { + /* istanbul ignore next */ return } // Ensure other menus are closed @@ -382,6 +383,7 @@ export default { // Keyboard nav focusNext(evt, up) { if (!this.visible) { + /* istanbul ignore next: should never happen */ return } evt.preventDefault() @@ -389,6 +391,7 @@ export default { this.$nextTick(() => { const items = this.getItems() if (items.length < 1) { + /* istanbul ignore next: should never happen */ return } let index = items.indexOf(evt.target) @@ -398,6 +401,7 @@ export default { index++ } if (index < 0) { + /* istanbul ignore next: should never happen */ index = 0 } this.focusItem(index, items) From 68e33abeb01e9c5936d284a571917e98334c365f Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:12:25 -0300 Subject: [PATCH 42/59] Update dropdown.legacy.spec.js --- .../dropdown/dropdown.legacy.spec.js | 105 +----------------- 1 file changed, 2 insertions(+), 103 deletions(-) diff --git a/src/components/dropdown/dropdown.legacy.spec.js b/src/components/dropdown/dropdown.legacy.spec.js index 88fd18f20d7..51893d412b7 100644 --- a/src/components/dropdown/dropdown.legacy.spec.js +++ b/src/components/dropdown/dropdown.legacy.spec.js @@ -1,50 +1,9 @@ import { loadFixture, testVM } from '../../../tests/utils' -describe('dropdown', () => { +describe('dropdown (legacy tests)', () => { beforeEach(loadFixture(__dirname, 'dropdown')) testVM() - it('should work', async () => { - const { - app: { $refs } - } = window - const dds = Object.keys($refs).map(ref => $refs[ref]) - - dds.forEach(dd => { - expect(dd._isVue).toBe(true) - expect(dd).toHaveClass('dropdown') - }) - }) - - it('should work with shorthand component tag names', async () => { - const { - app: { $refs } - } = window - const { dd_5 } = $refs // eslint-disable-line camelcase - - expect(dd_5).toBeComponent('b-dd') - }) - - /* - // This test complains somewhat due to mising Range functions in JSDOM - // Commenting out for now - it("should open only one dropdown at a time", async () => { - const { app: { $refs } } = window; - const dds = Object.keys($refs).map(ref => $refs[ref]); - - // Without async iterators, just use a for loop. - for (let i = 0; i < dds.length; i++) { - Array.from(dds[i].$el.children) - .find(node => node.tagName === "BUTTON" && node.id === `${dds[i].safeId('_BV_toggle_')}`) - .click(); - // Await the next render after click triggers dropdown. - await nextTick(); - const openDds = dds.filter(dd => dd.$el.classList.contains("show")); - expect(openDds.length).toBe(1); - } - }); -*/ - it('should have "dropdown-toggle-no-caret" class when no-caret is true', async () => { const { app: { $refs } @@ -68,6 +27,7 @@ describe('dropdown', () => { ) expect(toggle).not.toHaveClass('dropdown-toggle-no-caret') }) + /* it('boundary set to viewport should have class position-static', async () => { const {app: {$refs}} = window @@ -93,65 +53,4 @@ describe('dropdown', () => { const toggle = dd_10.$el.querySelector('.dropdown-toggle') expect(toggle).toBeElement('div') }) - - it('dd-item should render as link by default', async () => { - const { - app: { $refs } - } = window - const { dd_6 } = $refs // eslint-disable-line camelcase - - expect( - Array.from(dd_6.$refs.menu.children).find(node => node.innerHTML === 'link') - ).toBeElement('a') - }) - - it('dd-item-button should render as button', async () => { - const { - app: { $refs } - } = window - const { dd_6 } = $refs // eslint-disable-line camelcase - - expect( - Array.from(dd_6.$refs.menu.children).find(node => node.innerHTML === 'button') - ).toBeElement('button') - }) - - it('dd-divider should render', async () => { - const { - app: { $refs } - } = window - const { dd_6 } = $refs // eslint-disable-line camelcase - - expect( - Array.from(dd_6.$refs.menu.children).filter(node => - node.classList.contains('dropdown-divider') - ).length - ).toBe(1) - }) - - it('.dropdown menu aria-labelledby should target `_BV_toggle_` when not in split mode', async () => { - const { - app: { $refs } - } = window - const { dd_1 } = $refs // eslint-disable-line camelcase - - const menu = Array.from(dd_1.$el.children).find( - node => node.attributes.role && node.attributes.role.value === 'menu' - ) - - expect(menu.attributes['aria-labelledby'].value).toMatch(/_BV_toggle_$/) - }) - - it('.dropdown menu aria-labelledby should target `_BV_button_` when in split mode', async () => { - const { - app: { $refs } - } = window - const { dd_2 } = $refs // eslint-disable-line camelcase - - const menu = Array.from(dd_2.$el.children).find( - node => node.attributes.role && node.attributes.role.value === 'menu' - ) - - expect(menu.attributes['aria-labelledby'].value).toMatch(/_BV_button_$/) - }) }) From 5d7753cfbebc10e0aa4a797fe4b6de762ee12b04 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:19:53 -0300 Subject: [PATCH 43/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 01fe08ecabd..385410c4d91 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -246,6 +246,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') // Open menu by clicking toggle $toggle.trigger('click') @@ -254,49 +255,58 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') + expect($dropdown.classes()).toContain('show') expect(document.activeElement).toBe($menu.element) // Close menu by clicking toggle again $toggle.trigger('click') await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') // Open menu again $toggle.trigger('click') await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('true') expect(document.activeElement).toBe($menu.element) + expect($dropdown.classes()).toContain('show') // Close by clicking dropdown-item $item.trigger('click') await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') // Open menu via .show() method $dropdown.vm.show() await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('true') + expect($dropdown.classes()).toContain('show') // Close menu via .hide() method $dropdown.vm.hide() await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') // Open menu via .show() method again $dropdown.vm.show() await wrapper.vm.$nextTick() expect($toggle.attributes('aria-expanded')).toEqual('true') + expect($dropdown.classes()).toContain('show') expect(document.activeElement).toBe($menu.element) // Close menu by moving focus away from menu const focusInEvt = new FocusEvent('focusin') document.dispatchEvent(focusInEvt) await wrapper.vm.$nextTick() + expect($dropdown.classes()).not.toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('false') // Open menu via keydown.down event on toggle button $toggle.trigger('keydown.down') await wrapper.vm.$nextTick() + expect($dropdown.classes()).toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('true') expect(document.activeElement).toBe($menu.element) @@ -304,21 +314,25 @@ describe('dropdown', () => { const clickEvt = new MouseEvent('click') document.dispatchEvent(clickEvt) await wrapper.vm.$nextTick() + expect($dropdown.classes()).not.toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('false') // Open menu via .show() method again $dropdown.vm.show() await wrapper.vm.$nextTick() + expect($dropdown.classes()).toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('true') // Close menu by keydown.esc event on dropdown item $item.trigger('keydown.esc') await wrapper.vm.$nextTick() + expect($dropdown.classes()).not.toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('false') // Open menu via .show() method again $dropdown.vm.show() await wrapper.vm.$nextTick() + expect($dropdown.classes()).toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('true') // When disabled changes to true, menu should close @@ -326,11 +340,13 @@ describe('dropdown', () => { disabled: true }) await wrapper.vm.$nextTick() + expect($dropdown.classes()).not.toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('false') // When disabled, show() wont open menu $dropdown.vm.show() await wrapper.vm.$nextTick() + expect($dropdown.classes()).not.toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('false') // Re enable dropdown and open it @@ -340,11 +356,13 @@ describe('dropdown', () => { await wrapper.vm.$nextTick() $dropdown.vm.show() await wrapper.vm.$nextTick() + expect($dropdown.classes()).toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('true') // Should close on root emit when argument is not self wrapper.vm.$root.$emit('bv::dropdown::shown', {}) await wrapper.vm.$nextTick() + expect($dropdown.classes()).not.toContain('show') expect($toggle.attributes('aria-expanded')).toEqual('false') wrapper.destroy() @@ -370,12 +388,15 @@ describe('dropdown', () => { expect(wrapper.emitted('show')).not.toBeDefined() expect(wrapper.findAll('button').length).toBe(1) + expect(wrapper.findAll('.dropdown').length).toBe(1) const $toggle = wrapper.find('button') + const $dropdown = wrapper.find('.dropdown') expect($toggle.attributes('aria-haspopup')).toBeDefined() expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') // Should prevent menu from opening $toggle.trigger('click') @@ -387,6 +408,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') // Allow menu to open prevent = false @@ -399,6 +421,7 @@ describe('dropdown', () => { expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('true') + expect($dropdown.classes()).toContain('show') wrapper.destroy() }) From 8d2781337cbd4c1b6795152eff6103fdf44b961d Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:25:30 -0300 Subject: [PATCH 44/59] Update dropdown.js --- src/mixins/dropdown.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mixins/dropdown.js b/src/mixins/dropdown.js index 3b723355bf5..76c06e7baf6 100644 --- a/src/mixins/dropdown.js +++ b/src/mixins/dropdown.js @@ -179,6 +179,7 @@ export default { // Are we in a navbar ? if (this.inNavbar === null && this.isNav) { + /* istanbul ignore next */ this.inNavbar = Boolean(closest('.navbar', this.$el)) } From 4deba19ca6d68922e6dd97762b26e454d2724323 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:27:48 -0300 Subject: [PATCH 45/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 58 ++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 385410c4d91..aac1d205867 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -426,6 +426,64 @@ describe('dropdown', () => { wrapper.destroy() }) + it('preventDefault() works on toggle event', async () => { + let prevent = true + const wrapper = mount(Dropdown, { + attachToDocument: true, + listeners: { + toggle: evt => { + if (prevent) { + evt.preventDefault() + } + } + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + await wrapper.vm.$nextTick() + + expect(wrapper.emitted('show')).not.toBeDefined() + + expect(wrapper.findAll('button').length).toBe(1) + expect(wrapper.findAll('.dropdown').length).toBe(1) + const $toggle = wrapper.find('button') + const $dropdown = wrapper.find('.dropdown') + + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') + + // Should prevent menu from opening + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect(wrapper.emitted('show')).toBeDefined() + expect(wrapper.emitted('show').length).toBe(1) + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('false') + expect($dropdown.classes()).not.toContain('show') + + // Allow menu to open + prevent = false + $toggle.trigger('click') + await wrapper.vm.$nextTick() + + expect(wrapper.emitted('show')).toBeDefined() + expect(wrapper.emitted('show').length).toBe(2) + expect($toggle.attributes('aria-haspopup')).toBeDefined() + expect($toggle.attributes('aria-haspopup')).toEqual('true') + expect($toggle.attributes('aria-expanded')).toBeDefined() + expect($toggle.attributes('aria-expanded')).toEqual('true') + expect($dropdown.classes()).toContain('show') + + wrapper.destroy() + }) + it('Keyboard navigation works when open', async () => { const localVue = new CreateLocalVue() const App = localVue.extend({ From 19fd45d4826ea52305f5b5d071d7e2584d6a15ef Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:32:24 -0300 Subject: [PATCH 46/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index aac1d205867..582b2abd807 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -443,7 +443,7 @@ describe('dropdown', () => { expect(wrapper.isVueInstance()).toBe(true) await wrapper.vm.$nextTick() - expect(wrapper.emitted('show')).not.toBeDefined() + expect(wrapper.emitted('toggle')).not.toBeDefined() expect(wrapper.findAll('button').length).toBe(1) expect(wrapper.findAll('.dropdown').length).toBe(1) @@ -455,13 +455,16 @@ describe('dropdown', () => { expect($toggle.attributes('aria-expanded')).toBeDefined() expect($toggle.attributes('aria-expanded')).toEqual('false') expect($dropdown.classes()).not.toContain('show') + expect(wrapper.emitted('toggle')).not.toBeDefined() + expect(wrapper.emitted('show')).not.toBeDefined() // Should prevent menu from opening $toggle.trigger('click') await wrapper.vm.$nextTick() - expect(wrapper.emitted('show')).toBeDefined() - expect(wrapper.emitted('show').length).toBe(1) + expect(wrapper.emitted('toggle')).toBeDefined() + expect(wrapper.emitted('toggle').length).toBe(1) + expect(wrapper.emitted('show')).not.toBeDefined() expect($toggle.attributes('aria-haspopup')).toBeDefined() expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() @@ -473,8 +476,9 @@ describe('dropdown', () => { $toggle.trigger('click') await wrapper.vm.$nextTick() + expect(wrapper.emitted('toggle')).toBeDefined() + expect(wrapper.emitted('toggle').length).toBe(2) expect(wrapper.emitted('show')).toBeDefined() - expect(wrapper.emitted('show').length).toBe(2) expect($toggle.attributes('aria-haspopup')).toBeDefined() expect($toggle.attributes('aria-haspopup')).toEqual('true') expect($toggle.attributes('aria-expanded')).toBeDefined() From 7b5791ce073fb8dc1b212d4c38e6f6434ceb5ed3 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:48:44 -0300 Subject: [PATCH 47/59] Update dropdown.legacy.spec.js --- .../dropdown/dropdown.legacy.spec.js | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/src/components/dropdown/dropdown.legacy.spec.js b/src/components/dropdown/dropdown.legacy.spec.js index 51893d412b7..0f76748647c 100644 --- a/src/components/dropdown/dropdown.legacy.spec.js +++ b/src/components/dropdown/dropdown.legacy.spec.js @@ -4,30 +4,6 @@ describe('dropdown (legacy tests)', () => { beforeEach(loadFixture(__dirname, 'dropdown')) testVM() - it('should have "dropdown-toggle-no-caret" class when no-caret is true', async () => { - const { - app: { $refs } - } = window - const { dd_7 } = $refs // eslint-disable-line camelcase - - const toggle = Array.from(dd_7.$el.children).find( - node => node.tagName === 'BUTTON' && node.id === `${dd_7.safeId('_BV_toggle_')}` - ) - expect(toggle).toHaveClass('dropdown-toggle-no-caret') - }) - - it('should not have "dropdown-toggle-no-caret" class when no-caret and split are true', async () => { - const { - app: { $refs } - } = window - const { dd_8 } = $refs // eslint-disable-line camelcase - - const toggle = Array.from(dd_8.$el.children).find( - node => node.tagName === 'BUTTON' && node.id === `${dd_8.safeId('_BV_toggle_')}` - ) - expect(toggle).not.toHaveClass('dropdown-toggle-no-caret') - }) - /* it('boundary set to viewport should have class position-static', async () => { const {app: {$refs}} = window @@ -43,14 +19,4 @@ describe('dropdown (legacy tests)', () => { expect(dd_1).not.toHaveClass('position-static') }) */ - - it('should have a toggle with the given toggle tag', async () => { - const { - app: { $refs } - } = window - const { dd_10 } = $refs // eslint-disable-line camelcase - - const toggle = dd_10.$el.querySelector('.dropdown-toggle') - expect(toggle).toBeElement('div') - }) }) From 899d6a9e8d1582282742a3c10dde5e05f1798bdd Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 16:48:49 -0300 Subject: [PATCH 48/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 582b2abd807..f9f4fdae356 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -192,6 +192,100 @@ describe('dropdown', () => { wrapper.destroy() }) + it('should have "dropdown-toggle-no-caret" class when no-caret is true', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + noCaret: true + } + }) + expect(wrapper.find('.dropdown-toggle').classes()).toContain('dropdown-toggle-no-caret') + wrapper.destroy() + }) + + it('should not have "dropdown-toggle-no-caret" class when no-caret and split are true', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + noCaret: true, + split: true + } + }) + expect(wrapper.find('.dropdown-toggle').classes()).not.toContain('dropdown-toggle-no-caret') + wrapper.destroy() + }) + + it('should have a toggle with the given toggle tag', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + toggleTag: 'div' + } + }) + expect(wrapper.find('.dropdown-toggle').is('div')).toBe(true) + wrapper.destroy() + }) + + it('should have class dropup when prop dropup set', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + dropup: true + } + }) + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropup') + expect(wrapper.classes()).not.toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() + await wrapper.vm.$nextTick() + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropup') + expect(wrapper.classes()).toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() + }) + + it('should have class dropright when prop dropright set', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + dropright: true + } + }) + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropright') + expect(wrapper.classes()).not.toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() + await wrapper.vm.$nextTick() + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropright') + expect(wrapper.classes()).toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() + }) + + it('should have class dropleft when prop dropleft set', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + dropleft: true + } + }) + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropleft') + expect(wrapper.classes()).not.toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() + await wrapper.vm.$nextTick() + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropleft') + expect(wrapper.classes()).toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() + }) + it('split mode emits click event when split button clicked', async () => { const wrapper = mount(Dropdown, { attachToDocument: true, From 19ebbc359c4b7d4026601985f553da3d8faaa0ae Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:00:16 -0300 Subject: [PATCH 49/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index f9f4fdae356..69fd6f902e2 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -286,6 +286,27 @@ describe('dropdown', () => { wrapper.destroy() }) + it('menu should have class dropdown-menu-right when prop right set', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + right: true + } + }) + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).not.toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right') + expect(wrapper.find('.dropdown-menu').classes()).not.toContain('show') + wrapper.vm.show() + await wrapper.vm.$nextTick() + expect(wrapper.classes()).toContain('dropdown') + expect(wrapper.classes()).toContain('dropup') + expect(wrapper.classes()).toContain('show') + expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right') + expect(wrapper.find('.dropdown-menu').classes()).toContain('show') + wrapper.destroy() + }) + it('split mode emits click event when split button clicked', async () => { const wrapper = mount(Dropdown, { attachToDocument: true, From 44b4778c8b1063161ed46cb8f4d681c326999f00 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:04:03 -0300 Subject: [PATCH 50/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 69fd6f902e2..95d5339f9bb 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -300,7 +300,6 @@ describe('dropdown', () => { wrapper.vm.show() await wrapper.vm.$nextTick() expect(wrapper.classes()).toContain('dropdown') - expect(wrapper.classes()).toContain('dropup') expect(wrapper.classes()).toContain('show') expect(wrapper.find('.dropdown-menu').classes()).toContain('dropdown-menu-right') expect(wrapper.find('.dropdown-menu').classes()).toContain('show') From 22005bda602a71681da7bf2f1adfa1f24086b43a Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:09:30 -0300 Subject: [PATCH 51/59] Delete dropdown.legacy.spec.js --- .../dropdown/dropdown.legacy.spec.js | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/components/dropdown/dropdown.legacy.spec.js diff --git a/src/components/dropdown/dropdown.legacy.spec.js b/src/components/dropdown/dropdown.legacy.spec.js deleted file mode 100644 index 0f76748647c..00000000000 --- a/src/components/dropdown/dropdown.legacy.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -import { loadFixture, testVM } from '../../../tests/utils' - -describe('dropdown (legacy tests)', () => { - beforeEach(loadFixture(__dirname, 'dropdown')) - testVM() - - /* - it('boundary set to viewport should have class position-static', async () => { - const {app: {$refs}} = window - const {dd_9} = $refs - - expect(dd_9).toHaveClass('position-static') - }) - - it('boundary not set should not have class position-static', async () => { - const {app: {$refs}} = window - const {dd_1} = $refs - - expect(dd_1).not.toHaveClass('position-static') - }) - */ -}) From add1f9bcd8ee7da0a80818633c033770abc31116 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:09:42 -0300 Subject: [PATCH 52/59] Delete dropdown.html --- .../dropdown/fixtures/dropdown.html | 150 ------------------ 1 file changed, 150 deletions(-) delete mode 100644 src/components/dropdown/fixtures/dropdown.html diff --git a/src/components/dropdown/fixtures/dropdown.html b/src/components/dropdown/fixtures/dropdown.html deleted file mode 100644 index 2cfbb0166d2..00000000000 --- a/src/components/dropdown/fixtures/dropdown.html +++ /dev/null @@ -1,150 +0,0 @@ -
- - Action - Another action - Something else here - - -

- - - Action - Another action - Something else here... - - -

- - - Action - Another action - Something else here - - -

- - - Action - Another action - Something else here - - -

- - - Action - Another action - Something else here - - - - link - header - button - - - -

- - - - - Action - Another action - Something else here... - - -

- - - Action - Another action - Something else here... - - -

- - - Action - Another action - - -

- - - Action - Another action - - -

- - - Action - Another action - Something else here - - -

- - - Action - Another action - Something else here - - -

- - - Action - Another action - Something else here - - -

- - - Action - Another action - Something else here - -
From 4481e02de0c3fec1ab54ba0c8a5d9deb1f29f01d Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:09:52 -0300 Subject: [PATCH 53/59] Delete dropdown.js --- src/components/dropdown/fixtures/dropdown.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 src/components/dropdown/fixtures/dropdown.js diff --git a/src/components/dropdown/fixtures/dropdown.js b/src/components/dropdown/fixtures/dropdown.js deleted file mode 100644 index 0bae7b95202..00000000000 --- a/src/components/dropdown/fixtures/dropdown.js +++ /dev/null @@ -1,3 +0,0 @@ -window.app = new Vue({ - el: '#app' -}) From a49e3d75974e9343064e5e25f3503350eef4f2ef Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:14:24 -0300 Subject: [PATCH 54/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 95d5339f9bb..f7c4ec9394c 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -680,4 +680,30 @@ describe('dropdown', () => { wrapper.destroy() }) + + + it('when boundary not set should not have class position-static', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + await wrapper.vm.$nextTick() + expect(wrapper.classes()).not.toContain('position-static') + wrapper.destroy() + }) + + it('when boundary set to viewport should have class position-static', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + boundary: 'viewport' + } + }) + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + await wrapper.vm.$nextTick() + expect(wrapper.classes()).toContain('position-static') + wrapper.destroy() + }) }) From b3822747fafcc623a77a9f67bc64bac1843a914a Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:16:10 -0300 Subject: [PATCH 55/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index f7c4ec9394c..dcb3001d7b4 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -681,7 +681,6 @@ describe('dropdown', () => { wrapper.destroy() }) - it('when boundary not set should not have class position-static', async () => { const wrapper = mount(Dropdown, { attachToDocument: true From 1b800e9f02cda75bb15f52dc6032a0a4340cfbfd Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:22:53 -0300 Subject: [PATCH 56/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index dcb3001d7b4..453103b4039 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -705,4 +705,60 @@ describe('dropdown', () => { expect(wrapper.classes()).toContain('position-static') wrapper.destroy() }) + + it('split mode has href when prop split-href set', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + split: true, + splitHref: '/foo' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(2) + const $buttons = wrapper.findAll('.btn') + const $split = $buttons.at(0) + const $toggle = $buttons.at(1) + + expect($toggle.is('button')).toBe(true) + + expect($split.is('a')).toBe(true) + expect($split.classes()).toContain('btn') + expect($split.classes()).toContain('btn-secondary') + expect($split.attributes('href')).toBeDefined() + expect($split.attributes('href')).toEqual('/foo') + + wrapper.destroy() + }) + + it('split mode has href when prop split-to set', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + split: true, + splitTo: '/foo' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(2) + const $buttons = wrapper.findAll('.btn') + const $split = $buttons.at(0) + const $toggle = $buttons.at(1) + + expect($toggle.is('button')).toBe(true) + + expect($split.is('a')).toBe(true) + expect($split.classes()).toContain('btn') + expect($split.classes()).toContain('btn-secondary') + expect($split.attributes('href')).toBeDefined() + expect($split.attributes('href')).toEqual('/foo') + + wrapper.destroy() + }) }) From 70454f887a2f5917de5d33f2f57ac2fe7ca402bf Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:36:21 -0300 Subject: [PATCH 57/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 140 +++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 453103b4039..ff8f0682528 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -10,6 +10,7 @@ describe('dropdown', () => { // https://github.com/FezVrasta/popper.js/issues/478#issuecomment-407422016 // Hack to make Popper not bork out during tests. // Note popper still does not do any positiioning claculation in JSDOM though. + // So we cannpt test actual positioning of the menu... just detect when it is open. document.createRange = () => ({ setStart: () => {}, setEnd: () => {}, @@ -706,6 +707,145 @@ describe('dropdown', () => { wrapper.destroy() }) + it('toggle button size works', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + size: 'lg' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(1) + const $toggle = wrapper.find('.btn') + + expect($toggle.is('button')).toBe(true) + expect($toggle.classes()).toContain('btn-lg') + + wrapper.destroy() + }) + + it('split button size works', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + split: true, + size: 'lg' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(2) + const $split = wrapper.findAll('.btn').at(0) + const $toggle = wrapper.findAll('.btn').at(1) + + expect($split.is('button')).toBe(true) + expect($split.classes()).toContain('btn-lg') + expect($toggle.is('button')).toBe(true) + expect($toggle.classes()).toContain('btn-lg') + + wrapper.destroy() + }) + + it('toggle button content works', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + text: 'foobar' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(1) + const $toggle = wrapper.find('.btn') + + expect($toggle.is('button')).toBe(true) + expect($toggle.text()).toEqual('foobar') + + wrapper.destroy() + }) + + it('split button content works', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + split: true, + text: 'foobar' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(2) + const $split = wrapper.findAll('.btn').at(0) + + expect($split.is('button')).toBe(true) + expect($split.text()).toEqual('foobar') + + wrapper.destroy() + }) + + it('variant works on non-split button', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + varaint: 'primary' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(1) + const $toggle = wrapper.find('.btn') + + expect($toggle.is('button')).toBe(true) + expect($toggle.classes()).toContain('btn-primary') + expect($toggle.classes()).not.toContain('btn-secondary') + + wrapper.destroy() + }) + + it('variant works on split button', async () => { + const wrapper = mount(Dropdown, { + attachToDocument: true, + propsData: { + varaint: 'primary' + } + }) + + expect(wrapper.is('div')).toBe(true) + expect(wrapper.isVueInstance()).toBe(true) + + expect(wrapper.findAll('.btn').length).toBe(2) + const $split = wrapper.findAll('.btn').at(0) + const $toggle = wrapper.findAll('.btn').at(1) + + expect($split.is('button')).toBe(true) + expect($split.classes()).toContain('btn-primary') + expect($split.classes()).not.toContain('btn-secondary') + + expect($toggle.is('button')).toBe(true) + expect($toggle.classes()).toContain('btn-primary') + expect($toggle.classes()).not.toContain('btn-secondary') + + // Change split button variant + wrapper.setProps({ + splitVariant: 'danger' + }) + expect($split.classes()).toContain('btn-danger') + expect($toggle.classes()).toContain('btn-primary') + + wrapper.destroy() + }) + it('split mode has href when prop split-href set', async () => { const wrapper = mount(Dropdown, { attachToDocument: true, From 7e5999d700d03acaac6c9568b2961a0824770868 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:39:15 -0300 Subject: [PATCH 58/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index ff8f0682528..4a90a093eb8 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -796,7 +796,7 @@ describe('dropdown', () => { const wrapper = mount(Dropdown, { attachToDocument: true, propsData: { - varaint: 'primary' + variant: 'primary' } }) @@ -817,7 +817,7 @@ describe('dropdown', () => { const wrapper = mount(Dropdown, { attachToDocument: true, propsData: { - varaint: 'primary' + variant: 'primary' } }) From c22841cdbfdb3bb7f690c7312f2f75936dcd3df6 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Mon, 1 Apr 2019 17:44:46 -0300 Subject: [PATCH 59/59] Update dropdown.spec.js --- src/components/dropdown/dropdown.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/dropdown/dropdown.spec.js b/src/components/dropdown/dropdown.spec.js index 4a90a093eb8..f3ea7671b4e 100644 --- a/src/components/dropdown/dropdown.spec.js +++ b/src/components/dropdown/dropdown.spec.js @@ -817,6 +817,7 @@ describe('dropdown', () => { const wrapper = mount(Dropdown, { attachToDocument: true, propsData: { + split: true, variant: 'primary' } })