bootstrap-vue
Version:
BootstrapVue, with over 40 plugins and more than 80 custom components, custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-AR
788 lines (673 loc) • 25.1 kB
JavaScript
import Vue from 'vue'
import { mount } from '@vue/test-utils'
import { waitNT, waitRAF } from '../../../tests/utils'
import { BLink } from '../link/link'
import { BTab } from './tab'
import { BTabs } from './tabs'
describe('tabs', () => {
it('default has expected classes and structure', async () => {
const wrapper = mount(BTabs)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
expect(wrapper.is('div')).toBe(true)
expect(wrapper.classes()).toContain('tabs')
expect(wrapper.classes()).not.toContain('row')
expect(wrapper.classes()).not.toContain('no-gutters')
expect(wrapper.attributes('id')).toBeDefined()
wrapper.destroy()
})
it('default has expected data state', async () => {
const wrapper = mount(BTabs)
expect(wrapper.vm.currentTab).toBe(-1)
expect(wrapper.vm.tabs.length).toBe(0)
wrapper.destroy()
})
it('has correct card classes when prop card is true', async () => {
const wrapper = mount(BTabs, {
propsData: { card: true },
slots: { default: [BTab, BTab, BTab] }
})
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
expect(wrapper.is('div')).toBe(true)
expect(wrapper.classes()).toContain('tabs')
expect(wrapper.findAll('.card-header').length).toBe(1)
expect(wrapper.findAll('ul').length).toBe(1)
expect(wrapper.find('ul').classes()).toContain('nav')
expect(wrapper.find('ul').classes()).toContain('nav-tabs')
expect(wrapper.find('ul').classes()).toContain('card-header-tabs')
wrapper.destroy()
})
it('has correct card classes when props card and vertical are true', async () => {
const wrapper = mount(BTabs, {
propsData: { card: true, vertical: true },
slots: { default: [BTab, BTab, BTab] }
})
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
expect(wrapper.is('div')).toBe(true)
expect(wrapper.classes()).toContain('tabs')
expect(wrapper.classes()).toContain('row')
expect(wrapper.classes()).toContain('no-gutters')
expect(wrapper.findAll('.card-header').length).toBe(1)
expect(wrapper.findAll('ul').length).toBe(1)
expect(wrapper.find('ul').classes()).toContain('nav')
expect(wrapper.find('ul').classes()).toContain('nav-tabs')
expect(wrapper.find('ul').classes()).toContain('card-header')
expect(wrapper.find('ul').classes()).toContain('flex-column')
expect(wrapper.find('ul').classes()).toContain('h-100')
expect(wrapper.find('ul').classes()).toContain('border-bottom-0')
expect(wrapper.find('ul').classes()).toContain('rounded-0')
expect(wrapper.findAll('.tab-content.col').length).toBe(1)
expect(wrapper.findAll('.col-auto').length).toBe(1)
wrapper.destroy()
})
it('sets correct tab active for initial value', async () => {
const tabIndex = 1
const wrapper = mount(BTabs, {
propsData: { value: tabIndex },
slots: { default: [BTab, BTab, BTab] }
})
await waitNT(wrapper.vm)
await waitRAF()
expect(wrapper.vm.currentTab).toBe(tabIndex)
expect(wrapper.vm.tabs.length).toBe(3)
expect(wrapper.vm.tabs[tabIndex].localActive).toBe(true)
wrapper.destroy()
})
it('sets correct tab active when first tab is disabled', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, {}, [
h(BTab, { props: { disabled: true } }, 'tab 0'),
h(BTab, { props: {} }, 'tab 1'),
h(BTab, { props: {} }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 2nd tab (index 1) to be active
expect(tabs.vm.currentTab).toBe(1)
expect(tabs.vm.tabs[1].localActive).toBe(true)
expect(tabs.emitted('input')).toBeDefined()
expect(tabs.emitted('input').length).toBe(1)
// Should emit index of 1 (2nd tab)
expect(tabs.emitted('input')[0][0]).toBe(1)
wrapper.destroy()
})
it('sets current index based on active prop of b-tab', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, {}, [
h(BTab, { props: { active: false } }, 'tab 0'),
h(BTab, { props: { active: true } }, 'tab 1'),
h(BTab, { props: { active: false } }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 2nd tab (index 1) to be active
expect(tabs.vm.currentTab).toBe(1)
expect(tabs.vm.tabs[1].localActive).toBe(true)
expect(tabs.emitted('input')).toBeDefined()
expect(tabs.emitted('input').length).toBe(1)
// Should emit index of 1 (2nd tab)
expect(tabs.emitted('input')[0][0]).toBe(1)
wrapper.destroy()
})
it('selects first non-disabled tab when active tab disabled', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, {}, [
h(BTab, { props: { active: false, disabled: true } }, 'tab 0'),
h(BTab, { props: { active: true } }, 'tab 1'),
h(BTab, { props: { active: false } }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 2nd tab (index 1) to be active
expect(tabs.vm.currentTab).toBe(1)
expect(tabs.findAll(BTab).at(0).vm.localActive).toBe(false)
expect(tabs.findAll(BTab).at(1).vm.localActive).toBe(true)
expect(tabs.findAll(BTab).at(2).vm.localActive).toBe(false)
expect(tabs.emitted('input')).toBeDefined()
expect(tabs.emitted('input').length).toBe(1)
// Should emit index of 1 (2nd tab)
expect(tabs.emitted('input')[0][0]).toBe(1)
// Deactivate current tab (BTab 2, index 1)
tabs
.findAll(BTab)
.at(1)
.setProps({ active: false })
await waitNT(wrapper.vm)
await waitRAF()
// Expect last tab (index 2) to be active
expect(tabs.vm.currentTab).toBe(2)
expect(tabs.findAll(BTab).at(0).vm.localActive).toBe(false)
expect(tabs.findAll(BTab).at(1).vm.localActive).toBe(false)
expect(tabs.findAll(BTab).at(2).vm.localActive).toBe(true)
expect(tabs.emitted('input').length).toBe(2)
expect(tabs.emitted('input')[1][0]).toBe(2)
wrapper.destroy()
})
it('v-model works', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0 } }, [
h(BTab, { props: {} }, 'tab 0'),
h(BTab, { props: {} }, 'tab 1'),
h(BTab, { props: {} }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tabs.vm.tabs[0].localActive).toBe(true)
// It should not emit an input event as the value is the same
expect(tabs.emitted('input')).not.toBeDefined()
// Set 2nd BTab to be active
tabs.setProps({ value: 1 })
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tabs.emitted('input').length).toBe(1)
// Should emit index of 1 (2nd tab)
expect(tabs.emitted('input')[0][0]).toBe(1)
// Set 3rd BTab to be active
tabs.setProps({ value: 2 })
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(2)
expect(tabs.emitted('input').length).toBe(2)
// Should emit index of 2 (3rd tab)
expect(tabs.emitted('input')[1][0]).toBe(2)
wrapper.destroy()
})
it('v-model works when trying to activate a disabled tab', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0 } }, [
h(BTab, { props: {} }, 'tab 0'),
h(BTab, { props: { disabled: true } }, 'tab 1'),
h(BTab, { props: {} }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tabs.vm.tabs[0].localActive).toBe(true)
expect(tabs.emitted('input')).not.toBeDefined()
// Try to set 2nd (disabled) BTab to be active
tabs.setProps({ value: 1 })
await waitNT(wrapper.vm)
await waitRAF()
// Will try activate next non-disabled tab instead (3rd tab, index 2)
expect(tabs.vm.currentTab).toBe(2)
expect(tabs.emitted('input').length).toBe(1)
// Should emit index of 2 (3rd tab)
expect(tabs.emitted('input')[0][0]).toBe(2)
// Needed for test since value not bound to actual v-model on App
tabs.setProps({ value: 2 })
await waitNT(wrapper.vm)
await waitRAF()
// Try and set 2nd BTab to be active
tabs.setProps({ value: 1 })
await waitNT(wrapper.vm)
await waitRAF()
// Will find the previous non-disabled tab (1st tab, index 0)
expect(tabs.vm.currentTab).toBe(0)
expect(tabs.emitted('input').length).toBe(2)
// Should emit index of 0 (1st tab)
expect(tabs.emitted('input')[1][0]).toBe(0)
wrapper.destroy()
})
it('`activate-tab` event works', async () => {
const App = Vue.extend({
methods: {
preventTab(next, prev, bvEvt) {
// Prevent 3rd tab (index === 2) from activating
if (next === 2) {
bvEvt.preventDefault()
}
}
},
render(h) {
return h(BTabs, { props: { value: 0 }, on: { 'activate-tab': this.preventTab } }, [
h(BTab, { props: {} }, 'tab 0'),
h(BTab, { props: {} }, 'tab 1'),
h(BTab, { props: {} }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tabs.vm.tabs[0].localActive).toBe(true)
expect(tabs.emitted('input')).not.toBeDefined()
expect(tabs.emitted('activate-tab')).not.toBeDefined()
// Set 2nd BTab to be active
tabs.setProps({ value: 1 })
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tabs.emitted('input')).toBeDefined()
expect(tabs.emitted('input').length).toBe(1)
expect(tabs.emitted('input')[0][0]).toBe(1)
expect(tabs.emitted('activate-tab')).toBeDefined()
expect(tabs.emitted('activate-tab').length).toBe(1)
expect(tabs.emitted('activate-tab')[0][0]).toBe(1)
expect(tabs.emitted('activate-tab')[0][1]).toBe(0)
expect(tabs.emitted('activate-tab')[0][2]).toBeDefined()
expect(tabs.emitted('activate-tab')[0][2].vueTarget).toBe(tabs.vm)
// Attempt to set 3rd BTab to be active
tabs.setProps({ value: 2 })
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tabs.emitted('input')).toBeDefined()
expect(tabs.emitted('input').length).toBe(2)
expect(tabs.emitted('input')[1][0]).toBe(1)
expect(tabs.emitted('activate-tab').length).toBe(2)
expect(tabs.emitted('activate-tab')[1][0]).toBe(2)
expect(tabs.emitted('activate-tab')[1][1]).toBe(1)
expect(tabs.emitted('activate-tab')[1][2]).toBeDefined()
expect(tabs.emitted('activate-tab')[1][2].vueTarget).toBe(tabs.vm)
expect(tabs.emitted('activate-tab')[1][2].defaultPrevented).toBe(true)
wrapper.destroy()
})
it('clicking on tab activates the tab, and tab emits click event', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0 } }, [
h(BTab, { props: { title: 'one' } }, 'tab 0'),
h(BTab, { props: { title: 'two' } }, 'tab 1'),
h(BTab, { props: { title: 'three' } }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
const tab1 = tabs.findAll(BTab).at(0)
const tab2 = tabs.findAll(BTab).at(1)
const tab3 = tabs.findAll(BTab).at(2)
expect(wrapper.findAll('.nav-link')).toBeDefined()
expect(wrapper.findAll('.nav-link').length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
// Try to set 2nd BTab to be active via click
expect(tab2.emitted('click')).not.toBeDefined()
wrapper
.findAll('.nav-link')
.at(1)
.trigger('click')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(true)
expect(tab3.vm.localActive).toBe(false)
expect(tab2.emitted('click')).toBeDefined()
// Try to set 3rd BTab to be active via click
expect(tab3.emitted('click')).not.toBeDefined()
wrapper
.findAll('.nav-link')
.at(2)
.trigger('click')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(2)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(true)
expect(tab3.emitted('click')).toBeDefined()
// Try to set 1st BTab to be active via click (space === click in keynav mode)
expect(tab1.emitted('click')).not.toBeDefined()
wrapper
.findAll('.nav-link')
.at(0)
.trigger('keydown.space')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
expect(tab1.emitted('click')).toBeDefined()
wrapper.destroy()
})
it('pressing space on tab activates the tab, and tab emits click event', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0, noKeyNav: true } }, [
h(BTab, { props: { title: 'one' } }, 'tab 0'),
h(BTab, { props: { title: 'two' } }, 'tab 1'),
h(BTab, { props: { title: 'three' } }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
const tab1 = tabs.findAll(BTab).at(0)
const tab2 = tabs.findAll(BTab).at(1)
const tab3 = tabs.findAll(BTab).at(2)
expect(wrapper.findAll('.nav-link')).toBeDefined()
expect(wrapper.findAll('.nav-link').length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
// Try to set 2nd BTab to be active via space keypress
expect(tab2.emitted('click')).not.toBeDefined()
wrapper
.findAll('.nav-link')
.at(1)
.trigger('keydown.space')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(true)
expect(tab3.vm.localActive).toBe(false)
expect(tab2.emitted('click')).toBeDefined()
// Try to set 3rd BTab to be active via space keypress
expect(tab3.emitted('click')).not.toBeDefined()
wrapper
.findAll('.nav-link')
.at(2)
.trigger('keydown.space')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(2)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(true)
expect(tab3.emitted('click')).toBeDefined()
// Try to set 1st BTab to be active via space keypress
expect(tab1.emitted('click')).not.toBeDefined()
wrapper
.findAll('.nav-link')
.at(0)
.trigger('keydown.space')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
expect(tab1.emitted('click')).toBeDefined()
wrapper.destroy()
})
it('key nav works', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0 } }, [
h(BTab, { props: { title: 'one' } }, 'tab 0'),
h(BTab, { props: { title: 'two' } }, 'tab 1'),
h(BTab, { props: { title: 'three' } }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
const tab1 = tabs.findAll(BTab).at(0)
const tab2 = tabs.findAll(BTab).at(1)
const tab3 = tabs.findAll(BTab).at(2)
expect(wrapper.findAll('.nav-link')).toBeDefined()
expect(wrapper.findAll('.nav-link').length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
// RIGHT moves to next tab
wrapper
.findAll(BLink)
.at(0)
.trigger('keydown.right')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(true)
expect(tab3.vm.localActive).toBe(false)
// END key moves to last tab
wrapper
.findAll(BLink)
.at(1)
.trigger('keydown.end')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(2)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(true)
// LEFT moves to previous tab
wrapper
.findAll(BLink)
.at(2)
.trigger('keydown.left')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(true)
expect(tab3.vm.localActive).toBe(false)
// HOME moves to first tab
wrapper
.findAll(BLink)
.at(1)
.trigger('keydown.home')
await waitNT(wrapper.vm)
await waitRAF()
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
wrapper.destroy()
})
it('disabling active tab selects first non-disabled tab', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 2 } }, [
h(BTab, { props: { title: 'one' } }, 'tab 0'),
h(BTab, { props: { title: 'two' } }, 'tab 1'),
h(BTab, { props: { title: 'three', disabled: false } }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
const tab1 = tabs.findAll(BTab).at(0)
const tab2 = tabs.findAll(BTab).at(1)
const tab3 = tabs.findAll(BTab).at(2)
// Expect 3rd tab (index 2) to be active
expect(tabs.vm.currentTab).toBe(2)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(true)
// Disable 3rd tab
tab3.setProps({ disabled: true })
await waitNT(wrapper.vm)
await waitRAF()
// Expect 1st tab to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tab1.vm.localActive).toBe(true)
expect(tab2.vm.localActive).toBe(false)
expect(tab3.vm.localActive).toBe(false)
// Enable 3rd tab and Disable 1st tab
tab3.setProps({ disabled: false })
tab1.setProps({ disabled: true })
await waitNT(wrapper.vm)
await waitRAF()
// Expect 2nd tab to be active
expect(tabs.vm.currentTab).toBe(1)
expect(tab1.vm.localActive).toBe(false)
expect(tab2.vm.localActive).toBe(true)
expect(tab3.vm.localActive).toBe(false)
wrapper.destroy()
})
it('tab title slots are reactive', async () => {
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 2 } }, [
h(BTab, { props: { title: 'original' } }, 'tab content')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await waitNT(wrapper.vm)
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(1)
// Expect tab button content to be `original`
expect(wrapper.find('.nav-link').text()).toBe('original')
// Get the BTab's instance
const tabVm = wrapper.find(BTab).vm
expect(tabVm).toBeDefined()
// Change title slot content
tabVm.$slots.title = [tabVm.$createElement('span', {}, 'foobar')]
tabVm.$forceUpdate()
await waitNT(wrapper.vm)
await waitRAF()
// Expect tab button content to be `foobar`
expect(wrapper.find('.nav-link').text()).toBe('foobar')
wrapper.destroy()
})
it('"active-nav-item-class" is applied to active nav item', async () => {
const activeNavItemClass = 'text-success'
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0, activeNavItemClass } }, [
h(BTab, { props: {} }, 'tab 0'),
h(BTab, { props: {} }, 'tab 1'),
h(BTab, { props: {} }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await wrapper.vm.$nextTick()
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
const getNavItemByTab = tab => wrapper.find(`#${tab.$el.id}___BV_tab_button__`)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tabs.vm.tabs[0].localActive).toBe(true)
// Expect 1st tabs nav item to have "active-nav-item-class" applied
expect(getNavItemByTab(tabs.vm.tabs[0]).classes(activeNavItemClass)).toBe(true)
// Set 2nd tab to be active
tabs.setProps({ value: 1 })
await wrapper.vm.$nextTick()
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
// Expect 2nd tabs nav item to have "active-nav-item-class" applied
expect(getNavItemByTab(tabs.vm.tabs[1]).classes(activeNavItemClass)).toBe(true)
// Expect 1st tabs nav item to don't have "active-nav-item-class" applied anymore
expect(getNavItemByTab(tabs.vm.tabs[0]).classes(activeNavItemClass)).toBe(false)
wrapper.destroy()
})
it('"active-tab-class" is applied to active tab', async () => {
const activeTabClass = 'text-success'
const App = Vue.extend({
render(h) {
return h(BTabs, { props: { value: 0, activeTabClass } }, [
h(BTab, { props: {} }, 'tab 0'),
h(BTab, { props: {} }, 'tab 1'),
h(BTab, { props: {} }, 'tab 2')
])
}
})
const wrapper = mount(App)
expect(wrapper).toBeDefined()
await wrapper.vm.$nextTick()
await waitRAF()
const tabs = wrapper.find(BTabs)
expect(tabs).toBeDefined()
expect(tabs.findAll(BTab).length).toBe(3)
// Expect 1st tab (index 0) to be active
expect(tabs.vm.currentTab).toBe(0)
expect(tabs.vm.tabs[0].localActive).toBe(true)
// Expect 1st tab to have "active-tab-class" applied
expect(tabs.vm.tabs[0].$el.classList.contains(activeTabClass)).toBe(true)
// Set 2nd tab to be active
tabs.setProps({ value: 1 })
await wrapper.vm.$nextTick()
await waitRAF()
expect(tabs.vm.currentTab).toBe(1)
// Expect 2nd tab to have "active-tab-class" applied
expect(tabs.vm.tabs[1].$el.classList.contains(activeTabClass)).toBe(true)
// Expect 1st tab to don't have "active-tab-class" applied anymore
expect(tabs.vm.tabs[0].$el.classList.contains(activeTabClass)).toBe(false)
wrapper.destroy()
})
})