aboutsummaryrefslogtreecommitdiff
path: root/js/tests/unit/util/focustrap.spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/tests/unit/util/focustrap.spec.js')
-rw-r--r--js/tests/unit/util/focustrap.spec.js266
1 files changed, 137 insertions, 129 deletions
diff --git a/js/tests/unit/util/focustrap.spec.js b/js/tests/unit/util/focustrap.spec.js
index 99bc95fca..0a20017d5 100644
--- a/js/tests/unit/util/focustrap.spec.js
+++ b/js/tests/unit/util/focustrap.spec.js
@@ -1,7 +1,7 @@
-import FocusTrap from '../../../src/util/focustrap'
-import EventHandler from '../../../src/dom/event-handler'
-import SelectorEngine from '../../../src/dom/selector-engine'
-import { clearFixture, getFixture, createEvent } from '../../helpers/fixture'
+import EventHandler from '../../../src/dom/event-handler.js'
+import SelectorEngine from '../../../src/dom/selector-engine.js'
+import FocusTrap from '../../../src/util/focustrap.js'
+import { clearFixture, createEvent, getFixture } from '../../helpers/fixture.js'
describe('FocusTrap', () => {
let fixtureEl
@@ -20,12 +20,12 @@ describe('FocusTrap', () => {
const trapElement = fixtureEl.querySelector('div')
- spyOn(trapElement, 'focus')
+ const spy = spyOn(trapElement, 'focus')
const focustrap = new FocusTrap({ trapElement })
focustrap.activate()
- expect(trapElement.focus).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalled()
})
it('if configured not to autofocus, should not autofocus itself', () => {
@@ -33,148 +33,156 @@ describe('FocusTrap', () => {
const trapElement = fixtureEl.querySelector('div')
- spyOn(trapElement, 'focus')
+ const spy = spyOn(trapElement, 'focus')
const focustrap = new FocusTrap({ trapElement, autofocus: false })
focustrap.activate()
- expect(trapElement.focus).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
- it('should force focus inside focus trap if it can', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1">',
- ' <a href="#" id="inside">inside</a>',
- '</div>'
- ].join('')
+ it('should force focus inside focus trap if it can', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1">',
+ ' <a href="#" id="inside">inside</a>',
+ '</div>'
+ ].join('')
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
- const inside = document.getElementById('inside')
+ const inside = document.getElementById('inside')
- const focusInListener = () => {
- expect(inside.focus).toHaveBeenCalled()
- document.removeEventListener('focusin', focusInListener)
- done()
- }
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ document.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
- spyOn(inside, 'focus')
- spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [inside])
+ const spy = spyOn(inside, 'focus')
+ spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [inside])
- document.addEventListener('focusin', focusInListener)
+ document.addEventListener('focusin', focusInListener)
- const focusInEvent = createEvent('focusin', { bubbles: true })
- Object.defineProperty(focusInEvent, 'target', {
- value: document.getElementById('outside')
- })
+ const focusInEvent = createEvent('focusin', { bubbles: true })
+ Object.defineProperty(focusInEvent, 'target', {
+ value: document.getElementById('outside')
+ })
- document.dispatchEvent(focusInEvent)
+ document.dispatchEvent(focusInEvent)
+ })
})
- it('should wrap focus around forward on tab', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1">',
- ' <a href="#" id="first">first</a>',
- ' <a href="#" id="inside">inside</a>',
- ' <a href="#" id="last">last</a>',
- '</div>'
- ].join('')
-
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
-
- const first = document.getElementById('first')
- const inside = document.getElementById('inside')
- const last = document.getElementById('last')
- const outside = document.getElementById('outside')
-
- spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
- spyOn(first, 'focus').and.callThrough()
-
- const focusInListener = () => {
- expect(first.focus).toHaveBeenCalled()
- first.removeEventListener('focusin', focusInListener)
- done()
- }
-
- first.addEventListener('focusin', focusInListener)
-
- const keydown = createEvent('keydown')
- keydown.key = 'Tab'
-
- document.dispatchEvent(keydown)
- outside.focus()
+ it('should wrap focus around forward on tab', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1">',
+ ' <a href="#" id="first">first</a>',
+ ' <a href="#" id="inside">inside</a>',
+ ' <a href="#" id="last">last</a>',
+ '</div>'
+ ].join('')
+
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
+
+ const first = document.getElementById('first')
+ const inside = document.getElementById('inside')
+ const last = document.getElementById('last')
+ const outside = document.getElementById('outside')
+
+ spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
+ const spy = spyOn(first, 'focus').and.callThrough()
+
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ first.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
+
+ first.addEventListener('focusin', focusInListener)
+
+ const keydown = createEvent('keydown')
+ keydown.key = 'Tab'
+
+ document.dispatchEvent(keydown)
+ outside.focus()
+ })
})
- it('should wrap focus around backwards on shift-tab', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1">',
- ' <a href="#" id="first">first</a>',
- ' <a href="#" id="inside">inside</a>',
- ' <a href="#" id="last">last</a>',
- '</div>'
- ].join('')
-
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
-
- const first = document.getElementById('first')
- const inside = document.getElementById('inside')
- const last = document.getElementById('last')
- const outside = document.getElementById('outside')
-
- spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
- spyOn(last, 'focus').and.callThrough()
-
- const focusInListener = () => {
- expect(last.focus).toHaveBeenCalled()
- last.removeEventListener('focusin', focusInListener)
- done()
- }
-
- last.addEventListener('focusin', focusInListener)
-
- const keydown = createEvent('keydown')
- keydown.key = 'Tab'
- keydown.shiftKey = true
-
- document.dispatchEvent(keydown)
- outside.focus()
+ it('should wrap focus around backwards on shift-tab', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1">',
+ ' <a href="#" id="first">first</a>',
+ ' <a href="#" id="inside">inside</a>',
+ ' <a href="#" id="last">last</a>',
+ '</div>'
+ ].join('')
+
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
+
+ const first = document.getElementById('first')
+ const inside = document.getElementById('inside')
+ const last = document.getElementById('last')
+ const outside = document.getElementById('outside')
+
+ spyOn(SelectorEngine, 'focusableChildren').and.callFake(() => [first, inside, last])
+ const spy = spyOn(last, 'focus').and.callThrough()
+
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ last.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
+
+ last.addEventListener('focusin', focusInListener)
+
+ const keydown = createEvent('keydown')
+ keydown.key = 'Tab'
+ keydown.shiftKey = true
+
+ document.dispatchEvent(keydown)
+ outside.focus()
+ })
})
- it('should force focus on itself if there is no focusable content', done => {
- fixtureEl.innerHTML = [
- '<a href="#" id="outside">outside</a>',
- '<div id="focustrap" tabindex="-1"></div>'
- ].join('')
+ it('should force focus on itself if there is no focusable content', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = [
+ '<a href="#" id="outside">outside</a>',
+ '<div id="focustrap" tabindex="-1"></div>'
+ ].join('')
- const trapElement = fixtureEl.querySelector('div')
- const focustrap = new FocusTrap({ trapElement })
- focustrap.activate()
+ const trapElement = fixtureEl.querySelector('div')
+ const focustrap = new FocusTrap({ trapElement })
+ focustrap.activate()
- const focusInListener = () => {
- expect(focustrap._config.trapElement.focus).toHaveBeenCalled()
- document.removeEventListener('focusin', focusInListener)
- done()
- }
+ const focusInListener = () => {
+ expect(spy).toHaveBeenCalled()
+ document.removeEventListener('focusin', focusInListener)
+ resolve()
+ }
- spyOn(focustrap._config.trapElement, 'focus')
+ const spy = spyOn(focustrap._config.trapElement, 'focus')
- document.addEventListener('focusin', focusInListener)
+ document.addEventListener('focusin', focusInListener)
- const focusInEvent = createEvent('focusin', { bubbles: true })
- Object.defineProperty(focusInEvent, 'target', {
- value: document.getElementById('outside')
- })
+ const focusInEvent = createEvent('focusin', { bubbles: true })
+ Object.defineProperty(focusInEvent, 'target', {
+ value: document.getElementById('outside')
+ })
- document.dispatchEvent(focusInEvent)
+ document.dispatchEvent(focusInEvent)
+ })
})
})
@@ -182,29 +190,29 @@ describe('FocusTrap', () => {
it('should flag itself as no longer active', () => {
const focustrap = new FocusTrap({ trapElement: fixtureEl })
focustrap.activate()
- expect(focustrap._isActive).toBe(true)
+ expect(focustrap._isActive).toBeTrue()
focustrap.deactivate()
- expect(focustrap._isActive).toBe(false)
+ expect(focustrap._isActive).toBeFalse()
})
it('should remove all event listeners', () => {
const focustrap = new FocusTrap({ trapElement: fixtureEl })
focustrap.activate()
- spyOn(EventHandler, 'off')
+ const spy = spyOn(EventHandler, 'off')
focustrap.deactivate()
- expect(EventHandler.off).toHaveBeenCalled()
+ expect(spy).toHaveBeenCalled()
})
it('doesn\'t try removing event listeners unless it needs to (in case it hasn\'t been activated)', () => {
const focustrap = new FocusTrap({ trapElement: fixtureEl })
- spyOn(EventHandler, 'off')
+ const spy = spyOn(EventHandler, 'off')
focustrap.deactivate()
- expect(EventHandler.off).not.toHaveBeenCalled()
+ expect(spy).not.toHaveBeenCalled()
})
})
})