diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index e54b788aa..695b0ea90 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -505,7 +505,7 @@ $(function () {
var tabsHTML = '
' /* purposely incorrect, with all set to aria-selected="true" */
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
window.dispatchEvent(new Event('load'))
@@ -527,7 +527,7 @@ $(function () {
var tabsHTML = '' /* purposely incorrect, left out aria-selected="true" on active one */
var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
window.dispatchEvent(new Event('load'))
@@ -540,6 +540,171 @@ $(function () {
}, 10)
})
+ QUnit.test('should correctly switch tabs in response to left/right cursor keys (for horizontal/default tablist) and ignore up/down cursor keys', function (assert) {
+ assert.expect(27)
+ var done = assert.async()
+
+ var tabsHTML = '' +
+ '...
' +
+ '...
' +
+ '...
'
+ var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
+
+ var $firstTab = $tabs.find('li:first-child a')
+ var $secondTab = $tabs.find('li:nth-child(2) a')
+ var $thirdTab = $tabs.find('li:nth-child(3) a')
+ $firstTab[0].focus() /* set focus to first tab */
+ assert.ok(document.activeElement === $firstTab[0], 'first tab successfully focused')
+ /* right cursor key */
+ var keyDown = new Event('keydown')
+ keyDown.which = 39
+ $firstTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $firstTab[0], 'after 1st right cursor key, first tab not focused anymore')
+ assert.ok(!$firstTab.hasClass('active'), 'after 1st right cursor key, first tab not `.active` anymore')
+ assert.ok($firstTab.attr('aria-selected') === 'false', 'after 1st right cursor key, first tab has aria-selected="false"')
+ assert.ok($firstTab.attr('tabindex') === '-1', 'after 1st right cursor key, first tab has tabindex="-1"')
+ assert.ok(document.activeElement === $secondTab[0], 'after 1st right cursor key, second tab is focused')
+ assert.ok($secondTab.hasClass('active'), 'after 1st right cursor key, second tab is `.active`')
+ assert.ok($secondTab.attr('aria-selected') === 'true', 'after 1st right cursor key, second tab has aria-selected="true"')
+ assert.ok($secondTab.attr('tabindex') === '0', 'after 1st right cursor key, second tab has tabindex="0"')
+ /* right cursor key */
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $secondTab[0], 'after 2nd right cursor key, second tab not focused anymore')
+ assert.ok(!$secondTab.hasClass('active'), 'after 2nd right cursor key, second tab not `.active` anymore')
+ assert.ok($secondTab.attr('aria-selected') === 'false', 'after 2nd right cursor key, second tab has aria-selected="false"')
+ assert.ok($secondTab.attr('tabindex') === '-1', 'after 2nd right cursor key, second tab has tabindex="-1"')
+ assert.ok(document.activeElement === $thirdTab[0], 'after 2nd right cursor key, third tab is focused')
+ assert.ok($thirdTab.hasClass('active'), 'after 2nd right cursor key, third tab is `.active`')
+ assert.ok($thirdTab.attr('aria-selected') === 'true', 'after 2nd right cursor key, third tab has aria-selected="true"')
+ assert.ok($thirdTab.attr('tabindex') === '0', 'after 2nd right cursor key, third tab has tabindex="0"')
+ /* left cursor key */
+ keyDown.which = 37
+ $thirdTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $thirdTab[0], 'after left cursor key, third tab not focused anymore')
+ assert.ok(!$thirdTab.hasClass('active'), 'after left cursor key, third tab not `.active` anymore')
+ assert.ok($thirdTab.attr('aria-selected') === 'false', 'after left cursor key, third tab has aria-selected="false"')
+ assert.ok($thirdTab.attr('tabindex') === '-1', 'after left cursor key, third tab has tabindex="-1"')
+ assert.ok(document.activeElement === $secondTab[0], 'after left cursor key, second tab is focused')
+ assert.ok($secondTab.hasClass('active'), 'after left cursor key, second tab is `.active`')
+ assert.ok($secondTab.attr('aria-selected') === 'true', 'after left cursor key, second tab has aria-selected="true"')
+ assert.ok($secondTab.attr('tabindex') === '0', 'after left cursor key, second tab has tabindex="0"')
+ /* up cursor key */
+ keyDown.which = 38
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement === $secondTab[0], 'after up cursor key, second tab is still focused - no change')
+ /* down cursor key */
+ keyDown.which = 40
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement === $secondTab[0], 'after down cursor key, second tab is still focused - no change')
+ done()
+ })
+
+ QUnit.test('should correctly switch tabs in response to up/down cursor keys for vertical tablist and ignore left/right cursor keys', function (assert) {
+ assert.expect(27)
+ var done = assert.async()
+
+ var tabsHTML = '' +
+ '...
' +
+ '...
' +
+ '...
'
+ var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
+
+ var $firstTab = $tabs.find('li:first-child a')
+ var $secondTab = $tabs.find('li:nth-child(2) a')
+ var $thirdTab = $tabs.find('li:nth-child(3) a')
+ $firstTab[0].focus() /* set focus to first tab */
+ assert.ok(document.activeElement === $firstTab[0], 'first tab successfully focused')
+ /* down cursor key */
+ var keyDown = new Event('keydown')
+ keyDown.which = 40
+ $firstTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $firstTab[0], 'after 1st down cursor key, first tab not focused anymore')
+ assert.ok(!$firstTab.hasClass('active'), 'after 1st down cursor key, first tab not `.active` anymore')
+ assert.ok($firstTab.attr('aria-selected') === 'false', 'after 1st down cursor key, first tab has aria-selected="false"')
+ assert.ok($firstTab.attr('tabindex') === '-1', 'after 1st down cursor key, first tab has tabindex="-1"')
+ assert.ok(document.activeElement === $secondTab[0], 'after 1st down cursor key, second tab is focused')
+ assert.ok($secondTab.hasClass('active'), 'after 1st down cursor key, second tab is `.active`')
+ assert.ok($secondTab.attr('aria-selected') === 'true', 'after 1st down cursor key, second tab has aria-selected="true"')
+ assert.ok($secondTab.attr('tabindex') === '0', 'after 1st down cursor key, second tab has tabindex="0"')
+ /* down cursor key */
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $secondTab[0], 'after 2nd down cursor key, second tab not focused anymore')
+ assert.ok(!$secondTab.hasClass('active'), 'after 2nd down cursor key, second tab not `.active` anymore')
+ assert.ok($secondTab.attr('aria-selected') === 'false', 'after 2nd down cursor key, second tab has aria-selected="false"')
+ assert.ok($secondTab.attr('tabindex') === '-1', 'after 2nd down cursor key, second tab has tabindex="-1"')
+ assert.ok(document.activeElement === $thirdTab[0], 'after 2nd down cursor key, third tab is focused')
+ assert.ok($thirdTab.hasClass('active'), 'after 2nd down cursor key, third tab is `.active`')
+ assert.ok($thirdTab.attr('aria-selected') === 'true', 'after 2nd down cursor key, third tab has aria-selected="true"')
+ assert.ok($thirdTab.attr('tabindex') === '0', 'after 2nd down cursor key, third tab has tabindex="0"')
+ /* up cursor key */
+ keyDown.which = 38
+ $thirdTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $thirdTab[0], 'after up cursor key, third tab not focused anymore')
+ assert.ok(!$thirdTab.hasClass('active'), 'after up cursor key, third tab not `.active` anymore')
+ assert.ok($thirdTab.attr('aria-selected') === 'false', 'after up cursor key, third tab has aria-selected="false"')
+ assert.ok($thirdTab.attr('tabindex') === '-1', 'after up cursor key, third tab has tabindex="-1"')
+ assert.ok(document.activeElement === $secondTab[0], 'after up cursor key, second tab is focused')
+ assert.ok($secondTab.hasClass('active'), 'after up cursor key, second tab is `.active`')
+ assert.ok($secondTab.attr('aria-selected') === 'true', 'after up cursor key, second tab has aria-selected="true"')
+ assert.ok($secondTab.attr('tabindex') === '0', 'after up cursor key, second tab has tabindex="0"')
+ /* left cursor key */
+ keyDown.which = 37
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement === $secondTab[0], 'after left cursor key, second tab is still focused - no change')
+ /* right cursor key */
+ keyDown.which = 39
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement === $secondTab[0], 'after right cursor key, second tab is still focused - no change')
+ done()
+ })
+
+ QUnit.test('should not switch tabs in response to cursor keys if tab panel still transitioning', function (assert) {
+ assert.expect(13)
+ var done = assert.async()
+
+ var tabsHTML = '' +
+ '...
' +
+ '...
' +
+ '...
'
+ var $tabs = $(tabsHTML).appendTo('#qunit-fixture')
+
+ var $firstTab = $tabs.find('li:first-child a')
+ var $secondTab = $tabs.find('li:nth-child(2) a')
+ $firstTab[0].focus() /* set focus to first tab */
+ assert.ok(document.activeElement === $firstTab[0], 'first tab successfully focused')
+ /* right cursor key */
+ var keyDown = new Event('keydown')
+ keyDown.which = 39
+ $firstTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement !== $firstTab[0], 'after 1st right cursor key, first tab not focused anymore')
+ assert.ok(!$firstTab.hasClass('active'), 'after 1st right cursor key, first tab not `.active` anymore')
+ assert.ok($firstTab.attr('aria-selected') === 'false', 'after 1st right cursor key, first tab has aria-selected="false"')
+ assert.ok($firstTab.attr('tabindex') === '-1', 'after 1st right cursor key, first tab has tabindex="-1"')
+ assert.ok(document.activeElement === $secondTab[0], 'after 1st right cursor key, second tab is focused')
+ assert.ok($secondTab.hasClass('active'), 'after 1st right cursor key, second tab is `.active`')
+ assert.ok($secondTab.attr('aria-selected') === 'true', 'after 1st right cursor key, second tab has aria-selected="true"')
+ assert.ok($secondTab.attr('tabindex') === '0', 'after 1st right cursor key, second tab has tabindex="0"')
+ /* right cursor key - as this is fired so quickly, the tab panel is still transitioning */
+ $secondTab[0].dispatchEvent(keyDown)
+ assert.ok(document.activeElement === $secondTab[0], 'after 2nd right cursor key, while tab panel still transitioning, second tab is still focused')
+ assert.ok($secondTab.hasClass('active'), 'after 2nd right cursor key, while tab panel still transitioning, second tab is still `.active`')
+ assert.ok($secondTab.attr('aria-selected') === 'true', 'after 2nd right cursor key, while tab panel still transitioning, second tab still has aria-selected="true"')
+ assert.ok($secondTab.attr('tabindex') === '0', 'after 2nd right cursor key, while tab panel still transitioning, second tab still has tabindex="0"')
+ done()
+ })
+
QUnit.test('should return the version', function (assert) {
assert.expect(1)
assert.strictEqual(typeof Tab.VERSION, 'string')