aboutsummaryrefslogtreecommitdiff
path: root/js/tests/unit
diff options
context:
space:
mode:
authorMark Otto <[email protected]>2017-05-30 08:46:33 -0700
committerMark Otto <[email protected]>2017-05-30 08:46:33 -0700
commitd4eb0d4e739477fc51421eed29906addfd998a04 (patch)
tree5ffe09c63ac4e522890fc7b2b87c0a47b0f1a971 /js/tests/unit
parent0c12ccbeb6fdf0dd3818f97260aa43c79108d377 (diff)
parentf95cbc5950bf31995f33023014c47a61665ffacc (diff)
downloadbootstrap-d4eb0d4e739477fc51421eed29906addfd998a04.tar.xz
bootstrap-d4eb0d4e739477fc51421eed29906addfd998a04.zip
Merge branch 'v4-docs-streamlined' of https://github.com/twbs/bootstrap into v4-docs-streamlined
Diffstat (limited to 'js/tests/unit')
-rw-r--r--js/tests/unit/button.js35
-rw-r--r--js/tests/unit/carousel.js66
-rw-r--r--js/tests/unit/collapse.js162
-rw-r--r--js/tests/unit/dropdown.js522
-rw-r--r--js/tests/unit/modal.js135
-rw-r--r--js/tests/unit/phantom.js72
-rw-r--r--js/tests/unit/popover.js33
-rw-r--r--js/tests/unit/scrollspy.js222
-rw-r--r--js/tests/unit/tab.js32
-rw-r--r--js/tests/unit/tooltip.js163
10 files changed, 934 insertions, 508 deletions
diff --git a/js/tests/unit/button.js b/js/tests/unit/button.js
index c67cea345..489d400a6 100644
--- a/js/tests/unit/button.js
+++ b/js/tests/unit/button.js
@@ -138,4 +138,39 @@ $(function () {
assert.ok($btn2.find('input').prop('checked'), 'btn2 is checked')
})
+ QUnit.test('should not add aria-pressed on labels for radio/checkbox inputs in a data-toggle="buttons" group', function (assert) {
+ assert.expect(2)
+ var groupHTML = '<div class="btn-group" data-toggle="buttons">'
+ + '<label class="btn btn-primary"><input type="checkbox" autocomplete="off"> Checkbox</label>'
+ + '<label class="btn btn-primary"><input type="radio" name="options" autocomplete="off"> Radio</label>'
+ + '</div>'
+ var $group = $(groupHTML).appendTo('#qunit-fixture')
+
+ var $btn1 = $group.children().eq(0)
+ var $btn2 = $group.children().eq(1)
+
+ $btn1.find('input').trigger('click')
+ assert.ok($btn1.is(':not([aria-pressed])'), 'label for nested checkbox input has not been given an aria-pressed attribute')
+
+ $btn2.find('input').trigger('click')
+ assert.ok($btn2.is(':not([aria-pressed])'), 'label for nested radio input has not been given an aria-pressed attribute')
+ })
+
+ QUnit.test('should handle disabled attribute on non-button elements', function (assert) {
+ assert.expect(2)
+ var groupHTML = ' <div class="btn-group disabled" data-toggle="buttons" aria-disabled="true" disabled>'
+ + '<label class="btn btn-danger disabled" aria-disabled="true" disabled>'
+ + '<input type="checkbox" aria-disabled="true" autocomplete="off" disabled class="disabled"/>'
+ + '</label>'
+ + '</div>'
+ var $group = $(groupHTML).appendTo('#qunit-fixture')
+
+ var $btn = $group.children().eq(0)
+ var $input = $btn.children().eq(0)
+
+ $btn.trigger('click')
+ assert.ok($btn.is(':not(.active)'), 'button did not become active')
+ assert.ok(!$input.is(':checked'), 'checkbox did not get checked')
+ })
+
})
diff --git a/js/tests/unit/carousel.js b/js/tests/unit/carousel.js
index dbdea921a..894f78ab5 100644
--- a/js/tests/unit/carousel.js
+++ b/js/tests/unit/carousel.js
@@ -341,6 +341,49 @@ $(function () {
.bootstrapCarousel('next')
})
+ QUnit.test('should fire slid and slide events with from and to', function (assert) {
+ assert.expect(4)
+ var template = '<div id="myCarousel" class="carousel slide">'
+ + '<div class="carousel-inner">'
+ + '<div class="carousel-item active">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>First Thumbnail label</h4>'
+ + '</div>'
+ + '</div>'
+ + '<div class="carousel-item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Second Thumbnail label</h4>'
+ + '</div>'
+ + '</div>'
+ + '<div class="carousel-item">'
+ + '<img alt="">'
+ + '<div class="carousel-caption">'
+ + '<h4>Third Thumbnail label</h4>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<a class="left carousel-control" href="#myCarousel" data-slide="prev">&lsaquo;</a>'
+ + '<a class="right carousel-control" href="#myCarousel" data-slide="next">&rsaquo;</a>'
+ + '</div>'
+
+ var done = assert.async()
+ $(template)
+ .on('slid.bs.carousel', function (e) {
+ assert.ok(e.from !== undefined, 'from present')
+ assert.ok(e.to !== undefined, 'to present')
+ $(this).off()
+ done()
+ })
+ .on('slide.bs.carousel', function (e) {
+ assert.ok(e.from !== undefined, 'from present')
+ assert.ok(e.to !== undefined, 'to present')
+ $(this).off('slide.bs.carousel')
+ })
+ .bootstrapCarousel('next')
+ })
+
QUnit.test('should set interval from data attribute', function (assert) {
assert.expect(4)
var templateHTML = '<div id="myCarousel" class="carousel slide">'
@@ -611,29 +654,6 @@ $(function () {
assert.strictEqual($template.find('.carousel-item')[0], $template.find('.active')[0], 'first item still active after left arrow press in <textarea>')
})
- QUnit.test('should only add mouseenter and mouseleave listeners when not on mobile', function (assert) {
- assert.expect(2)
- var isMobile = 'ontouchstart' in document.documentElement
- var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false" data-pause="hover">'
- + '<div class="carousel-inner">'
- + '<div id="first" class="carousel-item active">'
- + '<img alt="">'
- + '</div>'
- + '<div id="second" class="carousel-item">'
- + '<img alt="">'
- + '</div>'
- + '<div id="third" class="carousel-item">'
- + '<img alt="">'
- + '</div>'
- + '</div>'
- + '</div>'
- var $template = $(templateHTML).bootstrapCarousel()
-
- $.each(['mouseover', 'mouseout'], function (i, type) {
- assert.strictEqual(type in $._data($template[0], 'events'), !isMobile, 'does' + (isMobile ? ' not' : '') + ' listen for ' + type + ' events')
- })
- })
-
QUnit.test('should wrap around from end to start when wrap option is true', function (assert) {
assert.expect(3)
var carouselHTML = '<div id="carousel-example-generic" class="carousel slide" data-wrap="true">'
diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js
index 713930433..2b9d0e58f 100644
--- a/js/tests/unit/collapse.js
+++ b/js/tests/unit/collapse.js
@@ -265,17 +265,17 @@ $(function () {
+ '</div>'
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
- var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" />').appendTo($groups.eq(0))
- $('<div id="body1" class="show"/>').appendTo($groups.eq(0))
+ $('<div id="body1" class="show" data-parent="#accordion"/>').appendTo($groups.eq(0))
- var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" />').appendTo($groups.eq(1))
- $('<div id="body2"/>').appendTo($groups.eq(1))
+ $('<div id="body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
- var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" />').appendTo($groups.eq(2))
- $('<div id="body3"/>')
+ $('<div id="body3" data-parent="#accordion"/>')
.appendTo($groups.eq(2))
.on('shown.bs.collapse', function () {
assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
@@ -299,17 +299,17 @@ $(function () {
+ '</div>'
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
- var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1"/>').appendTo($groups.eq(0))
- $('<div id="body1" class="show"/>').appendTo($groups.eq(0))
+ $('<div id="body1" class="show" data-parent=".accordion"/>').appendTo($groups.eq(0))
- var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body2"/>').appendTo($groups.eq(1))
- $('<div id="body2"/>').appendTo($groups.eq(1))
+ $('<div id="body2" data-parent=".accordion"/>').appendTo($groups.eq(1))
- var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent=".accordion"/>').appendTo($groups.eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3"/>').appendTo($groups.eq(2))
- $('<div id="body3"/>')
+ $('<div id="body3" data-parent=".accordion"/>')
.appendTo($groups.eq(2))
.on('shown.bs.collapse', function () {
assert.ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
@@ -322,7 +322,7 @@ $(function () {
$target3.trigger('click')
})
- QUnit.test('should set aria-expanded="true" on target when collapse is shown', function (assert) {
+ QUnit.test('should set aria-expanded="true" on trigger/control when collapse is shown', function (assert) {
assert.expect(1)
var done = assert.async()
@@ -338,7 +338,7 @@ $(function () {
$target.trigger('click')
})
- QUnit.test('should set aria-expanded="false" on target when collapse is hidden', function (assert) {
+ QUnit.test('should set aria-expanded="false" on trigger/control when collapse is hidden', function (assert) {
assert.expect(1)
var done = assert.async()
@@ -364,8 +364,8 @@ $(function () {
$('<div id="test1"/>')
.appendTo('#qunit-fixture')
.on('shown.bs.collapse', function () {
- assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
- assert.strictEqual($alt.attr('aria-expanded'), 'true', 'aria-expanded on alt is "true"')
+ assert.strictEqual($target.attr('aria-expanded'), 'true', 'aria-expanded on trigger/control is "true"')
+ assert.strictEqual($alt.attr('aria-expanded'), 'true', 'aria-expanded on alternative trigger/control is "true"')
done()
})
@@ -382,15 +382,15 @@ $(function () {
$('<div id="test1" class="show"/>')
.appendTo('#qunit-fixture')
.on('hidden.bs.collapse', function () {
- assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
- assert.strictEqual($alt.attr('aria-expanded'), 'false', 'aria-expanded on alt is "false"')
+ assert.strictEqual($target.attr('aria-expanded'), 'false', 'aria-expanded on trigger/control is "false"')
+ assert.strictEqual($alt.attr('aria-expanded'), 'false', 'aria-expanded on alternative trigger/control is "false"')
done()
})
$target.trigger('click')
})
- QUnit.test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function (assert) {
+ QUnit.test('should change aria-expanded from active accordion trigger/control to "false" and set the trigger/control for the newly active one to "true"', function (assert) {
assert.expect(3)
var done = assert.async()
@@ -401,22 +401,22 @@ $(function () {
+ '</div>'
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
- var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" aria-expanded="true" href="#body1"/>').appendTo($groups.eq(0))
- $('<div id="body1" aria-expanded="true" class="show"/>').appendTo($groups.eq(0))
+ $('<div id="body1" class="show" data-parent="#accordion"/>').appendTo($groups.eq(0))
- var $target2 = $('<a role="button" data-toggle="collapse" href="#body2" data-parent="#accordion" class="collapsed" />').appendTo($groups.eq(1))
+ var $target2 = $('<a role="button" data-toggle="collapse" aria-expanded="false" href="#body2" class="collapsed" aria-expanded="false" />').appendTo($groups.eq(1))
- $('<div id="body2" aria-expanded="false"/>').appendTo($groups.eq(1))
+ $('<div id="body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
- var $target3 = $('<a class="collapsed" data-toggle="collapse" role="button" href="#body3" data-parent="#accordion"/>').appendTo($groups.eq(2))
+ var $target3 = $('<a class="collapsed" data-toggle="collapse" aria-expanded="false" role="button" href="#body3"/>').appendTo($groups.eq(2))
- $('<div id="body3" aria-expanded="false"/>')
+ $('<div id="body3" data-parent="#accordion"/>')
.appendTo($groups.eq(2))
.on('shown.bs.collapse', function () {
- assert.strictEqual($target1.attr('aria-expanded'), 'false', 'inactive target 1 has aria-expanded="false"')
- assert.strictEqual($target2.attr('aria-expanded'), 'false', 'inactive target 2 has aria-expanded="false"')
- assert.strictEqual($target3.attr('aria-expanded'), 'true', 'active target 3 has aria-expanded="false"')
+ assert.strictEqual($target1.attr('aria-expanded'), 'false', 'inactive trigger/control 1 has aria-expanded="false"')
+ assert.strictEqual($target2.attr('aria-expanded'), 'false', 'inactive trigger/control 2 has aria-expanded="false"')
+ assert.strictEqual($target3.attr('aria-expanded'), 'true', 'active trigger/control 3 has aria-expanded="true"')
done()
})
@@ -435,16 +435,16 @@ $(function () {
var showFired = false
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.card')
- var $target1 = $('<a role="button" data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
+ var $target1 = $('<a role="button" data-toggle="collapse" href="#body1"/>').appendTo($groups.eq(0))
- $('<div id="body1" class="collapse"/>')
+ $('<div id="body1" class="collapse" data-parent="#accordion"/>')
.appendTo($groups.eq(0))
.on('show.bs.collapse', function () {
showFired = true
})
- var $target2 = $('<a role="button" data-toggle="collapse" href="#body2" data-parent="#accordion"/>').appendTo($groups.eq(1))
- var $body2 = $('<div id="body2" class="collapse"/>').appendTo($groups.eq(1))
+ var $target2 = $('<a role="button" data-toggle="collapse" href="#body2"/>').appendTo($groups.eq(1))
+ var $body2 = $('<div id="body2" class="collapse" data-parent="#accordion"/>').appendTo($groups.eq(1))
$target2.trigger('click')
@@ -490,4 +490,102 @@ $(function () {
.bootstrapCollapse('show')
})
+ QUnit.test('should allow accordion to use children other than card', function (assert) {
+ assert.expect(4)
+ var done = assert.async()
+ var accordionHTML = '<div id="accordion">'
+ + '<div class="item">'
+ + '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>'
+ + '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree"></div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<a id="linkTriggerTwo" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ + '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>'
+ + '</div>'
+ + '</div>'
+
+ $(accordionHTML).appendTo('#qunit-fixture')
+ var $trigger = $('#linkTrigger')
+ var $triggerTwo = $('#linkTriggerTwo')
+ var $collapseOne = $('#collapseOne')
+ var $collapseTwo = $('#collapseTwo')
+ $collapseOne.on('shown.bs.collapse', function () {
+ assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
+ assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
+ $collapseTwo.on('shown.bs.collapse', function () {
+ assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
+ assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
+ done()
+ })
+ $triggerTwo.trigger($.Event('click'))
+ })
+ $trigger.trigger($.Event('click'))
+ })
+
+ QUnit.test('should collapse accordion children but not nested accordion children', function (assert) {
+ assert.expect(9)
+ var done = assert.async()
+ $('<div id="accordion">'
+ + '<div class="item">'
+ + '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>'
+ + '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree">'
+ + '<div id="nestedAccordion">'
+ + '<div class="item">'
+ + '<a id="nestedLinkTrigger" data-parent="#nestedAccordion" data-toggle="collapse" href="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>'
+ + '<div id="nestedCollapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree">'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ + '<div class="item">'
+ + '<a id="linkTriggerTwo" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ + '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>'
+ + '</div>'
+ + '</div>').appendTo('#qunit-fixture')
+ var $trigger = $('#linkTrigger')
+ var $triggerTwo = $('#linkTriggerTwo')
+ var $nestedTrigger = $('#nestedLinkTrigger')
+ var $collapseOne = $('#collapseOne')
+ var $collapseTwo = $('#collapseTwo')
+ var $nestedCollapseOne = $('#nestedCollapseOne')
+
+
+ $collapseOne.one('shown.bs.collapse', function () {
+ assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
+ assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
+ assert.ok(!$('#nestedCollapseOne').hasClass('show'), '#nestedCollapseOne is not shown')
+ $nestedCollapseOne.one('shown.bs.collapse', function () {
+ assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
+ assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
+ assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
+ $collapseTwo.one('shown.bs.collapse', function () {
+ assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
+ assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
+ assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
+ done()
+ })
+ $triggerTwo.trigger($.Event('click'))
+ })
+ $nestedTrigger.trigger($.Event('click'))
+ })
+ $trigger.trigger($.Event('click'))
+ })
+
+ QUnit.test('should not prevent event for input', function (assert) {
+ assert.expect(3)
+ var done = assert.async()
+ var $target = $('<input type="checkbox" data-toggle="collapse" data-target="#collapsediv1" />').appendTo('#qunit-fixture')
+
+ $('<div id="collapsediv1"/>')
+ .appendTo('#qunit-fixture')
+ .on('shown.bs.collapse', function () {
+ assert.ok($(this).hasClass('show'))
+ assert.ok($target.attr('aria-expanded') === 'true')
+ assert.ok($target.prop('checked'))
+ done()
+ })
+
+ $target.trigger($.Event('click'))
+ })
})
diff --git a/js/tests/unit/dropdown.js b/js/tests/unit/dropdown.js
index 9a34fc0c9..1dd675b0b 100644
--- a/js/tests/unit/dropdown.js
+++ b/js/tests/unit/dropdown.js
@@ -45,58 +45,62 @@ $(function () {
})
QUnit.test('should not open dropdown if target is disabled via attribute', function (assert) {
- assert.expect(1)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ assert.expect(0)
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
-
- assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
+ setTimeout(function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ }, 300)
})
QUnit.test('should set aria-expanded="true" on target when dropdown menu is shown', function (assert) {
assert.expect(1)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var done = assert.async()
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
- var $dropdown = $(dropdownHTML)
- .find('[data-toggle="dropdown"]')
- .bootstrapDropdown()
- .trigger('click')
-
- assert.strictEqual($dropdown.attr('aria-expanded'), 'true', 'aria-expanded is set to string "true" on click')
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.strictEqual($dropdown.attr('aria-expanded'), 'true', 'aria-expanded is set to string "true" on click')
+ done()
+ })
+ $dropdown.trigger('click')
})
QUnit.test('should set aria-expanded="false" on target when dropdown menu is hidden', function (assert) {
assert.expect(1)
var done = assert.async()
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" aria-expanded="false" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
@@ -114,86 +118,107 @@ $(function () {
})
QUnit.test('should not open dropdown if target is disabled via class', function (assert) {
- assert.expect(1)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ assert.expect(0)
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
-
- assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ setTimeout(function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ }, 300)
})
QUnit.test('should add class show to menu if clicked', function (assert) {
assert.expect(1)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var done = assert.async()
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
-
- assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ done()
+ })
+ $dropdown.trigger('click')
})
QUnit.test('should test if element has a # before assuming it\'s a selector', function (assert) {
assert.expect(1)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var done = assert.async()
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="/foo/" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
-
- assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ done()
+ })
+ $dropdown.trigger('click')
})
QUnit.test('should remove "show" class if body is clicked', function (assert) {
assert.expect(2)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var done = assert.async()
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .trigger('click')
- assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
- $(document.body).trigger('click')
- assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class removed')
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ $(document.body).trigger('click')
+ }).on('hidden.bs.dropdown', function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class removed')
+ done()
+ })
+ $dropdown.trigger('click')
})
- QUnit.test('should remove "show" class if body is focused', function (assert) {
+ QUnit.test('should remove "show" class if tabbing outside of menu', function (assert) {
assert.expect(2)
+ var done = assert.async()
var dropdownHTML = '<div class="tabs">'
+ '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
@@ -209,30 +234,37 @@ $(function () {
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .trigger('click')
-
- assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
- $(document.body).trigger('focusin')
- assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class removed')
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
+ var e = $.Event('keyup')
+ e.which = 9 // Tab
+ $(document.body).trigger(e)
+ }).on('hidden.bs.dropdown', function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class removed')
+ done()
+ })
+ $dropdown.trigger('click')
})
QUnit.test('should remove "show" class if body is clicked, with multiple dropdowns', function (assert) {
assert.expect(7)
- var dropdownHTML = '<ul class="nav">'
- + '<li><a href="#menu1">Menu 1</a></li>'
- + '<li class="dropdown" id="testmenu">'
+ var done = assert.async()
+ var dropdownHTML = '<div class="nav">'
+ + '<div class="dropdown" id="testmenu">'
+ '<a class="dropdown-toggle" data-toggle="dropdown" href="#testmenu">Test menu <span class="caret"/></a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#sub1">Submenu 1</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<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-toggle="dropdown"><span class="caret"/></button>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Action 1</a></li>'
- + '</ul>'
+ + '<button class="btn dropdown-toggle" data-toggle="dropdown"></button>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Action 1</a>'
+ + '</div>'
+ '</div>'
var $dropdowns = $(dropdownHTML).appendTo('#qunit-fixture').find('[data-toggle="dropdown"]')
var $first = $dropdowns.first()
@@ -240,21 +272,31 @@ $(function () {
assert.strictEqual($dropdowns.length, 2, 'two dropdowns')
+ $first.parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.strictEqual($first.parents('.show').length, 1, '"show" class added on click')
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 1, 'only one dropdown is shown')
+ $(document.body).trigger('click')
+ }).on('hidden.bs.dropdown', function () {
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 0, '"show" class removed')
+ $last.trigger('click')
+ })
+
+ $last.parent('.btn-group')
+ .on('shown.bs.dropdown', function () {
+ assert.strictEqual($last.parent('.show').length, 1, '"show" class added on click')
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 1, 'only one dropdown is shown')
+ $(document.body).trigger('click')
+ }).on('hidden.bs.dropdown', function () {
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 0, '"show" class removed')
+ done()
+ })
$first.trigger('click')
- assert.strictEqual($first.parents('.show').length, 1, '"show" class added on click')
- assert.strictEqual($('#qunit-fixture .show').length, 1, 'only one dropdown is shown')
- $(document.body).trigger('click')
- assert.strictEqual($('#qunit-fixture .show').length, 0, '"show" class removed')
-
- $last.trigger('click')
- assert.strictEqual($last.parent('.show').length, 1, '"show" class added on click')
- assert.strictEqual($('#qunit-fixture .show').length, 1, 'only one dropdown is shown')
- $(document.body).trigger('click')
- assert.strictEqual($('#qunit-fixture .show').length, 0, '"show" class removed')
})
- QUnit.test('should remove "show" class if body is focused, with multiple dropdowns', function (assert) {
+ QUnit.test('should remove "show" class if body if tabbing outside of menu, with multiple dropdowns', function (assert) {
assert.expect(7)
+ var done = assert.async()
var dropdownHTML = '<div class="nav">'
+ '<div class="dropdown" id="testmenu">'
+ '<a class="dropdown-toggle" data-toggle="dropdown" href="#testmenu">Test menu <span class="caret"/></a>'
@@ -276,32 +318,45 @@ $(function () {
assert.strictEqual($dropdowns.length, 2, 'two dropdowns')
+ $first.parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.strictEqual($first.parents('.show').length, 1, '"show" class added on click')
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 1, 'only one dropdown is shown')
+ var e = $.Event('keyup')
+ e.which = 9 // Tab
+ $(document.body).trigger(e)
+ }).on('hidden.bs.dropdown', function () {
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 0, '"show" class removed')
+ $last.trigger('click')
+ })
+
+ $last.parent('.btn-group')
+ .on('shown.bs.dropdown', function () {
+ assert.strictEqual($last.parent('.show').length, 1, '"show" class added on click')
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 1, 'only one dropdown is shown')
+ var e = $.Event('keyup')
+ e.which = 9 // Tab
+ $(document.body).trigger(e)
+ }).on('hidden.bs.dropdown', function () {
+ assert.strictEqual($('#qunit-fixture .dropdown-menu.show').length, 0, '"show" class removed')
+ done()
+ })
$first.trigger('click')
- assert.strictEqual($first.parents('.show').length, 1, '"show" class added on click')
- assert.strictEqual($('#qunit-fixture .show').length, 1, 'only one dropdown is show')
- $(document.body).trigger('focusin')
- assert.strictEqual($('#qunit-fixture .show').length, 0, '"show" class removed')
-
- $last.trigger('click')
- assert.strictEqual($last.parent('.show').length, 1, '"show" class added on click')
- assert.strictEqual($('#qunit-fixture .show').length, 1, 'only one dropdown is show')
- $(document.body).trigger('focusin')
- assert.strictEqual($('#qunit-fixture .show').length, 0, '"show" class removed')
})
QUnit.test('should fire show and hide event', function (assert) {
assert.expect(2)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
@@ -326,17 +381,17 @@ $(function () {
QUnit.test('should fire shown and hidden event', function (assert) {
assert.expect(2)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
@@ -360,17 +415,17 @@ $(function () {
QUnit.test('should fire shown and hidden event with a relatedTarget', function (assert) {
assert.expect(2)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
@@ -394,19 +449,19 @@ $(function () {
assert.expect(3)
var done = assert.async()
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li><a href="#">Secondary link</a></li>'
- + '<li><a href="#">Something else here</a></li>'
- + '<li class="divider"/>'
- + '<li><a href="#">Another link</a></li>'
- + '<li><input type="text" id="input"></li>'
- + '<li><textarea id="textarea"/></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item" href="#">Secondary link</a>'
+ + '<a class="dropdown-item" href="#">Something else here</a>'
+ + '<div class="divider"/>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '<input type="text" id="input">'
+ + '<textarea id="textarea"/>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
@@ -433,63 +488,124 @@ $(function () {
})
QUnit.test('should skip disabled element when using keyboard navigation', function (assert) {
- assert.expect(1)
- var dropdownHTML = '<ul class="tabs">'
- + '<li class="dropdown">'
+ assert.expect(2)
+ var done = assert.async()
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
- + '<ul class="dropdown-menu">'
- + '<li class="disabled"><a href="#">Disabled link</a></li>'
- + '<li><a href="#">Another link</a></li>'
- + '</ul>'
- + '</li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<a class="dropdown-item disabled" href="#">Disabled link</a>'
+ + '<a class="dropdown-item" href="#">Another link</a>'
+ + '</div>'
+ + '</div>'
+ + '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .trigger('click')
- $dropdown.trigger($.Event('keydown', { which: 40 }))
- $dropdown.trigger($.Event('keydown', { which: 40 }))
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok(true, 'shown was fired')
+ $dropdown.trigger($.Event('keydown', { which: 40 }))
+ $dropdown.trigger($.Event('keydown', { which: 40 }))
+ assert.ok(!$(document.activeElement).is('.disabled'), '.disabled is not focused')
+ done()
+ })
+ $dropdown.trigger('click')
+ })
+
+ QUnit.test('should focus next/previous element when using keyboard navigation', function (assert) {
+ assert.expect(4)
+ var done = assert.async()
+ var dropdownHTML = '<div class="tabs">'
+ + '<div class="dropdown">'
+ + '<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown</a>'
+ + '<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>'
+ + '</div>'
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
+
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok(true, 'shown was fired')
+ $dropdown.trigger($.Event('keydown', { which: 40 }))
+ assert.ok($(document.activeElement).is($('#item1')), 'item1 is focused')
+
+ $(document.activeElement).trigger($.Event('keydown', { which: 40 }))
+ assert.ok($(document.activeElement).is($('#item2')), 'item2 is focused')
+
+ $(document.activeElement).trigger($.Event('keydown', { which: 38 }))
+ assert.ok($(document.activeElement).is($('#item1')), 'item1 is focused')
+ done()
+ })
+ $dropdown.trigger('click')
- assert.ok(!$(document.activeElement).parent().is('.disabled'), '.disabled is not focused')
})
QUnit.test('should not close the dropdown if the user clicks on a text field', function (assert) {
- assert.expect(1)
- var dropdownHTML = '<div class="btn-group">'
+ assert.expect(2)
+ var done = assert.async()
+ var dropdownHTML = '<div class="dropdown">'
+ '<button type="button" data-toggle="dropdown">Dropdown</button>'
- + '<ul class="dropdown-menu">'
- + '<li><input id="textField" type="text" /></li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<input id="textField" type="text" />'
+ + '</div>'
+ '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .trigger('click')
- $('#textField').trigger('click')
+ var $textfield = $('#textField')
+ $textfield.on('click', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ done()
+ })
- assert.ok($dropdown.parent('.btn-group').hasClass('show'), 'dropdown menu is shown')
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ $textfield.trigger($.Event('click'))
+ })
+ $dropdown.trigger('click')
})
QUnit.test('should not close the dropdown if the user clicks on a textarea', function (assert) {
- assert.expect(1)
- var dropdownHTML = '<div class="btn-group">'
+ assert.expect(2)
+ var done = assert.async()
+ var dropdownHTML = '<div class="dropdown">'
+ '<button type="button" data-toggle="dropdown">Dropdown</button>'
- + '<ul class="dropdown-menu">'
- + '<li><textarea id="textArea"></textarea></li>'
- + '</ul>'
+ + '<div class="dropdown-menu">'
+ + '<textarea id="textArea"></textarea>'
+ + '</div>'
+ '</div>'
var $dropdown = $(dropdownHTML)
.appendTo('#qunit-fixture')
.find('[data-toggle="dropdown"]')
.bootstrapDropdown()
- .trigger('click')
- $('#textArea').trigger('click')
+ var $textarea = $('#textArea')
+ $textarea.on('click', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ done()
+ })
- assert.ok($dropdown.parent('.btn-group').hasClass('show'), 'dropdown menu is shown')
+ $dropdown
+ .parent('.dropdown')
+ .on('shown.bs.dropdown', function () {
+ assert.ok($dropdown.parent('.dropdown').hasClass('show'), 'dropdown menu is shown')
+ $textarea.trigger($.Event('click'))
+ })
+ $dropdown.trigger('click')
})
})
diff --git a/js/tests/unit/modal.js b/js/tests/unit/modal.js
index 84492cec2..fc6c4f38c 100644
--- a/js/tests/unit/modal.js
+++ b/js/tests/unit/modal.js
@@ -9,6 +9,19 @@ $(function () {
})
QUnit.module('modal', {
+ before: function () {
+ // Enable the scrollbar measurer
+ $('<style type="text/css"> .modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; } </style>').appendTo('head')
+ // Function to calculate the scrollbar width which is then compared to the padding or margin changes
+ $.fn.getScrollbarWidth = function () {
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ document.body.appendChild(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ document.body.removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+ },
beforeEach: function () {
// Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
$.fn.bootstrapModal = $.fn.modal.noConflict()
@@ -336,81 +349,147 @@ $(function () {
$toggleBtn.trigger('click')
})
- QUnit.test('should restore inline body padding after closing', function (assert) {
+ QUnit.test('should adjust the inline body padding when opening and restore when closing', function (assert) {
assert.expect(2)
var done = assert.async()
- var originalBodyPad = 0
var $body = $(document.body)
-
- $body.css('padding-right', originalBodyPad)
+ var originalPadding = $body.css('padding-right')
$('<div id="modal-test"/>')
.on('hidden.bs.modal', function () {
- var currentBodyPad = parseInt($body.css('padding-right'), 10)
- assert.notStrictEqual($body.attr('style'), '', 'body has non-empty style attribute')
- assert.strictEqual(currentBodyPad, originalBodyPad, 'original body padding was not changed')
+ var currentPadding = $body.css('padding-right')
+ assert.strictEqual(currentPadding, originalPadding, 'body padding should be reset after closing')
$body.removeAttr('style')
done()
})
.on('shown.bs.modal', function () {
+ var expectedPadding = parseFloat(originalPadding) + $(this).getScrollbarWidth() + 'px'
+ var currentPadding = $body.css('padding-right')
+ assert.strictEqual(currentPadding, expectedPadding, 'body padding should be adjusted while opening')
$(this).bootstrapModal('hide')
})
.bootstrapModal('show')
})
- QUnit.test('should ignore values set via CSS when trying to restore body padding after closing', function (assert) {
- assert.expect(1)
+ QUnit.test('should store the original body padding in data-padding-right before showing', function (assert) {
+ assert.expect(2)
var done = assert.async()
var $body = $(document.body)
- var $style = $('<style>body { padding-right: 42px; }</style>').appendTo('head')
+ var originalPadding = '0px'
+ $body.css('padding-right', originalPadding)
$('<div id="modal-test"/>')
.on('hidden.bs.modal', function () {
- assert.ok(!$body.attr('style'), 'body does not have inline padding set')
- $style.remove()
+ assert.strictEqual($body.data('padding-right'), undefined, 'data-padding-right should be cleared after closing')
+ $body.removeAttr('style')
done()
})
.on('shown.bs.modal', function () {
+ assert.strictEqual($body.data('padding-right'), originalPadding, 'original body padding should be stored in data-padding-right')
$(this).bootstrapModal('hide')
})
.bootstrapModal('show')
})
- QUnit.test('should have a paddingRight when the modal is taller than the viewport', function (assert) {
+ QUnit.test('should adjust the inline padding of fixed elements when opening and restore when closing', function (assert) {
assert.expect(2)
var done = assert.async()
- $('<div class="fixed-top fixed-bottom sticky-top is-fixed">@Johann-S</div>').appendTo('#qunit-fixture')
- $('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top').css('padding-right', '10px')
+ var $element = $('<div class="fixed-top"></div>').appendTo('#qunit-fixture')
+ var originalPadding = $element.css('padding-right')
$('<div id="modal-test"/>')
+ .on('hidden.bs.modal', function () {
+ var currentPadding = $element.css('padding-right')
+ assert.strictEqual(currentPadding, originalPadding, 'fixed element padding should be reset after closing')
+ $element.remove()
+ done()
+ })
.on('shown.bs.modal', function () {
- var paddingRight = parseInt($(document.body).css('padding-right'), 10)
- assert.strictEqual(isNaN(paddingRight), false)
- assert.strictEqual(paddingRight !== 0, true)
- $(document.body).css('padding-right', '') // Because test case "should ignore other inline styles when trying to restore body padding after closing" fail if not
+ var expectedPadding = parseFloat(originalPadding) + $(this).getScrollbarWidth() + 'px'
+ var currentPadding = $element.css('padding-right')
+ assert.strictEqual(currentPadding, expectedPadding, 'fixed element padding should be adjusted while opening')
+ $(this).bootstrapModal('hide')
+ })
+ .bootstrapModal('show')
+ })
+
+ QUnit.test('should store the original padding of fixed elements in data-padding-right before showing', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+ var $element = $('<div class="fixed-top"></div>').appendTo('#qunit-fixture')
+ var originalPadding = '0px'
+ $element.css('padding-right', originalPadding)
+
+ $('<div id="modal-test"/>')
+ .on('hidden.bs.modal', function () {
+ assert.strictEqual($element.data('padding-right'), undefined, 'data-padding-right should be cleared after closing')
+ $element.remove()
done()
})
+ .on('shown.bs.modal', function () {
+ assert.strictEqual($element.data('padding-right'), originalPadding, 'original fixed element padding should be stored in data-padding-right')
+ $(this).bootstrapModal('hide')
+ })
.bootstrapModal('show')
})
- QUnit.test('should remove padding-right on modal after closing', function (assert) {
- assert.expect(3)
+ QUnit.test('should adjust the inline margin of the navbar-toggler when opening and restore when closing', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+ var $element = $('<div class="navbar-toggler"></div>').appendTo('#qunit-fixture')
+ var originalMargin = $element.css('margin-right')
+
+ $('<div id="modal-test"/>')
+ .on('hidden.bs.modal', function () {
+ var currentMargin = $element.css('margin-right')
+ assert.strictEqual(currentMargin, originalMargin, 'navbar-toggler margin should be reset after closing')
+ $element.remove()
+ done()
+ })
+ .on('shown.bs.modal', function () {
+ var expectedMargin = parseFloat(originalMargin) + $(this).getScrollbarWidth() + 'px'
+ var currentMargin = $element.css('margin-right')
+ assert.strictEqual(currentMargin, expectedMargin, 'navbar-toggler margin should be adjusted while opening')
+ $(this).bootstrapModal('hide')
+ })
+ .bootstrapModal('show')
+ })
+
+ QUnit.test('should store the original margin of the navbar-toggler in data-margin-right before showing', function (assert) {
+ assert.expect(2)
var done = assert.async()
- $('<div class="fixed-top fixed-bottom is-fixed sticky-top">@Johann-S</div>').appendTo('#qunit-fixture')
- $('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top').css('padding-right', '10px')
+ var $element = $('<div class="navbar-toggler"></div>').appendTo('#qunit-fixture')
+ var originalMargin = '0px'
+ $element.css('margin-right', originalMargin)
$('<div id="modal-test"/>')
+ .on('hidden.bs.modal', function () {
+ assert.strictEqual($element.data('margin-right'), undefined, 'data-margin-right should be cleared after closing')
+ $element.remove()
+ done()
+ })
.on('shown.bs.modal', function () {
- var paddingRight = parseInt($(document.body).css('padding-right'), 10)
- assert.strictEqual(isNaN(paddingRight), false)
- assert.strictEqual(paddingRight !== 0, true)
+ assert.strictEqual($element.data('margin-right'), originalMargin, 'original navbar-toggler margin should be stored in data-margin-right')
$(this).bootstrapModal('hide')
})
+ .bootstrapModal('show')
+ })
+
+ QUnit.test('should ignore values set via CSS when trying to restore body padding after closing', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+ var $body = $(document.body)
+ var $style = $('<style>body { padding-right: 42px; }</style>').appendTo('head')
+
+ $('<div id="modal-test"/>')
.on('hidden.bs.modal', function () {
- var paddingRight = parseInt($(document.body).css('padding-right'), 10)
- assert.strictEqual(paddingRight, 0)
+ assert.ok(!$body.attr('style'), 'body does not have inline padding set')
+ $style.remove()
done()
})
+ .on('shown.bs.modal', function () {
+ $(this).bootstrapModal('hide')
+ })
.bootstrapModal('show')
})
diff --git a/js/tests/unit/phantom.js b/js/tests/unit/phantom.js
deleted file mode 100644
index eea7486a4..000000000
--- a/js/tests/unit/phantom.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * grunt-contrib-qunit
- * http://gruntjs.com/
- *
- * Copyright (c) 2014 "Cowboy" Ben Alman, contributors
- * Licensed under the MIT license.
- */
-
-(function () {
- 'use strict'
-
- // Don't re-order tests.
- QUnit.config.reorder = false
- // Run tests serially, not in parallel.
- QUnit.config.autorun = false
-
- // Send messages to the parent PhantomJS process via alert! Good times!!
- function sendMessage() {
- var args = [].slice.call(arguments)
- alert(JSON.stringify(args))
- }
-
- // These methods connect QUnit to PhantomJS.
- QUnit.log(function (obj) {
- // What is this I don’t even
- if (obj.message === '[object Object], undefined:undefined') { return }
-
- // Parse some stuff before sending it.
- var actual
- var expected
- if (!obj.result) {
- // Dumping large objects can be very slow, and the dump isn't used for
- // passing tests, so only dump if the test failed.
- actual = QUnit.dump.parse(obj.actual)
- expected = QUnit.dump.parse(obj.expected)
- }
- // Send it.
- sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
- })
-
- QUnit.testStart(function (obj) {
- sendMessage('qunit.testStart', obj.name)
- })
-
- QUnit.testDone(function (obj) {
- sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total, obj.duration)
- })
-
- QUnit.moduleStart(function (obj) {
- sendMessage('qunit.moduleStart', obj.name)
- })
-
- QUnit.moduleDone(function (obj) {
- if (obj.failed === 0) {
- console.log('\r\u221A All tests passed in "' + obj.name + '" module')
- } else {
- console.log('\u00D7 ' + obj.failed + ' tests failed in "' + obj.name + '" module')
- }
- sendMessage('qunit.moduleDone', obj.name, obj.failed, obj.passed, obj.total)
- })
-
- QUnit.begin(function () {
- sendMessage('qunit.begin')
- console.log('\n\nStarting test suite')
- console.log('================================================\n')
- })
-
- QUnit.done(function (obj) {
- sendMessage('qunit.done', obj.failed, obj.passed, obj.total, obj.runtime)
- })
-
-}())
diff --git a/js/tests/unit/popover.js b/js/tests/unit/popover.js
index 64c8c556a..a7762bfab 100644
--- a/js/tests/unit/popover.js
+++ b/js/tests/unit/popover.js
@@ -47,13 +47,18 @@ $(function () {
QUnit.test('should render popover element', function (assert) {
assert.expect(2)
- var $popover = $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>')
+ var done = assert.async()
+ $('<a href="#" title="mdo" data-content="https://twitter.com/mdo">@mdo</a>')
.appendTo('#qunit-fixture')
+ .on('shown.bs.popover', function () {
+ assert.notEqual($('.popover').length, 0, 'popover was inserted')
+ $(this).bootstrapPopover('hide')
+ })
+ .on('hidden.bs.popover', function () {
+ assert.strictEqual($('.popover').length, 0, 'popover removed')
+ done()
+ })
.bootstrapPopover('show')
-
- assert.notEqual($('.popover').length, 0, 'popover was inserted')
- $popover.bootstrapPopover('hide')
- assert.strictEqual($('.popover').length, 0, 'popover removed')
})
QUnit.test('should store popover instance in popover data object', function (assert) {
@@ -364,4 +369,22 @@ $(function () {
})
.modal('show')
})
+
+ QUnit.test('should convert number to string without error for content and title', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+ var $popover = $('<a href="#">@mdo</a>')
+ .appendTo('#qunit-fixture')
+ .bootstrapPopover({
+ title: 5,
+ content: 7
+ })
+ .on('shown.bs.popover', function () {
+ assert.strictEqual($('.popover .popover-title').text(), '5')
+ assert.strictEqual($('.popover .popover-content').text(), '7')
+ done()
+ })
+
+ $popover.bootstrapPopover('show')
+ })
})
diff --git a/js/tests/unit/scrollspy.js b/js/tests/unit/scrollspy.js
index 877ec67a2..a6a72e7a6 100644
--- a/js/tests/unit/scrollspy.js
+++ b/js/tests/unit/scrollspy.js
@@ -26,7 +26,7 @@ $(function () {
QUnit.test('should throw explicit error on undefined method', function (assert) {
assert.expect(1)
- var $el = $('<div/>')
+ var $el = $('<div/>').appendTo('#qunit-fixture')
$el.bootstrapScrollspy()
try {
$el.bootstrapScrollspy('noMethod')
@@ -38,7 +38,7 @@ $(function () {
QUnit.test('should return jquery collection containing the element', function (assert) {
assert.expect(2)
- var $el = $('<div/>')
+ var $el = $('<div/>').appendTo('#qunit-fixture')
var $scrollspy = $el.bootstrapScrollspy()
assert.ok($scrollspy instanceof $, 'returns jquery collection')
assert.strictEqual($scrollspy[0], $el[0], 'collection contains element')
@@ -53,8 +53,8 @@ $(function () {
+ '<div class="topbar-inner">'
+ '<div class="container" id="ss-target">'
+ '<ul class="nav">'
- + '<li><a href="#masthead">Overview</a></li>'
- + '<li><a href="#detail">Detail</a></li>'
+ + '<li class="nav-item"><a href="#masthead">Overview</a></li>'
+ + '<li class="nav-item"><a href="#detail">Detail</a></li>'
+ '</ul>'
+ '</div>'
+ '</div>'
@@ -98,8 +98,8 @@ $(function () {
+ '<div class="topbar-inner">'
+ '<div class="container" id="ss-target">'
+ '<ul class="nav">'
- + '<li><a href="#masthead">Overview</a></li>'
- + '<li><a href="#detail">Detail</a></li>'
+ + '<li class="nav-item"><a href="#masthead">Overview</a></li>'
+ + '<li class="nav-item"><a href="#detail">Detail</a></li>'
+ '</ul>'
+ '</div>'
+ '</div>'
@@ -140,10 +140,10 @@ $(function () {
var sectionHTML = '<div id="header" style="height: 500px;"></div>'
+ '<nav id="navigation" class="navbar">'
- + '<ul class="nav navbar-nav">'
- + '<li class="active"><a class="nav-link" id="one-link" href="#one">One</a></li>'
- + '<li><a class="nav-link" id="two-link" href="#two">Two</a></li>'
- + '<li><a class="nav-link" id="three-link" href="#three">Three</a></li>'
+ + '<ul class="navbar-nav">'
+ + '<li class="nav-item active"><a class="nav-link" id="one-link" href="#one">One</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="two-link" href="#two">Two</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="three-link" href="#three">Three</a></li>'
+ '</ul>'
+ '</nav>'
+ '<div id="content" style="height: 200px; overflow-y: auto;">'
@@ -173,8 +173,8 @@ $(function () {
var navbarHtml =
'<nav class="navbar">'
+ '<ul class="nav">'
- + '<li><a class="nav-link" id="a-1" href="#div-1">div 1</a></li>'
- + '<li><a class="nav-link" id="a-2" href="#div-2">div 2</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="a-1" href="#div-1">div 1</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="a-2" href="#div-2">div 2</a></li>'
+ '</ul>'
+ '</nav>'
var contentHtml =
@@ -205,15 +205,89 @@ $(function () {
.then(function () { done() })
})
+ QUnit.test('should add the active class to the correct element (nav markup)', function (assert) {
+ assert.expect(2)
+ var navbarHtml =
+ '<nav class="navbar">'
+ + '<nav class="nav">'
+ + '<a class="nav-link" id="a-1" href="#div-1">div 1</a>'
+ + '<a class="nav-link" id="a-2" href="#div-2">div 2</a>'
+ + '</nav>'
+ + '</nav>'
+ var contentHtml =
+ '<div class="content" style="overflow: auto; height: 50px">'
+ + '<div id="div-1" style="height: 100px; padding: 0; margin: 0">div 1</div>'
+ + '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '.navbar' })
+
+ var done = assert.async()
+ var testElementIsActiveAfterScroll = function (element, target) {
+ var deferred = $.Deferred()
+ var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
+ $content.one('scroll', function () {
+ assert.ok($(element).hasClass('active'), 'target:' + target + ', element' + element)
+ deferred.resolve()
+ })
+ $content.scrollTop(scrollHeight)
+ return deferred.promise()
+ }
+
+ $.when(testElementIsActiveAfterScroll('#a-1', '#div-1'))
+ .then(function () { return testElementIsActiveAfterScroll('#a-2', '#div-2') })
+ .then(function () { done() })
+ })
+
+ QUnit.test('should add the active class to the correct element (list-group markup)', function (assert) {
+ assert.expect(2)
+ var navbarHtml =
+ '<nav class="navbar">'
+ + '<div class="list-group">'
+ + '<a class="list-group-item" id="a-1" href="#div-1">div 1</a>'
+ + '<a class="list-group-item" id="a-2" href="#div-2">div 2</a>'
+ + '</div>'
+ + '</nav>'
+ var contentHtml =
+ '<div class="content" style="overflow: auto; height: 50px">'
+ + '<div id="div-1" style="height: 100px; padding: 0; margin: 0">div 1</div>'
+ + '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '.navbar' })
+
+ var done = assert.async()
+ var testElementIsActiveAfterScroll = function (element, target) {
+ var deferred = $.Deferred()
+ var scrollHeight = Math.ceil($content.scrollTop() + $(target).position().top)
+ $content.one('scroll', function () {
+ assert.ok($(element).hasClass('active'), 'target:' + target + ', element' + element)
+ deferred.resolve()
+ })
+ $content.scrollTop(scrollHeight)
+ return deferred.promise()
+ }
+
+ $.when(testElementIsActiveAfterScroll('#a-1', '#div-1'))
+ .then(function () { return testElementIsActiveAfterScroll('#a-2', '#div-2') })
+ .then(function () { done() })
+ })
+
QUnit.test('should add the active class correctly when there are nested elements at 0 scroll offset', function (assert) {
assert.expect(6)
var times = 0
var done = assert.async()
var navbarHtml = '<nav id="navigation" class="navbar">'
+ '<ul class="nav">'
- + '<li><a id="a-1" class="nav-link" href="#div-1">div 1</a>'
- + '<ul>'
- + '<li><a id="a-2" class="nav-link" href="#div-2">div 2</a></li>'
+ + '<li class="nav-item"><a id="a-1" class="nav-link" href="#div-1">div 1</a>'
+ + '<ul class="nav">'
+ + '<li class="nav-item"><a id="a-2" class="nav-link" href="#div-2">div 2</a></li>'
+ '</ul>'
+ '</li>'
+ '</ul>'
@@ -246,16 +320,96 @@ $(function () {
testActiveElements()
})
+ QUnit.test('should add the active class correctly when there are nested elements (nav markup)', function (assert) {
+ assert.expect(6)
+ var times = 0
+ var done = assert.async()
+ var navbarHtml = '<nav id="navigation" class="navbar">'
+ + '<nav class="nav">'
+ + '<a id="a-1" class="nav-link" href="#div-1">div 1</a>'
+ + '<nav class="nav">'
+ + '<a id="a-2" class="nav-link" href="#div-2">div 2</a>'
+ + '</nav>'
+ + '</nav>'
+ + '</nav>'
+
+ var contentHtml = '<div class="content" style="position: absolute; top: 0px; overflow: auto; height: 50px">'
+ + '<div id="div-1" style="padding: 0; margin: 0">'
+ + '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ + '</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '#navigation' })
+
+ function testActiveElements() {
+ if (++times > 3) { return done() }
+
+ $content.one('scroll', function () {
+ assert.ok($('#a-1').hasClass('active'), 'nav item for outer element has "active" class')
+ assert.ok($('#a-2').hasClass('active'), 'nav item for inner element has "active" class')
+ testActiveElements()
+ })
+
+ $content.scrollTop($content.scrollTop() + 10)
+ }
+
+ testActiveElements()
+ })
+
+ QUnit.test('should add the active class correctly when there are nested elements (list-group markup)', function (assert) {
+ assert.expect(6)
+ var times = 0
+ var done = assert.async()
+ var navbarHtml = '<nav id="navigation" class="navbar">'
+ + '<div class="list-group">'
+ + '<a id="a-1" class="list-group-item" href="#div-1">div 1</a>'
+ + '<div class="list-group">'
+ + '<a id="a-2" class="list-group-item" href="#div-2">div 2</a>'
+ + '</div>'
+ + '</div>'
+ + '</nav>'
+
+ var contentHtml = '<div class="content" style="position: absolute; top: 0px; overflow: auto; height: 50px">'
+ + '<div id="div-1" style="padding: 0; margin: 0">'
+ + '<div id="div-2" style="height: 200px; padding: 0; margin: 0">div 2</div>'
+ + '</div>'
+ + '</div>'
+
+ $(navbarHtml).appendTo('#qunit-fixture')
+
+ var $content = $(contentHtml)
+ .appendTo('#qunit-fixture')
+ .bootstrapScrollspy({ offset: 0, target: '#navigation' })
+
+ function testActiveElements() {
+ if (++times > 3) { return done() }
+
+ $content.one('scroll', function () {
+ assert.ok($('#a-1').hasClass('active'), 'nav item for outer element has "active" class')
+ assert.ok($('#a-2').hasClass('active'), 'nav item for inner element has "active" class')
+ testActiveElements()
+ })
+
+ $content.scrollTop($content.scrollTop() + 10)
+ }
+
+ testActiveElements()
+ })
+
QUnit.test('should clear selection if above the first section', function (assert) {
assert.expect(3)
var done = assert.async()
var sectionHTML = '<div id="header" style="height: 500px;"></div>'
+ '<nav id="navigation" class="navbar">'
- + '<ul class="nav navbar-nav">'
- + '<li><a id="one-link" class="nav-link active" href="#one">One</a></li>'
- + '<li><a id="two-link" class="nav-link" href="#two">Two</a></li>'
- + '<li><a id="three-link" class="nav-link" href="#three">Three</a></li>'
+ + '<ul class="navbar-nav">'
+ + '<li class="nav-item"><a id="one-link" class="nav-link active" href="#one">One</a></li>'
+ + '<li class="nav-item"><a id="two-link" class="nav-link" href="#two">Two</a></li>'
+ + '<li class="nav-item"><a id="three-link" class="nav-link" href="#three">Three</a></li>'
+ '</ul>'
+ '</nav>'
$(sectionHTML).appendTo('#qunit-fixture')
@@ -293,10 +447,10 @@ $(function () {
var sectionHTML = '<div id="header" style="height: 500px;"></div>'
+ '<nav id="navigation" class="navbar">'
- + '<ul class="nav navbar-nav">'
- + '<li><a id="one-link" class="nav-link active" href="#one">One</a></li>'
- + '<li><a id="two-link" class="nav-link" href="#two">Two</a></li>'
- + '<li><a id="three-link" class="nav-link" href="#three">Three</a></li>'
+ + '<ul class="navbar-nav">'
+ + '<li class="nav-item"><a id="one-link" class="nav-link active" href="#one">One</a></li>'
+ + '<li class="nav-item"><a id="two-link" class="nav-link" href="#two">Two</a></li>'
+ + '<li class="nav-item"><a id="three-link" class="nav-link" href="#three">Three</a></li>'
+ '</ul>'
+ '</nav>'
$(sectionHTML).appendTo('#qunit-fixture')
@@ -336,11 +490,11 @@ $(function () {
var navbarHtml =
'<nav class="navbar">'
+ '<ul class="nav">'
- + '<li><a id="li-100-1" class="nav-link" href="#div-100-1">div 1</a></li>'
- + '<li><a id="li-100-2" class="nav-link" href="#div-100-2">div 2</a></li>'
- + '<li><a id="li-100-3" class="nav-link" href="#div-100-3">div 3</a></li>'
- + '<li><a id="li-100-4" class="nav-link" href="#div-100-4">div 4</a></li>'
- + '<li><a id="li-100-5" class="nav-link" href="#div-100-5">div 5</a></li>'
+ + '<li class="nav-item"><a id="li-100-1" class="nav-link" href="#div-100-1">div 1</a></li>'
+ + '<li class="nav-item"><a id="li-100-2" class="nav-link" href="#div-100-2">div 2</a></li>'
+ + '<li class="nav-item"><a id="li-100-3" class="nav-link" href="#div-100-3">div 3</a></li>'
+ + '<li class="nav-item"><a id="li-100-4" class="nav-link" href="#div-100-4">div 4</a></li>'
+ + '<li class="nav-item"><a id="li-100-5" class="nav-link" href="#div-100-5">div 5</a></li>'
+ '</ul>'
+ '</nav>'
var contentHtml =
@@ -384,9 +538,9 @@ $(function () {
var $navbar = $(
'<nav class="navbar"' + (type === 'data' ? ' id="navbar-offset-method-menu"' : '') + '>'
+ '<ul class="nav">'
- + '<li><a id="li-' + type + 'm-1" class="nav-link" href="#div-' + type + 'm-1">div 1</a></li>'
- + '<li><a id="li-' + type + 'm-2" class="nav-link" href="#div-' + type + 'm-2">div 2</a></li>'
- + '<li><a id="li-' + type + 'm-3" class="nav-link" href="#div-' + type + 'm-3">div 3</a></li>'
+ + '<li class="nav-item"><a id="li-' + type + 'm-1" class="nav-link" href="#div-' + type + 'm-1">div 1</a></li>'
+ + '<li class="nav-item"><a id="li-' + type + 'm-2" class="nav-link" href="#div-' + type + 'm-2">div 2</a></li>'
+ + '<li class="nav-item"><a id="li-' + type + 'm-3" class="nav-link" href="#div-' + type + 'm-3">div 3</a></li>'
+ '</ul>'
+ '</nav>'
)
@@ -428,9 +582,9 @@ $(function () {
var $navbar = $(
'<nav class="navbar"' + (type === 'data' ? ' id="navbar-offset-method-menu"' : '') + '>'
+ '<ul class="nav">'
- + '<li><a class="nav-link" id="li-' + type + 'm-1" href="#div-' + type + 'm-1">div 1</a></li>'
- + '<li><a class="nav-link" id="li-' + type + 'm-2" href="#div-' + type + 'm-2">div 2</a></li>'
- + '<li><a class="nav-link" id="li-' + type + 'm-3" href="#div-' + type + 'm-3">div 3</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="li-' + type + 'm-1" href="#div-' + type + 'm-1">div 1</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="li-' + type + 'm-2" href="#div-' + type + 'm-2">div 2</a></li>'
+ + '<li class="nav-item"><a class="nav-link" id="li-' + type + 'm-3" href="#div-' + type + 'm-3">div 3</a></li>'
+ '</ul>'
+ '</nav>'
)
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index 734648e9e..1e2b66c04 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -46,7 +46,7 @@ $(function () {
QUnit.test('should activate element by tab id', function (assert) {
assert.expect(2)
- var tabsHTML = '<ul class="tabs">'
+ var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@@ -62,7 +62,7 @@ $(function () {
QUnit.test('should activate element by tab id', function (assert) {
assert.expect(2)
- var pillsHTML = '<ul class="pills">'
+ var pillsHTML = '<ul class="nav nav-pills">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@@ -78,7 +78,7 @@ $(function () {
QUnit.test('should activate element by tab id in ordered list', function (assert) {
assert.expect(2)
- var pillsHTML = '<ol class="pills">'
+ var pillsHTML = '<ol class="nav nav-pills">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ol>'
@@ -108,11 +108,27 @@ $(function () {
assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
})
+ QUnit.test('should activate element by tab id in list group', function (assert) {
+ assert.expect(2)
+ var tabsHTML = '<div class="list-group">' +
+ '<a href="#home">Home</a>' +
+ '<a href="#profile">Profile</a>' +
+ '</div>'
+
+ $('<nav><div id="home"></div><div id="profile"></div></nav>').appendTo('#qunit-fixture')
+
+ $(tabsHTML).find('a:last').bootstrapTab('show')
+ assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'profile')
+
+ $(tabsHTML).find('a:first').bootstrapTab('show')
+ assert.strictEqual($('#qunit-fixture').find('.active').attr('id'), 'home')
+ })
+
QUnit.test('should not fire shown when show is prevented', function (assert) {
assert.expect(1)
var done = assert.async()
- $('<div class="tab"/>')
+ $('<div class="nav"/>')
.on('show.bs.tab', function (e) {
e.preventDefault()
assert.ok(true, 'show event fired')
@@ -166,7 +182,7 @@ $(function () {
assert.expect(2)
var done = assert.async()
- var dropHTML = '<ul class="drop">'
+ var dropHTML = '<ul class="drop nav">'
+ '<li class="dropdown"><a data-toggle="dropdown" href="#">1</a>'
+ '<ul class="dropdown-menu">'
+ '<li><a href="#1-1" data-toggle="tab">1-1</a></li>'
@@ -194,7 +210,7 @@ $(function () {
assert.expect(2)
var done = assert.async()
- var tabsHTML = '<ul class="tabs">'
+ var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@@ -225,7 +241,7 @@ $(function () {
assert.expect(1)
var done = assert.async()
- var tabsHTML = '<ul class="tabs">'
+ var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
@@ -250,7 +266,7 @@ $(function () {
assert.expect(2)
var done = assert.async()
- var tabsHTML = '<ul class="tabs">'
+ var tabsHTML = '<ul class="nav">'
+ '<li><a href="#home">Home</a></li>'
+ '<li><a href="#profile">Profile</a></li>'
+ '</ul>'
diff --git a/js/tests/unit/tooltip.js b/js/tests/unit/tooltip.js
index e1aec5551..c0cafefe5 100644
--- a/js/tests/unit/tooltip.js
+++ b/js/tests/unit/tooltip.js
@@ -111,7 +111,7 @@ $(function () {
assert
.ok($('.tooltip')
- .is('.fade.bs-tether-element-attached-top.bs-tether-element-attached-center.show'), 'has correct classes applied')
+ .is('.fade.bs-tooltip-bottom.show'), 'has correct classes applied')
$tooltip.bootstrapTooltip('hide')
@@ -364,32 +364,29 @@ $(function () {
})
QUnit.test('should add position class before positioning so that position-specific styles are taken into account', function (assert) {
- assert.expect(1)
+ assert.expect(2)
+ var done = assert.async()
var styles = '<style>'
- + '.tooltip.right { white-space: nowrap; }'
- + '.tooltip.right .tooltip-inner { max-width: none; }'
+ + '.bs-tooltip-right { white-space: nowrap; }'
+ + '.bs-tooltip-right .tooltip-inner { max-width: none; }'
+ '</style>'
var $styles = $(styles).appendTo('head')
var $container = $('<div/>').appendTo('#qunit-fixture')
- var $target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>')
+ $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>')
.appendTo($container)
.bootstrapTooltip({
- placement: 'right'
+ placement: 'right',
+ trigger: 'manual'
+ })
+ .on('inserted.bs.tooltip', function () {
+ var $tooltip = $($(this).data('bs.tooltip').tip)
+ assert.ok($tooltip.hasClass('bs-tooltip-right'))
+ assert.ok($tooltip.attr('style') === undefined)
+ $styles.remove()
+ done()
})
.bootstrapTooltip('show')
-
- var $tooltip = $($target.data('bs.tooltip').tip)
-
- // this is some dumb hack stuff because sub pixels in firefox
- var top = Math.round($target.offset().top + $target[0].offsetHeight / 2 - $tooltip[0].offsetHeight / 2)
- var top2 = Math.round($tooltip.offset().top)
- var topDiff = top - top2
- assert.ok(topDiff <= 1 && topDiff >= -1)
- $target.bootstrapTooltip('hide')
-
- $container.remove()
- $styles.remove()
})
QUnit.test('should use title attribute for tooltip text', function (assert) {
@@ -459,7 +456,7 @@ $(function () {
assert.expect(1)
var done = assert.async()
- var containerHTML = '<div>'
+ var containerHTML = '<div id="test">'
+ '<p style="margin-top: 200px">'
+ '<a href="#" title="very very very very very very very long tooltip">Hover me</a>'
+ '</p>'
@@ -476,21 +473,24 @@ $(function () {
})
.appendTo('#qunit-fixture')
- var $trigger = $container
+ $container
.find('a')
.css('margin-top', 200)
.bootstrapTooltip({
placement: 'top',
animate: false
})
+ .on('shown.bs.tooltip', function () {
+ var $tooltip = $($(this).data('bs.tooltip').tip)
+ if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
+ assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($(this).offset().top))
+ }
+ else {
+ assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) >= Math.round($(this).offset().top))
+ }
+ done()
+ })
.bootstrapTooltip('show')
-
- var $tooltip = $($trigger.data('bs.tooltip').tip)
-
- setTimeout(function () {
- assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
- done()
- }, 0)
})
QUnit.test('should show tooltip if leave event hasn\'t occurred before delay expires', function (assert) {
@@ -629,45 +629,6 @@ $(function () {
$tooltip.trigger('mouseenter')
})
- QUnit.test('should correctly position tooltips on SVG elements', function (assert) {
- if (!window.SVGElement) {
- // Skip IE8 since it doesn't support SVG
- assert.expect(0)
- return
- }
- assert.expect(2)
-
- var done = assert.async()
-
- var styles = '<style>'
- + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
- + '.tooltip { position: absolute; }'
- + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }'
- + '</style>'
- var $styles = $(styles).appendTo('head')
-
- $('#qunit-fixture').append(
- '<div style="position: fixed; top: 0; left: 0;">'
- + ' <svg width="200" height="200">'
- + ' <circle cx="100" cy="100" r="10" title="m" id="theCircle" />'
- + ' </svg>'
- + '</div>')
- var $circle = $('#theCircle')
-
- $circle
- .on('shown.bs.tooltip', function () {
- var offset = $('.tooltip').offset()
- $styles.remove()
- assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
- $circle.bootstrapTooltip('hide')
- assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
- done()
- })
- .bootstrapTooltip({ placement: 'top', trigger: 'manual' })
-
- $circle.bootstrapTooltip('show')
- })
-
QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) {
assert.expect(1)
var titleHtml = function () {
@@ -731,43 +692,6 @@ $(function () {
assert.strictEqual(currentUid, $('#tt-content').text())
})
- QUnit.test('should correctly position tooltips on transformed elements', function (assert) {
- var styleProps = document.documentElement.style
- if (!('transform' in styleProps) && !('webkitTransform' in styleProps) && !('msTransform' in styleProps)) {
- assert.expect(0)
- return
- }
- assert.expect(2)
-
- var done = assert.async()
-
- var styles = '<style>'
- + '#qunit-fixture { top: 0; left: 0; }'
- + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }'
- + '.tooltip { position: absolute; }'
- + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }'
- + '#target { position: absolute; top: 100px; left: 50px; width: 100px; height: 200px; -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); }'
- + '</style>'
- var $styles = $(styles).appendTo('head')
-
- var $element = $('<div id="target" title="1"/>').appendTo('#qunit-fixture')
-
- $element
- .on('shown.bs.tooltip', function () {
- var offset = $('.tooltip').offset()
- $styles.remove()
- assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location')
- assert.ok(Math.abs(offset.top - 126) <= 1, 'tooltip has correct vertical location')
- $element.bootstrapTooltip('hide')
- done()
- })
- .bootstrapTooltip({
- trigger: 'manual'
- })
-
- $element.bootstrapTooltip('show')
- })
-
QUnit.test('should do nothing when an attempt is made to hide an uninitialized tooltip', function (assert) {
assert.expect(1)
@@ -869,4 +793,37 @@ $(function () {
})
.modal('show')
})
+
+ QUnit.test('should reset tip classes when hidden event triggered', function (assert) {
+ assert.expect(2)
+ var done = assert.async()
+ var $el = $('<a href="#" rel="tooltip" title="Test tooltip"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip('show')
+ .on('hidden.bs.tooltip', function () {
+ var tooltip = $el.data('bs.tooltip')
+ var $tooltip = $(tooltip.getTipElement())
+ assert.ok($tooltip.hasClass('tooltip'))
+ assert.ok($tooltip.hasClass('fade'))
+ done()
+ })
+
+ $el.bootstrapTooltip('hide')
+ })
+
+ QUnit.test('should convert number in title to string', function (assert) {
+ assert.expect(1)
+ var done = assert.async()
+ var $el = $('<a href="#" rel="tooltip" title="7"/>')
+ .appendTo('#qunit-fixture')
+ .bootstrapTooltip('show')
+ .on('shown.bs.tooltip', function () {
+ var tooltip = $el.data('bs.tooltip')
+ var $tooltip = $(tooltip.getTipElement())
+ assert.strictEqual($tooltip.children().text(), '7')
+ done()
+ })
+
+ $el.bootstrapTooltip('show')
+ })
})