Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoSot <geo.sotis@gmail.com>2022-01-30 15:30:04 +0300
committerGitHub <noreply@github.com>2022-01-30 15:30:04 +0300
commitaa650f0f1e30279f0868433a4afab9c3efa93b2c (patch)
tree88cf537f2e7b6613bc2e53d4e38ca93798786d07 /js/tests/unit/dropdown.spec.js
parentd09281705988690b63a5364548447c603cb557fd (diff)
tests: replace 'done' callback with 'Promise' to fix deprecation errors (#35659)
Reference: https://jasmine.github.io/tutorials/async 'DEPRECATION: An asynchronous function called its 'done' callback more than once. This is a bug in the spec, beforeAll, beforeEach, afterAll, or afterEach function in question. This will be treated as an error in a future version. See<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#deprecations-due-to-calling-done-multiple-times> for more information.
Diffstat (limited to 'js/tests/unit/dropdown.spec.js')
-rw-r--r--js/tests/unit/dropdown.spec.js2856
1 files changed, 1486 insertions, 1370 deletions
diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js
index 6ee58fe71a..f24b59ed5c 100644
--- a/js/tests/unit/dropdown.spec.js
+++ b/js/tests/unit/dropdown.spec.js
@@ -57,36 +57,38 @@ describe('Dropdown', () => {
expect(dropdownByElement._element).toEqual(btnDropdown)
})
- it('should create offset modifier correctly when offset option is a function', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
-
- const getOffset = jasmine.createSpy('getOffset').and.returnValue([10, 20])
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown, {
- offset: getOffset,
- popperConfig: {
- onFirstUpdate: state => {
- expect(getOffset).toHaveBeenCalledWith({
- popper: state.rects.popper,
- reference: state.rects.reference,
- placement: state.placement
- }, btnDropdown)
- done()
+ it('should create offset modifier correctly when offset option is a function', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const getOffset = jasmine.createSpy('getOffset').and.returnValue([10, 20])
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown, {
+ offset: getOffset,
+ popperConfig: {
+ onFirstUpdate: state => {
+ expect(getOffset).toHaveBeenCalledWith({
+ popper: state.rects.popper,
+ reference: state.rects.reference,
+ placement: state.placement
+ }, btnDropdown)
+ resolve()
+ }
}
- }
- })
- const offset = dropdown._getOffset()
+ })
+ const offset = dropdown._getOffset()
- expect(typeof offset).toEqual('function')
+ expect(typeof offset).toEqual('function')
- dropdown.show()
+ dropdown.show()
+ })
})
it('should create offset modifier correctly when offset option is a string into data attribute', () => {
@@ -151,761 +153,817 @@ describe('Dropdown', () => {
})
describe('toggle', () => {
- it('should toggle a dropdown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
-
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ it('should toggle a dropdown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
+
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
+ dropdown.toggle()
})
-
- dropdown.toggle()
})
- it('should destroy old popper references on toggle', done => {
- fixtureEl.innerHTML = [
- '<div class="first dropdown">',
- ' <button class="firstBtn btn" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>',
- '<div class="second dropdown">',
- ' <button class="secondBtn btn" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should destroy old popper references on toggle', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="first dropdown">',
+ ' <button class="firstBtn btn" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>',
+ '<div class="second dropdown">',
+ ' <button class="secondBtn btn" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown1 = fixtureEl.querySelector('.firstBtn')
+ const btnDropdown2 = fixtureEl.querySelector('.secondBtn')
+ const firstDropdownEl = fixtureEl.querySelector('.first')
+ const secondDropdownEl = fixtureEl.querySelector('.second')
+ const dropdown1 = new Dropdown(btnDropdown1)
+
+ firstDropdownEl.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown1).toHaveClass('show')
+ spyOn(dropdown1._popper, 'destroy')
+ btnDropdown2.click()
+ })
- const btnDropdown1 = fixtureEl.querySelector('.firstBtn')
- const btnDropdown2 = fixtureEl.querySelector('.secondBtn')
- const firstDropdownEl = fixtureEl.querySelector('.first')
- const secondDropdownEl = fixtureEl.querySelector('.second')
- const dropdown1 = new Dropdown(btnDropdown1)
+ secondDropdownEl.addEventListener('shown.bs.dropdown', () => setTimeout(() => {
+ expect(dropdown1._popper.destroy).toHaveBeenCalled()
+ resolve()
+ }))
- firstDropdownEl.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown1).toHaveClass('show')
- spyOn(dropdown1._popper, 'destroy')
- btnDropdown2.click()
+ dropdown1.toggle()
})
-
- secondDropdownEl.addEventListener('shown.bs.dropdown', () => setTimeout(() => {
- expect(dropdown1._popper.destroy).toHaveBeenCalled()
- done()
- }))
-
- dropdown1.toggle()
})
- it('should toggle a dropdown and add/remove event listener on mobile', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropdown and add/remove event listener on mobile', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const defaultValueOnTouchStart = document.documentElement.ontouchstart
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const defaultValueOnTouchStart = document.documentElement.ontouchstart
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- document.documentElement.ontouchstart = noop
- spyOn(EventHandler, 'on')
- spyOn(EventHandler, 'off')
+ document.documentElement.ontouchstart = noop
+ spyOn(EventHandler, 'on')
+ spyOn(EventHandler, 'off')
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- expect(EventHandler.on).toHaveBeenCalledWith(jasmine.any(Object), 'mouseover', noop)
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ expect(EventHandler.on).toHaveBeenCalledWith(jasmine.any(Object), 'mouseover', noop)
- dropdown.toggle()
- })
+ dropdown.toggle()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(btnDropdown).not.toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
- expect(EventHandler.off).toHaveBeenCalledWith(jasmine.any(Object), 'mouseover', noop)
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(btnDropdown).not.toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
+ expect(EventHandler.off).toHaveBeenCalledWith(jasmine.any(Object), 'mouseover', noop)
- document.documentElement.ontouchstart = defaultValueOnTouchStart
- done()
- })
+ document.documentElement.ontouchstart = defaultValueOnTouchStart
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropdown at the right', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu dropdown-menu-end">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropdown at the right', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu dropdown-menu-end">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropup', done => {
- fixtureEl.innerHTML = [
- '<div class="dropup">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropup', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropup">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropupEl = fixtureEl.querySelector('.dropup')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropupEl = fixtureEl.querySelector('.dropup')
+ const dropdown = new Dropdown(btnDropdown)
- dropupEl.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ dropupEl.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropup at the right', done => {
- fixtureEl.innerHTML = [
- '<div class="dropup">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu dropdown-menu-end">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropup at the right', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropup">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu dropdown-menu-end">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropupEl = fixtureEl.querySelector('.dropup')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropupEl = fixtureEl.querySelector('.dropup')
+ const dropdown = new Dropdown(btnDropdown)
- dropupEl.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ dropupEl.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropend', done => {
- fixtureEl.innerHTML = [
- '<div class="dropend">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropend', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropend">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropendEl = fixtureEl.querySelector('.dropend')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropendEl = fixtureEl.querySelector('.dropend')
+ const dropdown = new Dropdown(btnDropdown)
- dropendEl.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ dropendEl.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropstart', done => {
- fixtureEl.innerHTML = [
- '<div class="dropstart">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropstart', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropstart">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropstartEl = fixtureEl.querySelector('.dropstart')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropstartEl = fixtureEl.querySelector('.dropstart')
+ const dropdown = new Dropdown(btnDropdown)
- dropstartEl.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ dropstartEl.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropdown with parent reference', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropdown with parent reference', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown, {
- reference: 'parent'
- })
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown, {
+ reference: 'parent'
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropdown with a dom node reference', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropdown with a dom node reference', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown, {
- reference: fixtureEl
- })
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown, {
+ reference: fixtureEl
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropdown with a jquery object reference', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should toggle a dropdown with a jquery object reference', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown, {
- reference: { 0: fixtureEl, jquery: 'jQuery' }
- })
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown, {
+ reference: { 0: fixtureEl, jquery: 'jQuery' }
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ })
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should toggle a dropdown with a valid virtual element reference', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle visually-hidden" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
-
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const virtualElement = {
- nodeType: 1,
- getBoundingClientRect() {
- return {
- width: 0,
- height: 0,
- top: 0,
- right: 0,
- bottom: 0,
- left: 0
+ it('should toggle a dropdown with a valid virtual element reference', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle visually-hidden" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const virtualElement = {
+ nodeType: 1,
+ getBoundingClientRect() {
+ return {
+ width: 0,
+ height: 0,
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ }
}
}
- }
- expect(() => new Dropdown(btnDropdown, {
- reference: {}
- })).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
+ expect(() => new Dropdown(btnDropdown, {
+ reference: {}
+ })).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
- expect(() => new Dropdown(btnDropdown, {
- reference: {
- getBoundingClientRect: 'not-a-function'
- }
- })).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
-
- // use onFirstUpdate as Poppers internal update is executed async
- const dropdown = new Dropdown(btnDropdown, {
- reference: virtualElement,
- popperConfig: {
- onFirstUpdate() {
- expect(virtualElement.getBoundingClientRect).toHaveBeenCalled()
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
+ expect(() => new Dropdown(btnDropdown, {
+ reference: {
+ getBoundingClientRect: 'not-a-function'
}
- }
- })
+ })).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
+
+ // use onFirstUpdate as Poppers internal update is executed async
+ const dropdown = new Dropdown(btnDropdown, {
+ reference: virtualElement,
+ popperConfig: {
+ onFirstUpdate() {
+ expect(virtualElement.getBoundingClientRect).toHaveBeenCalled()
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ }
+ }
+ })
- spyOn(virtualElement, 'getBoundingClientRect').and.callThrough()
+ spyOn(virtualElement, 'getBoundingClientRect').and.callThrough()
- dropdown.toggle()
+ dropdown.toggle()
+ })
})
- it('should not toggle a dropdown if the element is disabled', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not toggle a dropdown if the element is disabled', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.toggle()
+ dropdown.toggle()
- setTimeout(() => {
- expect().nothing()
- done()
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ })
})
})
- it('should not toggle a dropdown if the element contains .disabled', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle disabled" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not toggle a dropdown if the element contains .disabled', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle disabled" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.toggle()
+ dropdown.toggle()
- setTimeout(() => {
- expect().nothing()
- done()
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ })
})
})
- it('should not toggle a dropdown if the menu is shown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu show">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not toggle a dropdown if the menu is shown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu show">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.toggle()
+ dropdown.toggle()
- setTimeout(() => {
- expect().nothing()
- done()
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ })
})
})
- it('should not toggle a dropdown if show event is prevented', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not toggle a dropdown if show event is prevented', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('show.bs.dropdown', event => {
- event.preventDefault()
- })
+ btnDropdown.addEventListener('show.bs.dropdown', event => {
+ event.preventDefault()
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.toggle()
+ dropdown.toggle()
- setTimeout(() => {
- expect().nothing()
- done()
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ })
})
})
})
describe('show', () => {
- it('should show a dropdown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
-
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ it('should show a dropdown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
+
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
+ resolve()
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
- done()
+ dropdown.show()
})
-
- dropdown.show()
})
- it('should not show a dropdown if the element is disabled', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not show a dropdown if the element is disabled', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.show()
+ dropdown.show()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 10)
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ }, 10)
+ })
})
- it('should not show a dropdown if the element contains .disabled', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle disabled" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not show a dropdown if the element contains .disabled', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle disabled" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.show()
+ dropdown.show()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 10)
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ }, 10)
+ })
})
- it('should not show a dropdown if the menu is shown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu show">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not show a dropdown if the menu is shown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu show">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.show()
+ dropdown.show()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 10)
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ }, 10)
+ })
})
- it('should not show a dropdown if show event is prevented', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not show a dropdown if show event is prevented', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('show.bs.dropdown', event => {
- event.preventDefault()
- })
+ btnDropdown.addEventListener('show.bs.dropdown', event => {
+ event.preventDefault()
+ })
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- throw new Error('should not throw shown.bs.dropdown event')
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ throw new Error('should not throw shown.bs.dropdown event')
+ })
- dropdown.show()
+ dropdown.show()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 10)
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ }, 10)
+ })
})
})
describe('hide', () => {
- it('should hide a dropdown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="true">Dropdown</button>',
- ' <div class="dropdown-menu show">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
-
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ it('should hide a dropdown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="true">Dropdown</button>',
+ ' <div class="dropdown-menu show">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
+
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(dropdownMenu).not.toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
+ resolve()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(dropdownMenu).not.toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
- done()
+ dropdown.hide()
})
-
- dropdown.hide()
})
- it('should hide a dropdown and destroy popper', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should hide a dropdown and destroy popper', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- spyOn(dropdown._popper, 'destroy')
- dropdown.hide()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ spyOn(dropdown._popper, 'destroy')
+ dropdown.hide()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(dropdown._popper.destroy).toHaveBeenCalled()
- done()
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(dropdown._popper.destroy).toHaveBeenCalled()
+ resolve()
+ })
- dropdown.show()
+ dropdown.show()
+ })
})
- it('should not hide a dropdown if the element is disabled', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu show">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not hide a dropdown if the element is disabled', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu show">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- throw new Error('should not throw hidden.bs.dropdown event')
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ throw new Error('should not throw hidden.bs.dropdown event')
+ })
- dropdown.hide()
+ dropdown.hide()
- setTimeout(() => {
- expect(dropdownMenu).toHaveClass('show')
- done()
- }, 10)
+ setTimeout(() => {
+ expect(dropdownMenu).toHaveClass('show')
+ resolve()
+ }, 10)
+ })
})
- it('should not hide a dropdown if the element contains .disabled', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle disabled" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu show">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not hide a dropdown if the element contains .disabled', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle disabled" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu show">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- throw new Error('should not throw hidden.bs.dropdown event')
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ throw new Error('should not throw hidden.bs.dropdown event')
+ })
- dropdown.hide()
+ dropdown.hide()
- setTimeout(() => {
- expect(dropdownMenu).toHaveClass('show')
- done()
- }, 10)
+ setTimeout(() => {
+ expect(dropdownMenu).toHaveClass('show')
+ resolve()
+ }, 10)
+ })
})
- it('should not hide a dropdown if the menu is not shown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not hide a dropdown if the menu is not shown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- throw new Error('should not throw hidden.bs.dropdown event')
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ throw new Error('should not throw hidden.bs.dropdown event')
+ })
- dropdown.hide()
+ dropdown.hide()
- setTimeout(() => {
- expect().nothing()
- done()
- }, 10)
+ setTimeout(() => {
+ expect().nothing()
+ resolve()
+ }, 10)
+ })
})
- it('should not hide a dropdown if hide event is prevented', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu show">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not hide a dropdown if hide event is prevented', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu show">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('hide.bs.dropdown', event => {
- event.preventDefault()
- })
+ btnDropdown.addEventListener('hide.bs.dropdown', event => {
+ event.preventDefault()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- throw new Error('should not throw hidden.bs.dropdown event')
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ throw new Error('should not throw hidden.bs.dropdown event')
+ })
- dropdown.hide()
+ dropdown.hide()
- setTimeout(() => {
- expect(dropdownMenu).toHaveClass('show')
- done()
+ setTimeout(() => {
+ expect(dropdownMenu).toHaveClass('show')
+ resolve()
+ })
})
})
- it('should remove event listener on touch-enabled device that was added in show method', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Dropdwon item</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should remove event listener on touch-enabled device that was added in show method', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Dropdwon item</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const defaultValueOnTouchStart = document.documentElement.ontouchstart
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(btnDropdown)
+ const defaultValueOnTouchStart = document.documentElement.ontouchstart
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(btnDropdown)
- document.documentElement.ontouchstart = noop
- spyOn(EventHandler, 'off')
+ document.documentElement.ontouchstart = noop
+ spyOn(EventHandler, 'off')
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- dropdown.hide()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ dropdown.hide()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(btnDropdown).not.toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
- expect(EventHandler.off).toHaveBeenCalled()
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(btnDropdown).not.toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
+ expect(EventHandler.off).toHaveBeenCalled()
- document.documentElement.ontouchstart = defaultValueOnTouchStart
- done()
- })
+ document.documentElement.ontouchstart = defaultValueOnTouchStart
+ resolve()
+ })
- dropdown.show()
+ dropdown.show()
+ })
})
})
@@ -1013,903 +1071,957 @@ describe('Dropdown', () => {
})
describe('data-api', () => {
- it('should show and hide a dropdown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
-
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- let showEventTriggered = false
- let hideEventTriggered = false
+ it('should show and hide a dropdown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ let showEventTriggered = false
+ let hideEventTriggered = false
+
+ btnDropdown.addEventListener('show.bs.dropdown', () => {
+ showEventTriggered = true
+ })
- btnDropdown.addEventListener('show.bs.dropdown', () => {
- showEventTriggered = true
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', event => setTimeout(() => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ expect(showEventTriggered).toBeTrue()
+ expect(event.relatedTarget).toEqual(btnDropdown)
+ document.body.click()
+ }))
- btnDropdown.addEventListener('shown.bs.dropdown', event => setTimeout(() => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- expect(showEventTriggered).toBeTrue()
- expect(event.relatedTarget).toEqual(btnDropdown)
- document.body.click()
- }))
+ btnDropdown.addEventListener('hide.bs.dropdown', () => {
+ hideEventTriggered = true
+ })
- btnDropdown.addEventListener('hide.bs.dropdown', () => {
- hideEventTriggered = true
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', event => {
+ expect(btnDropdown).not.toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
+ expect(hideEventTriggered).toBeTrue()
+ expect(event.relatedTarget).toEqual(btnDropdown)
+ resolve()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', event => {
- expect(btnDropdown).not.toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('false')
- expect(hideEventTriggered).toBeTrue()
- expect(event.relatedTarget).toEqual(btnDropdown)
- done()
+ btnDropdown.click()
})
-
- btnDropdown.click()
})
- it('should not use "static" Popper in navbar', done => {
- fixtureEl.innerHTML = [
- '<nav class="navbar navbar-expand-md navbar-light bg-light">',
- ' <div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- ' </div>',
- '</nav>'
- ].join('')
+ it('should not use "static" Popper in navbar', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<nav class="navbar navbar-expand-md navbar-light bg-light">',
+ ' <div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ ' </div>',
+ '</nav>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(dropdown._popper).not.toBeNull()
- expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
- done()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(dropdown._popper).not.toBeNull()
+ expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
+ resolve()
+ })
- dropdown.show()
+ dropdown.show()
+ })
})
- it('should not collapse the dropdown when clicking a select option nested in the dropdown', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <select>',
- ' <option selected>Open this select menu</option>',
- ' <option value="1">One</option>',
- ' </select>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not collapse the dropdown when clicking a select option nested in the dropdown', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <select>',
+ ' <option selected>Open this select menu</option>',
+ ' <option value="1">One</option>',
+ ' </select>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- const hideSpy = spyOn(dropdown, '_completeHide')
+ const hideSpy = spyOn(dropdown, '_completeHide')
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- const clickEvent = new MouseEvent('click', {
- bubbles: true
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ const clickEvent = new MouseEvent('click', {
+ bubbles: true
+ })
+
+ dropdownMenu.querySelector('option').dispatchEvent(clickEvent)
})
- dropdownMenu.querySelector('option').dispatchEvent(clickEvent)
- })
+ dropdownMenu.addEventListener('click', event => {
+ expect(event.target.tagName).toMatch(/select|option/i)
- dropdownMenu.addEventListener('click', event => {
- expect(event.target.tagName).toMatch(/select|option/i)
+ Dropdown.clearMenus(event)
- Dropdown.clearMenus(event)
+ setTimeout(() => {
+ expect(hideSpy).not.toHaveBeenCalled()
+ resolve()
+ }, 10)
+ })
- setTimeout(() => {
- expect(hideSpy).not.toHaveBeenCalled()
- done()
- }, 10)
+ dropdown.show()
})
-
- dropdown.show()
})
- it('should manage bs attribute `data-bs-popper`="static" when dropdown is in navbar', done => {
- fixtureEl.innerHTML = [
- '<nav class="navbar navbar-expand-md navbar-light bg-light">',
- ' <div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- ' </div>',
- '</nav>'
- ].join('')
+ it('should manage bs attribute `data-bs-popper`="static" when dropdown is in navbar', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<nav class="navbar navbar-expand-md navbar-light bg-light">',
+ ' <div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ ' </div>',
+ '</nav>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
- dropdown.hide()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
+ dropdown.hide()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(dropdownMenu.getAttribute('data-bs-popper')).toBeNull()
- done()
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(dropdownMenu.getAttribute('data-bs-popper')).toBeNull()
+ resolve()
+ })
- dropdown.show()
+ dropdown.show()
+ })
})
- it('should not use Popper if display set to static', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-display="static">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not use Popper if display set to static', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-display="static">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- // Popper adds this attribute when we use it
- expect(dropdownMenu.getAttribute('data-popper-placement')).toBeNull()
- done()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ // Popper adds this attribute when we use it
+ expect(dropdownMenu.getAttribute('data-popper-placement')).toBeNull()
+ resolve()
+ })
- btnDropdown.click()
+ btnDropdown.click()
+ })
})
- it('should manage bs attribute `data-bs-popper`="static" when display set to static', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-display="static">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should manage bs attribute `data-bs-popper`="static" when display set to static', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-display="static">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const dropdown = new Dropdown(btnDropdown)
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdown = new Dropdown(btnDropdown)
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
- dropdown.hide()
- })
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(dropdownMenu.getAttribute('data-bs-popper')).toEqual('static')
+ dropdown.hide()
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(dropdownMenu.getAttribute('data-bs-popper')).toBeNull()
- done()
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(dropdownMenu.getAttribute('data-bs-popper')).toBeNull()
+ resolve()
+ })
- dropdown.show()
+ dropdown.show()
+ })
})
- it('should remove "show" class if tabbing outside of menu', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should remove "show" class if tabbing outside of menu', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- btnDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(btnDropdown).toHaveClass('show')
+ btnDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(btnDropdown).toHaveClass('show')
- const keyup = createEvent('keyup')
+ const keyup = createEvent('keyup')
- keyup.key = 'Tab'
- document.dispatchEvent(keyup)
- })
+ keyup.key = 'Tab'
+ document.dispatchEvent(keyup)
+ })
- btnDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect(btnDropdown).not.toHaveClass('show')
- done()
- })
+ btnDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect(btnDropdown).not.toHaveClass('show')
+ resolve()
+ })
- btnDropdown.click()
+ btnDropdown.click()
+ })
})
- it('should remove "show" class if body is clicked, with multiple dropdowns', done => {
- fixtureEl.innerHTML = [
- '<div class="nav">',
- ' <div class="dropdown" id="testmenu">',
- ' <a class="dropdown-toggle" data-bs-toggle="dropdown" href="#testmenu">Test menu</a>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
- ' </div>',
- ' </div>',
- '</div>',
- '<div class="btn-group">',
- ' <button class="btn">Actions</button>',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown"></button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Action 1</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should remove "show" class if body is clicked, with multiple dropdowns', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="nav">',
+ ' <div class="dropdown" id="testmenu">',
+ ' <a class="dropdown-toggle" data-bs-toggle="dropdown" href="#testmenu">Test menu</a>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' </div>',
+ ' </div>',
+ '</div>',
+ '<div class="btn-group">',
+ ' <button class="btn">Actions</button>',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown"></button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Action 1</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdownList = fixtureEl.querySelectorAll('[data-bs-toggle="dropdown"]')
+ const triggerDropdownList = fixtureEl.querySelectorAll('[data-bs-toggle="dropdown"]')
- expect(triggerDropdownList).toHaveSize(2)
+ expect(triggerDropdownList).toHaveSize(2)
- const [triggerDropdownFirst, triggerDropdownLast] = triggerDropdownList
+ const [triggerDropdownFirst, triggerDropdownLast] = triggerDropdownList
- triggerDropdownFirst.addEventListener('shown.bs.dropdown', () => {
- expect(triggerDropdownFirst).toHaveClass('show')
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
- document.body.click()
- })
+ triggerDropdownFirst.addEventListener('shown.bs.dropdown', () => {
+ expect(triggerDropdownFirst).toHaveClass('show')
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
+ document.body.click()
+ })
- triggerDropdownFirst.addEventListener('hidden.bs.dropdown', () => {
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
- triggerDropdownLast.click()
- })
+ triggerDropdownFirst.addEventListener('hidden.bs.dropdown', () => {
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
+ triggerDropdownLast.click()
+ })
- triggerDropdownLast.addEventListener('shown.bs.dropdown', () => {
- expect(triggerDropdownLast).toHaveClass('show')
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
- document.body.click()
- })
+ triggerDropdownLast.addEventListener('shown.bs.dropdown', () => {
+ expect(triggerDropdownLast).toHaveClass('show')
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
+ document.body.click()
+ })
- triggerDropdownLast.addEventListener('hidden.bs.dropdown', () => {
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
- done()
- })
+ triggerDropdownLast.addEventListener('hidden.bs.dropdown', () => {
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
+ resolve()
+ })
- triggerDropdownFirst.click()
+ triggerDropdownFirst.click()
+ })
})
- it('should remove "show" class if body if tabbing outside of menu, with multiple dropdowns', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <a class="dropdown-toggle" data-bs-toggle="dropdown" href="#testmenu">Test menu</a>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
- ' </div>',
- '</div>',
- '<div class="btn-group">',
- ' <button class="btn">Actions</button>',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown"></button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Action 1</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should remove "show" class if body if tabbing outside of menu, with multiple dropdowns', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <a class="dropdown-toggle" data-bs-toggle="dropdown" href="#testmenu">Test menu</a>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' </div>',
+ '</div>',
+ '<div class="btn-group">',
+ ' <button class="btn">Actions</button>',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown"></button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Action 1</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdownList = fixtureEl.querySelectorAll('[data-bs-toggle="dropdown"]')
+ const triggerDropdownList = fixtureEl.querySelectorAll('[data-bs-toggle="dropdown"]')
- expect(triggerDropdownList).toHaveSize(2)
+ expect(triggerDropdownList).toHaveSize(2)
- const [triggerDropdownFirst, triggerDropdownLast] = triggerDropdownList
+ const [triggerDropdownFirst, triggerDropdownLast] = triggerDropdownList
- triggerDropdownFirst.addEventListener('shown.bs.dropdown', () => {
- expect(triggerDropdownFirst).toHaveClass('show')
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
+ triggerDropdownFirst.addEventListener('shown.bs.dropdown', () => {
+ expect(triggerDropdownFirst).toHaveClass('show')
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
- const keyup = createEvent('keyup')
- keyup.key = 'Tab'
+ const keyup = createEvent('keyup')
+ keyup.key = 'Tab'
- document.dispatchEvent(keyup)
- })
+ document.dispatchEvent(keyup)
+ })
- triggerDropdownFirst.addEventListener('hidden.bs.dropdown', () => {
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
- triggerDropdownLast.click()
- })
+ triggerDropdownFirst.addEventListener('hidden.bs.dropdown', () => {
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
+ triggerDropdownLast.click()
+ })
- triggerDropdownLast.addEventListener('shown.bs.dropdown', () => {
- expect(triggerDropdownLast).toHaveClass('show')
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
+ triggerDropdownLast.addEventListener('shown.bs.dropdown', () => {
+ expect(triggerDropdownLast).toHaveClass('show')
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(1)
- const keyup = createEvent('keyup')
- keyup.key = 'Tab'
+ const keyup = createEvent('keyup')
+ keyup.key = 'Tab'
- document.dispatchEvent(keyup)
- })
+ document.dispatchEvent(keyup)
+ })
- triggerDropdownLast.addEventListener('hidden.bs.dropdown', () => {
- expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
- done()
- })
+ triggerDropdownLast.addEventListener('hidden.bs.dropdown', () => {
+ expect(fixtureEl.querySelectorAll('.dropdown-menu.show')).toHaveSize(0)
+ resolve()
+ })
- triggerDropdownFirst.click()
+ triggerDropdownFirst.click()
+ })
})
- it('should fire hide and hidden event without a clickEvent if event type is not click', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should fire hide and hidden event without a clickEvent if event type is not click', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- triggerDropdown.addEventListener('hide.bs.dropdown', event => {
- expect(event.clickEvent).toBeUndefined()
- })
+ triggerDropdown.addEventListener('hide.bs.dropdown', event => {
+ expect(event.clickEvent).toBeUndefined()
+ })
- triggerDropdown.addEventListener('hidden.bs.dropdown', event => {
- expect(event.clickEvent).toBeUndefined()
- done()
- })
+ triggerDropdown.addEventListener('hidden.bs.dropdown', event => {
+ expect(event.clickEvent).toBeUndefined()
+ resolve()
+ })
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- const keydown = createEvent('keydown')
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ const keydown = createEvent('keydown')
- keydown.key = 'Escape'
- triggerDropdown.dispatchEvent(keydown)
- })
+ keydown.key = 'Escape'
+ triggerDropdown.dispatchEvent(keydown)
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should bubble up the events to the parent elements', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#subMenu">Sub menu</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should bubble up the events to the parent elements', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#subMenu">Sub menu</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownParent = fixtureEl.querySelector('.dropdown')
- const dropdown = new Dropdown(triggerDropdown)
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownParent = fixtureEl.querySelector('.dropdown')
+ const dropdown = new Dropdown(triggerDropdown)
- const showFunction = jasmine.createSpy('showFunction')
- dropdownParent.addEventListener('show.bs.dropdown', showFunction)
+ const showFunction = jasmine.createSpy('showFunction')
+ dropdownParent.addEventListener('show.bs.dropdown', showFunction)
- const shownFunction = jasmine.createSpy('shownFunction')
- dropdownParent.addEventListener('shown.bs.dropdown', () => {
- shownFunction()
- dropdown.hide()
- })
+ const shownFunction = jasmine.createSpy('shownFunction')
+ dropdownParent.addEventListener('shown.bs.dropdown', () => {
+ shownFunction()
+ dropdown.hide()
+ })
- const hideFunction = jasmine.createSpy('hideFunction')
- dropdownParent.addEventListener('hide.bs.dropdown', hideFunction)
+ const hideFunction = jasmine.createSpy('hideFunction')
+ dropdownParent.addEventListener('hide.bs.dropdown', hideFunction)
- dropdownParent.addEventListener('hidden.bs.dropdown', () => {
- expect(showFunction).toHaveBeenCalled()
- expect(shownFunction).toHaveBeenCalled()
- expect(hideFunction).toHaveBeenCalled()
- done()
- })
+ dropdownParent.addEventListener('hidden.bs.dropdown', () => {
+ expect(showFunction).toHaveBeenCalled()
+ expect(shownFunction).toHaveBeenCalled()
+ expect(hideFunction).toHaveBeenCalled()
+ resolve()
+ })
- dropdown.show()
+ dropdown.show()
+ })
})
- it('should ignore keyboard events within <input>s and <textarea>s', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
- ' <input type="text">',
- ' <textarea></textarea>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should ignore keyboard events within <input>s and <textarea>s', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <input type="text">',
+ ' <textarea></textarea>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const input = fixtureEl.querySelector('input')
- const textarea = fixtureEl.querySelector('textarea')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const input = fixtureEl.querySelector('input')
+ const textarea = fixtureEl.querySelector('textarea')
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- input.focus()
- const keydown = createEvent('keydown')
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ input.focus()
+ const keydown = createEvent('keydown')
- keydown.key = 'ArrowUp'
- input.dispatchEvent(keydown)
+ keydown.key = 'ArrowUp'
+ input.dispatchEvent(keydown)
- expect(document.activeElement).toEqual(input, 'input still focused')
+ expect(document.activeElement).toEqual(input, 'input still focused')
- textarea.focus()
- textarea.dispatchEvent(keydown)
+ textarea.focus()
+ textarea.dispatchEvent(keydown)
- expect(document.activeElement).toEqual(textarea, 'textarea still focused')
- done()
- })
+ expect(document.activeElement).toEqual(textarea, 'textarea still focused')
+ resolve()
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should skip disabled element when using keyboard navigation', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item disabled" href="#sub1">Submenu 1</a>',
- ' <button class="dropdown-item" type="button" disabled>Disabled button</button>',
- ' <a id="item1" class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should skip disabled element when using keyboard navigation', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item disabled" href="#sub1">Submenu 1</a>',
+ ' <button class="dropdown-item" type="button" disabled>Disabled button</button>',
+ ' <a id="item1" class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- const keydown = createEvent('keydown')
- keydown.key = 'ArrowDown'
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowDown'
- triggerDropdown.dispatchEvent(keydown)
- triggerDropdown.dispatchEvent(keydown)
+ triggerDropdown.dispatchEvent(keydown)
+ triggerDropdown.dispatchEvent(keydown)
- expect(document.activeElement).not.toHaveClass('disabled')
- expect(document.activeElement.hasAttribute('disabled')).toBeFalse()
- done()
- })
+ expect(document.activeElement).not.toHaveClass('disabled')
+ expect(document.activeElement.hasAttribute('disabled')).toBeFalse()
+ resolve()
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should skip hidden element when using keyboard navigation', done => {
- fixtureEl.innerHTML = [
- '<style>',
- ' .d-none {',
- ' display: none;',
- ' }',
- '</style>',
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <button class="dropdown-item d-none" type="button">Hidden button by class</button>',
- ' <a class="dropdown-item" href="#sub1" style="display: none">Hidden link</a>',
- ' <a class="dropdown-item" href="#sub1" style="visibility: hidden">Hidden link</a>',
- ' <a id="item1" class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should skip hidden element when using keyboard navigation', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<style>',
+ ' .d-none {',
+ ' display: none;',
+ ' }',
+ '</style>',
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <button class="dropdown-item d-none" type="button">Hidden button by class</button>',
+ ' <a class="dropdown-item" href="#sub1" style="display: none">Hidden link</a>',
+ ' <a class="dropdown-item" href="#sub1" style="visibility: hidden">Hidden link</a>',
+ ' <a id="item1" class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- const keydown = createEvent('keydown')
- keydown.key = 'ArrowDown'
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowDown'
- triggerDropdown.dispatchEvent(keydown)
+ triggerDropdown.dispatchEvent(keydown)
- expect(document.activeElement).not.toHaveClass('d-none')
- expect(document.activeElement.style.display).not.toEqual('none')
- expect(document.activeElement.style.visibility).not.toEqual('hidden')
+ expect(document.activeElement).not.toHaveClass('d-none')
+ expect(document.activeElement.style.display).not.toEqual('none')
+ expect(document.activeElement.style.visibility).not.toEqual('hidden')
- done()
- })
+ resolve()
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should focus next/previous element when using keyboard navigation', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a id="item1" class="dropdown-item" href="#">A link</a>',
- ' <a id="item2" class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should focus next/previous element when using keyboard navigation', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a id="item1" class="dropdown-item" href="#">A link</a>',
+ ' <a id="item2" class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const item1 = fixtureEl.querySelector('#item1')
- const item2 = fixtureEl.querySelector('#item2')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const item1 = fixtureEl.querySelector('#item1')
+ const item2 = fixtureEl.querySelector('#item2')
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- const keydownArrowDown = createEvent('keydown')
- keydownArrowDown.key = 'ArrowDown'
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ const keydownArrowDown = createEvent('keydown')
+ keydownArrowDown.key = 'ArrowDown'
- triggerDropdown.dispatchEvent(keydownArrowDown)
- expect(document.activeElement).toEqual(item1, 'item1 is focused')
+ triggerDropdown.dispatchEvent(keydownArrowDown)
+ expect(document.activeElement).toEqual(item1, 'item1 is focused')
- document.activeElement.dispatchEvent(keydownArrowDown)
- expect(document.activeElement).toEqual(item2, 'item2 is focused')
+ document.activeElement.dispatchEvent(keydownArrowDown)
+ expect(document.activeElement).toEqual(item2, 'item2 is focused')
- const keydownArrowUp = createEvent('keydown')
- keydownArrowUp.key = 'ArrowUp'
+ const keydownArrowUp = createEvent('keydown')
+ keydownArrowUp.key = 'ArrowUp'
- document.activeElement.dispatchEvent(keydownArrowUp)
- expect(document.activeElement).toEqual(item1, 'item1 is focused')
+ document.activeElement.dispatchEvent(keydownArrowUp)
+ expect(document.activeElement).toEqual(item1, 'item1 is focused')
- done()
- })
+ resolve()
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should open the dropdown and focus on the last item when using ArrowUp for the first time', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a id="item1" class="dropdown-item" href="#">A link</a>',
- ' <a id="item2" class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should open the dropdown and focus on the last item when using ArrowUp for the first time', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a id="item1" class="dropdown-item" href="#">A link</a>',
+ ' <a id="item2" class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const lastItem = fixtureEl.querySelector('#item2')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const lastItem = fixtureEl.querySelector('#item2')
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- setTimeout(() => {
- expect(document.activeElement).toEqual(lastItem, 'item2 is focused')
- done()
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ setTimeout(() => {
+ expect(document.activeElement).toEqual(lastItem, 'item2 is focused')
+ resolve()
+ })
})
- })
- const keydown = createEvent('keydown')
- keydown.key = 'ArrowUp'
- triggerDropdown.dispatchEvent(keydown)
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowUp'
+ triggerDropdown.dispatchEvent(keydown)
+ })
})
- it('should open the dropdown and focus on the first item when using ArrowDown for the first time', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a id="item1" class="dropdown-item" href="#">A link</a>',
- ' <a id="item2" class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should open the dropdown and focus on the first item when using ArrowDown for the first time', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a id="item1" class="dropdown-item" href="#">A link</a>',
+ ' <a id="item2" class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const firstItem = fixtureEl.querySelector('#item1')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const firstItem = fixtureEl.querySelector('#item1')
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- setTimeout(() => {
- expect(document.activeElement).toEqual(firstItem, 'item1 is focused')
- done()
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ setTimeout(() => {
+ expect(document.activeElement).toEqual(firstItem, 'item1 is focused')
+ resolve()
+ })
})
- })
- const keydown = createEvent('keydown')
- keydown.key = 'ArrowDown'
- triggerDropdown.dispatchEvent(keydown)
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowDown'
+ triggerDropdown.dispatchEvent(keydown)
+ })
})
- it('should not close the dropdown if the user clicks on a text field within dropdown-menu', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <input type="text">',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not close the dropdown if the user clicks on a text field within dropdown-menu', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <input type="text">',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const input = fixtureEl.querySelector('input')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const input = fixtureEl.querySelector('input')
- input.addEventListener('click', () => {
- expect(triggerDropdown).toHaveClass('show')
- done()
- })
+ input.addEventListener('click', () => {
+ expect(triggerDropdown).toHaveClass('show')
+ resolve()
+ })
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(triggerDropdown).toHaveClass('show')
- input.dispatchEvent(createEvent('click'))
- })
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(triggerDropdown).toHaveClass('show')
+ input.dispatchEvent(createEvent('click'))
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should not close the dropdown if the user clicks on a textarea within dropdown-menu', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <textarea></textarea>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not close the dropdown if the user clicks on a textarea within dropdown-menu', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <textarea></textarea>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const textarea = fixtureEl.querySelector('textarea')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const textarea = fixtureEl.querySelector('textarea')
- textarea.addEventListener('click', () => {
- expect(triggerDropdown).toHaveClass('show')
- done()
- })
+ textarea.addEventListener('click', () => {
+ expect(triggerDropdown).toHaveClass('show')
+ resolve()
+ })
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- expect(triggerDropdown).toHaveClass('show')
- textarea.dispatchEvent(createEvent('click'))
- })
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ expect(triggerDropdown).toHaveClass('show')
+ textarea.dispatchEvent(createEvent('click'))
+ })
- triggerDropdown.click()
+ triggerDropdown.click()
+ })
})
- it('should close the dropdown if the user clicks on a text field that is not contained within dropdown-menu', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' </div>',
- '</div>',
- '<input type="text">'
- ].join('')
+ it('should close the dropdown if the user clicks on a text field that is not contained within dropdown-menu', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' </div>',
+ '</div>',
+ '<input type="text">'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const input = fixtureEl.querySelector('input')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const input = fixtureEl.querySelector('input')
- triggerDropdown.addEventListener('hidden.bs.dropdown', () => {
- expect().nothing()
- done()
- })
+ triggerDropdown.addEventListener('hidden.bs.dropdown', () => {
+ expect().nothing()
+ resolve()
+ })
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- input.dispatchEvent(createEvent('click', {
- bubbles: true
- }))
- })
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ input.dispatchEvent(createEvent('click', {
+ bubbles: true
+ }))
+ })
- triggerDropdown.click()
- })
+ triggerDropdown.click()
+ })
+ })
+
+ it('should ignore keyboard events for <input>s and <textarea>s within dropdown-menu, except for escape key', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
+ ' <input type="text">',
+ ' <textarea></textarea>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const input = fixtureEl.querySelector('input')
+ const textarea = fixtureEl.querySelector('textarea')
+
+ const test = (eventKey, elementToDispatch) => {
+ const event = createEvent('keydown')
+ event.key = eventKey
+ elementToDispatch.focus()
+ elementToDispatch.dispatchEvent(event)
+ expect(document.activeElement).toEqual(elementToDispatch, `${elementToDispatch.tagName} still focused`)
+ }
- it('should ignore keyboard events for <input>s and <textarea>s within dropdown-menu, except for escape key', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#sub1">Submenu 1</a>',
- ' <input type="text">',
- ' <textarea></textarea>',
- ' </div>',
- '</div>'
- ].join('')
+ const keydownEscape = createEvent('keydown')
+ keydownEscape.key = 'Escape'
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const input = fixtureEl.querySelector('input')
- const textarea = fixtureEl.querySelector('textarea')
-
- const test = (eventKey, elementToDispatch) => {
- const event = createEvent('keydown')
- event.key = eventKey
- elementToDispatch.focus()
- elementToDispatch.dispatchEvent(event)
- expect(document.activeElement).toEqual(elementToDispatch, `${elementToDispatch.tagName} still focused`)
- }
-
- const keydownEscape = createEvent('keydown')
- keydownEscape.key = 'Escape'
+ triggerDropdown.addEventListener('shown.bs.dropdown', () => {
+ // Key Space
+ test('Space', input)
- triggerDropdown.addEventListener('shown.bs.dropdown', () => {
- // Key Space
- test('Space', input)
+ test('Space', textarea)
- test('Space', textarea)
+ // Key ArrowUp
+ test('ArrowUp', input)
- // Key ArrowUp
- test('ArrowUp', input)
+ test('ArrowUp', textarea)
- test('ArrowUp', textarea)
+ // Key ArrowDown
+ test('ArrowDown', input)
- // Key ArrowDown
- test('ArrowDown', input)
+ test('ArrowDown', textarea)
- test('ArrowDown', textarea)
+ // Key Escape
+ input.focus()
+ input.dispatchEvent(keydownEscape)
- // Key Escape
- input.focus()
- input.dispatchEvent(keydownEscape)
+ expect(triggerDropdown).not.toHaveClass('show')
+ resolve()
+ })
- expect(triggerDropdown).not.toHaveClass('show')
- done()
+ triggerDropdown.click()
})
-
- triggerDropdown.click()
})
- it('should not open dropdown if escape key was pressed on the toggle', done => {
- fixtureEl.innerHTML = [
- '<div class="tabs">',
- ' <div class="dropdown">',
- ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Secondary link</a>',
- ' <a class="dropdown-item" href="#">Something else here</a>',
- ' <div class="divider"></div>',
- ' <a class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not open dropdown if escape key was pressed on the toggle', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="tabs">',
+ ' <div class="dropdown">',
+ ' <button disabled class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Secondary link</a>',
+ ' <a class="dropdown-item" href="#">Something else here</a>',
+ ' <div class="divider"></div>',
+ ' <a class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = new Dropdown(triggerDropdown)
- const button = fixtureEl.querySelector('button[data-bs-toggle="dropdown"]')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = new Dropdown(triggerDropdown)
+ const button = fixtureEl.querySelector('button[data-bs-toggle="dropdown"]')
- spyOn(dropdown, 'toggle')
+ spyOn(dropdown, 'toggle')
- // Key escape
- button.focus()
- // Key escape
- const keydownEscape = createEvent('keydown')
- keydownEscape.key = 'Escape'
- button.dispatchEvent(keydownEscape)
+ // Key escape
+ button.focus()
+ // Key escape
+ const keydownEscape = createEvent('keydown')
+ keydownEscape.key = 'Escape'
+ button.dispatchEvent(keydownEscape)
- setTimeout(() => {
- expect(dropdown.toggle).not.toHaveBeenCalled()
- expect(triggerDropdown).not.toHaveClass('show')
- done()
- }, 20)
- })
-
- it('should propagate escape key events if dropdown is closed', done => {
- fixtureEl.innerHTML = [
- '<div class="parent">',
- ' <div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Some Item</a>',
- ' </div>',
- ' </div>',
- '</div>'
- ].join('')
-
- const parent = fixtureEl.querySelector('.parent')
- const toggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ setTimeout(() => {
+ expect(dropdown.toggle).not.toHaveBeenCalled()
+ expect(triggerDropdown).not.toHaveClass('show')
+ resolve()
+ }, 20)
+ })
+ })
+
+ it('should propagate escape key events if dropdown is closed', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="parent">',
+ ' <div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Some Item</a>',
+ ' </div>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ const parent = fixtureEl.querySelector('.parent')
+ const toggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+
+ const parentKeyHandler = jasmine.createSpy('parentKeyHandler')
+
+ parent.addEventListener('keydown', parentKeyHandler)
+ parent.addEventListener('keyup', () => {
+ expect(parentKeyHandler).toHaveBeenCalled()
+ resolve()
+ })
- const parentKeyHandler = jasmine.createSpy('parentKeyHandler')
+ const keydownEscape = createEvent('keydown', { bubbles: true })
+ keydownEscape.key = 'Escape'
+ const keyupEscape = createEvent('keyup', { bubbles: true })
+ keyupEscape.key = 'Escape'
- parent.addEventListener('keydown', parentKeyHandler)
- parent.addEventListener('keyup', () => {
- expect(parentKeyHandler).toHaveBeenCalled()
- done()
+ toggle.focus()
+ toggle.dispatchEvent(keydownEscape)
+ toggle.dispatchEvent(keyupEscape)
})
-
- const keydownEscape = createEvent('keydown', { bubbles: true })
- keydownEscape.key = 'Escape'
- const keyupEscape = createEvent('keyup', { bubbles: true })
- keyupEscape.key = 'Escape'
-
- toggle.focus()
- toggle.dispatchEvent(keydownEscape)
- toggle.dispatchEvent(keyupEscape)
})
- it('should close dropdown using `escape` button, and return focus to its trigger', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Some Item</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should close dropdown using `escape` button, and return focus to its trigger', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Some Item</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const toggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const toggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- toggle.addEventListener('shown.bs.dropdown', () => {
- const keydownEvent = createEvent('keydown', { bubbles: true })
- keydownEvent.key = 'ArrowDown'
- toggle.dispatchEvent(keydownEvent)
- keydownEvent.key = 'Escape'
- toggle.dispatchEvent(keydownEvent)
- })
+ toggle.addEventListener('shown.bs.dropdown', () => {
+ const keydownEvent = createEvent('keydown', { bubbles: true })
+ keydownEvent.key = 'ArrowDown'
+ toggle.dispatchEvent(keydownEvent)
+ keydownEvent.key = 'Escape'
+ toggle.dispatchEvent(keydownEvent)
+ })
- toggle.addEventListener('hidden.bs.dropdown', () => setTimeout(() => {
- expect(document.activeElement).toEqual(toggle)
- done()
- }))
+ toggle.addEventListener('hidden.bs.dropdown', () => setTimeout(() => {
+ expect(document.activeElement).toEqual(toggle)
+ resolve()
+ }))
- toggle.click()
+ toggle.click()
+ })
})
- it('should close dropdown (only) by clicking inside the dropdown menu when it has data-attribute `data-bs-auto-close="inside"`', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="inside">Dropdown toggle</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Dropdown item</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should close dropdown (only) by clicking inside the dropdown menu when it has data-attribute `data-bs-auto-close="inside"`', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="inside">Dropdown toggle</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Dropdown item</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const dropdownToggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdownToggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const expectDropdownToBeOpened = () => setTimeout(() => {
- expect(dropdownToggle).toHaveClass('show')
- dropdownMenu.click()
- }, 150)
+ const expectDropdownToBeOpened = () => setTimeout(() => {
+ expect(dropdownToggle).toHaveClass('show')
+ dropdownMenu.click()
+ }, 150)
- dropdownToggle.addEventListener('shown.bs.dropdown', () => {
- document.documentElement.click()
- expectDropdownToBeOpened()
- })
+ dropdownToggle.addEventListener('shown.bs.dropdown', () => {
+ document.documentElement.click()
+ expectDropdownToBeOpened()
+ })
- dropdownToggle.addEventListener('hidden.bs.dropdown', () => setTimeout(() => {
- expect(dropdownToggle).not.toHaveClass('show')
- done()
- }))
+ dropdownToggle.addEventListener('hidden.bs.dropdown', () => setTimeout(() => {
+ expect(dropdownToggle).not.toHaveClass('show')
+ resolve()
+ }))
- dropdownToggle.click()
+ dropdownToggle.click()
+ })
})
- it('should close dropdown (only) by clicking outside the dropdown menu when it has data-attribute `data-bs-auto-close="outside"`', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside">Dropdown toggle</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Dropdown item</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should close dropdown (only) by clicking outside the dropdown menu when it has data-attribute `data-bs-auto-close="outside"`', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside">Dropdown toggle</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Dropdown item</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const dropdownToggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdownToggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const expectDropdownToBeOpened = () => setTimeout(() => {
- expect(dropdownToggle).toHaveClass('show')
- document.documentElement.click()
- }, 150)
+ const expectDropdownToBeOpened = () => setTimeout(() => {
+ expect(dropdownToggle).toHaveClass('show')
+ document.documentElement.click()
+ }, 150)
- dropdownToggle.addEventListener('shown.bs.dropdown', () => {
- dropdownMenu.click()
- expectDropdownToBeOpened()
- })
+ dropdownToggle.addEventListener('shown.bs.dropdown', () => {
+ dropdownMenu.click()
+ expectDropdownToBeOpened()
+ })
- dropdownToggle.addEventListener('hidden.bs.dropdown', () => {
- expect(dropdownToggle).not.toHaveClass('show')
- done()
- })
+ dropdownToggle.addEventListener('hidden.bs.dropdown', () => {
+ expect(dropdownToggle).not.toHaveClass('show')
+ resolve()
+ })
- dropdownToggle.click()
+ dropdownToggle.click()
+ })
})
- it('should not close dropdown by clicking inside or outside the dropdown menu when it has data-attribute `data-bs-auto-close="false"`', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="false">Dropdown toggle</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#">Dropdown item</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should not close dropdown by clicking inside or outside the dropdown menu when it has data-attribute `data-bs-auto-close="false"`', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="false">Dropdown toggle</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#">Dropdown item</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const dropdownToggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
+ const dropdownToggle = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdownMenu = fixtureEl.querySelector('.dropdown-menu')
- const expectDropdownToBeOpened = (shouldTriggerClick = true) => setTimeout(() => {
- expect(dropdownToggle).toHaveClass('show')
- if (shouldTriggerClick) {
- document.documentElement.click()
- } else {
- done()
- }
+ const expectDropdownToBeOpened = (shouldTriggerClick = true) => setTimeout(() => {
+ expect(dropdownToggle).toHaveClass('show')
+ if (shouldTriggerClick) {
+ document.documentElement.click()
+ } else {
+ resolve()
+ }
- expectDropdownToBeOpened(false)
- }, 150)
+ expectDropdownToBeOpened(false)
+ }, 150)
- dropdownToggle.addEventListener('shown.bs.dropdown', () => {
- dropdownMenu.click()
- expectDropdownToBeOpened()
- })
+ dropdownToggle.addEventListener('shown.bs.dropdown', () => {
+ dropdownMenu.click()
+ expectDropdownToBeOpened()
+ })
- dropdownToggle.click()
+ dropdownToggle.click()
+ })
})
})
@@ -2030,52 +2142,54 @@ describe('Dropdown', () => {
})
})
- it('should open dropdown when pressing keydown or keyup', done => {
- fixtureEl.innerHTML = [
- '<div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item disabled" href="#sub1">Submenu 1</a>',
- ' <button class="dropdown-item" type="button" disabled>Disabled button</button>',
- ' <a id="item1" class="dropdown-item" href="#">Another link</a>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should open dropdown when pressing keydown or keyup', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown">Dropdown</button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item disabled" href="#sub1">Submenu 1</a>',
+ ' <button class="dropdown-item" type="button" disabled>Disabled button</button>',
+ ' <a id="item1" class="dropdown-item" href="#">Another link</a>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const dropdown = fixtureEl.querySelector('.dropdown')
+ const triggerDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const dropdown = fixtureEl.querySelector('.dropdown')
- const keydown = createEvent('keydown')
- keydown.key = 'ArrowDown'
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowDown'
- const keyup = createEvent('keyup')
- keyup.key = 'ArrowUp'
+ const keyup = createEvent('keyup')
+ keyup.key = 'ArrowUp'
- const handleArrowDown = () => {
- expect(triggerDropdown).toHaveClass('show')
- expect(triggerDropdown.getAttribute('aria-expanded')).toEqual('true')
- setTimeout(() => {
- dropdown.hide()
- keydown.key = 'ArrowUp'
- triggerDropdown.dispatchEvent(keyup)
- }, 20)
- }
-
- const handleArrowUp = () => {
- expect(triggerDropdown).toHaveClass('show')
- expect(triggerDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- }
-
- dropdown.addEventListener('shown.bs.dropdown', event => {
- if (event.target.key === 'ArrowDown') {
- handleArrowDown()
- } else {
- handleArrowUp()
+ const handleArrowDown = () => {
+ expect(triggerDropdown).toHaveClass('show')
+ expect(triggerDropdown.getAttribute('aria-expanded')).toEqual('true')
+ setTimeout(() => {
+ dropdown.hide()
+ keydown.key = 'ArrowUp'
+ triggerDropdown.dispatchEvent(keyup)
+ }, 20)
}
- })
- triggerDropdown.dispatchEvent(keydown)
+ const handleArrowUp = () => {
+ expect(triggerDropdown).toHaveClass('show')
+ expect(triggerDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ }
+
+ dropdown.addEventListener('shown.bs.dropdown', event => {
+ if (event.target.key === 'ArrowDown') {
+ handleArrowDown()
+ } else {
+ handleArrowUp()
+ }
+ })
+
+ triggerDropdown.dispatchEvent(keydown)
+ })
})
it('should allow `data-bs-toggle="dropdown"` click events to bubble up', () => {
@@ -2101,27 +2215,29 @@ describe('Dropdown', () => {
expect(delegatedClickListener).toHaveBeenCalled()
})
- it('should open the dropdown when clicking the child element inside `data-bs-toggle="dropdown"`', done => {
- fixtureEl.innerHTML = [
- '<div class="container">',
- ' <div class="dropdown">',
- ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown"><span id="childElement">Dropdown</span></button>',
- ' <div class="dropdown-menu">',
- ' <a class="dropdown-item" href="#subMenu">Sub menu</a>',
- ' </div>',
- ' </div>',
- '</div>'
- ].join('')
+ it('should open the dropdown when clicking the child element inside `data-bs-toggle="dropdown"`', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<div class="container">',
+ ' <div class="dropdown">',
+ ' <button class="btn dropdown-toggle" data-bs-toggle="dropdown"><span id="childElement">Dropdown</span></button>',
+ ' <div class="dropdown-menu">',
+ ' <a class="dropdown-item" href="#subMenu">Sub menu</a>',
+ ' </div>',
+ ' </div>',
+ '</div>'
+ ].join('')
- const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
- const childElement = fixtureEl.querySelector('#childElement')
+ const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
+ const childElement = fixtureEl.querySelector('#childElement')
- btnDropdown.addEventListener('shown.bs.dropdown', () => setTimeout(() => {
- expect(btnDropdown).toHaveClass('show')
- expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
- done()
- }))
+ btnDropdown.addEventListener('shown.bs.dropdown', () => setTimeout(() => {
+ expect(btnDropdown).toHaveClass('show')
+ expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
+ resolve()
+ }))
- childElement.click()
+ childElement.click()
+ })
})
})