diff --git a/src/modules/tabs/fixtures/tabset.component.fixture.html b/src/modules/tabs/fixtures/tabset.component.fixture.html index fa2b0ae95..046851583 100644 --- a/src/modules/tabs/fixtures/tabset.component.fixture.html +++ b/src/modules/tabs/fixtures/tabset.component.fixture.html @@ -23,6 +23,7 @@ *ngIf="tab3Available" [tabHeading]="tab3Heading" [tabHeaderCount]="tab3HeaderCount" + [tabIndex]="3" [active]="activeTab === 2" >
diff --git a/src/modules/tabs/tabset.component.spec.ts b/src/modules/tabs/tabset.component.spec.ts index 350b85acb..294386395 100644 --- a/src/modules/tabs/tabset.component.spec.ts +++ b/src/modules/tabs/tabset.component.spec.ts @@ -2,7 +2,8 @@ import { ComponentFixture, TestBed, fakeAsync, - tick + tick, + async } from '@angular/core/testing'; import { @@ -33,7 +34,7 @@ describe('Tabset component', () => { }); }); - function validateTabSelected(el: Element, tabIndex: number) { + function validateTabSelected(el: Element, tabIndex: number, content?: string) { let selectedCls: string; let buttonEls: NodeListOf; let inDropDownMode = el.querySelector('.sky-tabset-mode-dropdown'); @@ -43,7 +44,7 @@ describe('Tabset component', () => { buttonEls = el.querySelectorAll('.sky-tab-dropdown-item'); } else { selectedCls = 'sky-btn-tab-selected'; - buttonEls = el.querySelectorAll('.sky-tab-button'); + buttonEls = el.querySelectorAll('.sky-btn-tab'); } let contentEls = el.querySelectorAll('.sky-tab'); @@ -69,6 +70,9 @@ describe('Tabset component', () => { expect(buttonEl.getAttribute('aria-selected')).toBe(expectedHasClass.toString()); } } + if (content) { + expect(contentEls[tabIndex]).toHaveText(content); + } } it('should initialize tabs in proper order', fakeAsync(() => { @@ -82,24 +86,36 @@ describe('Tabset component', () => { }); })); - it('should initialize tabs that are added to the tabset after init', fakeAsync(() => { + it('should initialize tabs that are added to the tabset after init', async(() => { let fixture = TestBed.createComponent(TabsetTestComponent); + fixture.componentInstance.tab3Content = 'test content'; fixture.componentInstance.tab3Available = false; fixture.detectChanges(); - tick(); - fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); - let tabsetService: SkyTabsetService = (fixture.componentInstance.tabsetComponent as any).tabsetService; - expect(tabsetService.tabs.getValue().length).toBe(2); + let tabsetService: SkyTabsetService = (fixture.componentInstance.tabsetComponent as any).tabsetService; + expect(tabsetService.tabs.getValue().length).toBe(2); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.componentInstance.tab3Available = true; + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.nativeElement.querySelectorAll('.sky-btn-tab')[2].click(); - fixture.componentInstance.tab3Available = true; - fixture.detectChanges(); - tick(); - fixture.detectChanges(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); - expect(tabsetService.tabs.getValue().length).toBe(3); - fixture.componentInstance.tabsetComponent.tabs.forEach((item, index) => { - expect(item).toBe(tabsetService.tabs.getValue()[index]); + validateTabSelected(fixture.nativeElement, 2, fixture.componentInstance.tab3Content); + + expect(tabsetService.tabs.getValue().length).toBe(3); + fixture.componentInstance.tabsetComponent.tabs.forEach((item, index) => { + expect(item).toBe(tabsetService.tabs.value[index]); + }); + }); + }); + }); }); })); @@ -132,18 +148,20 @@ describe('Tabset component', () => { validateTabSelected(el, 2); })); - it('should change the active tab when the tab is clicked manually', () => { + it('should change the active tab when the tab is clicked manually', fakeAsync(() => { let fixture = TestBed.createComponent(TabsetTestComponent); let el = fixture.nativeElement; fixture.detectChanges(); + tick(); el.querySelectorAll('.sky-btn-tab')[1].click(); fixture.detectChanges(); + tick(); validateTabSelected(el, 1); - }); + })); it('should not change the active tab when a disabled tab is clicked', () => { let fixture = TestBed.createComponent(TabsetTestComponent); @@ -246,56 +264,70 @@ describe('Tabset component', () => { expect(closeTabSpy).toHaveBeenCalled(); }); - it('should select the next tab when the active tab is closed', () => { + it('should select the next tab when the active tab is closed', fakeAsync(() => { let fixture = TestBed.createComponent(TabsetTestComponent); let cmp: TabsetTestComponent = fixture.componentInstance; let el = fixture.nativeElement; + fixture.detectChanges(); + tick(); cmp.activeTab = 1; fixture.detectChanges(); + tick(); cmp.tab2Available = false; fixture.detectChanges(); + tick(); expect(el.querySelectorAll('.sky-btn-tab').length).toBe(2); validateTabSelected(el, 1); - }); + })); it( 'should select the previous tab when the last tab is closed and the last tab was active', - () => { + fakeAsync(() => { let fixture = TestBed.createComponent(TabsetTestComponent); let cmp: TabsetTestComponent = fixture.componentInstance; let el = fixture.nativeElement; + fixture.detectChanges(); + tick(); cmp.activeTab = 2; fixture.detectChanges(); + tick(); cmp.tab3Available = false; fixture.detectChanges(); + tick(); expect(el.querySelectorAll('.sky-btn-tab').length).toBe(2); validateTabSelected(el, 1); } - ); + )); it( 'should maintain the currently active tab when a non-active tab is closed', - () => { + fakeAsync(() => { let fixture = TestBed.createComponent(TabsetTestComponent); let cmp: TabsetTestComponent = fixture.componentInstance; let el = fixture.nativeElement; + cmp.tab3Content = 'tab 3 content'; + fixture.detectChanges(); + tick(); cmp.activeTab = 2; fixture.detectChanges(); + tick(); + validateTabSelected(el, 2, 'tab 3 content'); cmp.tab2Available = false; fixture.detectChanges(); + tick(); expect(el.querySelectorAll('.sky-btn-tab').length).toBe(2); - validateTabSelected(el, 2); + validateTabSelected(el, 1, 'tab 3 content'); } - ); + )); it( 'should display count in tab when tabHeaderCount is defined', @@ -388,7 +420,7 @@ describe('Tabset component', () => { ); it( - 'should collapse into a dropdown on initialization', + 'should collapse into a dropdown on initialization', fakeAsync(() => { let fixture = TestBed.createComponent(TabsetTestComponent); @@ -404,7 +436,7 @@ describe('Tabset component', () => { expect(tabEl).not.toBeNull(); } - )); + )); describe('when collapsed', () => { let fixture: ComponentFixture; @@ -451,33 +483,33 @@ describe('Tabset component', () => { ); it('should allow another tab to be selected from the dropdown', fakeAsync(() => { - let el = fixture.nativeElement; + let el = fixture.nativeElement; - fixture.detectChanges(); - tick(); + fixture.detectChanges(); + tick(); - mockAdapterService.fakeOverflowChange(true); + mockAdapterService.fakeOverflowChange(true); - fixture.detectChanges(); - tick(); + fixture.detectChanges(); + tick(); - let tabEl = el.querySelector('.sky-dropdown-button-type-tab'); + let tabEl = el.querySelector('.sky-dropdown-button-type-tab'); - tabEl.click(); - tick(); - fixture.detectChanges(); - tick(); + tabEl.click(); + tick(); + fixture.detectChanges(); + tick(); - let dropdownTabButtons = el.querySelectorAll('.sky-tab-dropdown-item-btn'); - expect(dropdownTabButtons[1]).toHaveText('Tab 2'); + let dropdownTabButtons = el.querySelectorAll('.sky-tab-dropdown-item-btn'); + expect(dropdownTabButtons[1]).toHaveText('Tab 2'); - dropdownTabButtons[1].click(); - tick(); - fixture.detectChanges(); - tick(); + dropdownTabButtons[1].click(); + tick(); + fixture.detectChanges(); + tick(); - validateTabSelected(el, 1); - } + validateTabSelected(el, 1); + } )); it( @@ -524,7 +556,7 @@ describe('Tabset component', () => { validateTabSelected(el, 0); } - )); + )); it( 'should notify the consumer when a tab\'s close button is clicked', @@ -576,7 +608,7 @@ describe('Tabset component', () => { fixture.detectChanges(); tick(); cmp.activeIndex = 1; - fixture.detectChanges(); + fixture.detectChanges(); tick(); fixture.detectChanges(); tick(); @@ -625,6 +657,8 @@ describe('Tabset component', () => { let fixture = TestBed.createComponent(TabsetActiveTestComponent); let cmp: TabsetActiveTestComponent = fixture.componentInstance; let el = fixture.nativeElement; + cmp.tab1Content = 'tab 1 content'; + cmp.tab3Content = 'tab 3 content'; fixture.detectChanges(); tick(); @@ -642,7 +676,7 @@ describe('Tabset component', () => { tick(); fixture.detectChanges(); tick(); - validateTabSelected(el, 2); + validateTabSelected(el, 1, 'tab 3 content'); el.querySelectorAll('.sky-btn-tab')[0].click(); @@ -651,7 +685,7 @@ describe('Tabset component', () => { fixture.detectChanges(); tick(); expect(cmp.activeIndex).toBe(0); - validateTabSelected(el, 0); + validateTabSelected(el, 0, 'tab 1 content'); })); it('handles initialized tabs', fakeAsync(() => { @@ -704,7 +738,7 @@ describe('Tabset component', () => { }); }); - describe('keyboard accessibility', () => { + describe('keyboard accessibility', () => { let debugElement: DebugElement; let fixture: ComponentFixture; @@ -775,19 +809,23 @@ describe('Tabset component', () => { }); })); - it('should emit a click event on enter press', () => { + it('should emit a click event on enter press', fakeAsync(() => { fixture.detectChanges(); + tick(); fixture.detectChanges(); - let el = debugElement.queryAll(By.css('.sky-btn-tab'))[1]; + tick(); + let el = debugElement.queryAll(By.css('.sky-btn-tab'))[1]; - el.triggerEventHandler('keydown', { keyCode: 15}); + el.triggerEventHandler('keydown', { keyCode: 15 }); fixture.detectChanges(); + tick(); validateTabSelected(fixture.nativeElement, 0); - el.triggerEventHandler('keydown', { keyCode: 13}); + el.triggerEventHandler('keydown', { keyCode: 13 }); fixture.detectChanges(); + tick(); validateTabSelected(fixture.nativeElement, 1); } - ); + )); }); }); diff --git a/src/modules/tabs/tabset.component.ts b/src/modules/tabs/tabset.component.ts index 21072e9ae..a6b2af2d8 100644 --- a/src/modules/tabs/tabset.component.ts +++ b/src/modules/tabs/tabset.component.ts @@ -95,8 +95,10 @@ export class SkyTabsetComponent // initialize each tab's index. (in case tabs are instantiated out of order) this.tabs.forEach(item => item.initializeTabIndex()); this.tabs.changes.subscribe((change: QueryList) => { - change.filter(tab => tab.tabIndex === undefined) - .forEach(item => item.initializeTabIndex()); + this.tabsetService.tabs.take(1).subscribe(currentTabs => { + change.filter(tab => currentTabs.indexOf(tab) < 0) + .forEach(item => item.initializeTabIndex()); + }); }); if (this.active || this.active === 0) {