1
+ import { SPACE } from '@angular/cdk/keycodes' ;
1
2
import { waitForAsync , ComponentFixture , fakeAsync , TestBed , tick } from '@angular/core/testing' ;
2
3
import { Component , QueryList , ViewChild , ViewChildren } from '@angular/core' ;
3
4
import {
4
5
MAT_RIPPLE_GLOBAL_OPTIONS ,
5
6
RippleGlobalOptions ,
6
7
} from '@angular/material-experimental/mdc-core' ;
7
8
import { By } from '@angular/platform-browser' ;
8
- import { dispatchFakeEvent , dispatchMouseEvent } from '../../../cdk/testing/private' ;
9
+ import {
10
+ dispatchFakeEvent ,
11
+ dispatchKeyboardEvent ,
12
+ dispatchMouseEvent ,
13
+ } from '../../../cdk/testing/private' ;
9
14
import { Direction , Directionality } from '@angular/cdk/bidi' ;
10
15
import { Subject } from 'rxjs' ;
11
16
import { MatTabsModule } from '../module' ;
@@ -30,6 +35,7 @@ describe('MDC-based MatTabNavBar', () => {
30
35
TabLinkWithTabIndexBinding ,
31
36
TabLinkWithNativeTabindexAttr ,
32
37
TabBarWithInactiveTabsOnInit ,
38
+ TabBarWithPanel ,
33
39
] ,
34
40
providers : [
35
41
{ provide : MAT_RIPPLE_GLOBAL_OPTIONS , useFactory : ( ) => globalRippleOptions } ,
@@ -309,6 +315,123 @@ describe('MDC-based MatTabNavBar', () => {
309
315
expect ( instance . tabNavBar . selectedIndex ) . toBe ( 1 ) ;
310
316
} ) ;
311
317
318
+ describe ( 'without panel' , ( ) => {
319
+ let fixture : ComponentFixture < SimpleTabNavBarTestApp > ;
320
+
321
+ beforeEach ( ( ) => {
322
+ fixture = TestBed . createComponent ( SimpleTabNavBarTestApp ) ;
323
+ fixture . detectChanges ( ) ;
324
+ } ) ;
325
+
326
+ it ( 'should have no explicit roles' , ( ) => {
327
+ const tabBar = fixture . nativeElement . querySelector ( '.mat-mdc-tab-nav-bar' ) ! ;
328
+ expect ( tabBar . getAttribute ( 'role' ) ) . toBe ( null ) ;
329
+
330
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
331
+ expect ( tabLinks [ 0 ] . getAttribute ( 'role' ) ) . toBe ( null ) ;
332
+ expect ( tabLinks [ 1 ] . getAttribute ( 'role' ) ) . toBe ( null ) ;
333
+ expect ( tabLinks [ 2 ] . getAttribute ( 'role' ) ) . toBe ( null ) ;
334
+ } ) ;
335
+
336
+ it ( 'should not setup aria-controls' , ( ) => {
337
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
338
+ expect ( tabLinks [ 0 ] . getAttribute ( 'aria-controls' ) ) . toBe ( null ) ;
339
+ expect ( tabLinks [ 1 ] . getAttribute ( 'aria-controls' ) ) . toBe ( null ) ;
340
+ expect ( tabLinks [ 2 ] . getAttribute ( 'aria-controls' ) ) . toBe ( null ) ;
341
+ } ) ;
342
+
343
+ it ( 'should not manage aria-selected' , ( ) => {
344
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
345
+ expect ( tabLinks [ 0 ] . getAttribute ( 'aria-selected' ) ) . toBe ( null ) ;
346
+ expect ( tabLinks [ 1 ] . getAttribute ( 'aria-selected' ) ) . toBe ( null ) ;
347
+ expect ( tabLinks [ 2 ] . getAttribute ( 'aria-selected' ) ) . toBe ( null ) ;
348
+ } ) ;
349
+
350
+ it ( 'should not activate a link when space is pressed' , ( ) => {
351
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
352
+ expect ( tabLinks [ 1 ] . classList . contains ( 'mdc-tab--active' ) ) . toBe ( false ) ;
353
+
354
+ dispatchKeyboardEvent ( tabLinks [ 1 ] , 'keydown' , SPACE ) ;
355
+ fixture . detectChanges ( ) ;
356
+
357
+ expect ( tabLinks [ 1 ] . classList . contains ( 'mdc-tab--active' ) ) . toBe ( false ) ;
358
+ } ) ;
359
+ } ) ;
360
+
361
+ describe ( 'with panel' , ( ) => {
362
+ let fixture : ComponentFixture < TabBarWithPanel > ;
363
+
364
+ beforeEach ( ( ) => {
365
+ fixture = TestBed . createComponent ( TabBarWithPanel ) ;
366
+ fixture . detectChanges ( ) ;
367
+ } ) ;
368
+
369
+ it ( 'should have the proper roles' , ( ) => {
370
+ const tabBar = fixture . nativeElement . querySelector ( '.mat-mdc-tab-nav-bar' ) ! ;
371
+ expect ( tabBar . getAttribute ( 'role' ) ) . toBe ( 'tablist' ) ;
372
+
373
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
374
+ expect ( tabLinks [ 0 ] . getAttribute ( 'role' ) ) . toBe ( 'tab' ) ;
375
+ expect ( tabLinks [ 1 ] . getAttribute ( 'role' ) ) . toBe ( 'tab' ) ;
376
+ expect ( tabLinks [ 2 ] . getAttribute ( 'role' ) ) . toBe ( 'tab' ) ;
377
+
378
+ const tabPanel = fixture . nativeElement . querySelector ( '.mat-mdc-tab-nav-panel' ) ! ;
379
+ expect ( tabPanel . getAttribute ( 'role' ) ) . toBe ( 'tabpanel' ) ;
380
+ } ) ;
381
+
382
+ it ( 'should manage tabindex properly' , ( ) => {
383
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
384
+ expect ( tabLinks [ 0 ] . tabIndex ) . toBe ( 0 ) ;
385
+ expect ( tabLinks [ 1 ] . tabIndex ) . toBe ( - 1 ) ;
386
+ expect ( tabLinks [ 2 ] . tabIndex ) . toBe ( - 1 ) ;
387
+
388
+ tabLinks [ 1 ] . click ( ) ;
389
+ fixture . detectChanges ( ) ;
390
+
391
+ expect ( tabLinks [ 0 ] . tabIndex ) . toBe ( - 1 ) ;
392
+ expect ( tabLinks [ 1 ] . tabIndex ) . toBe ( 0 ) ;
393
+ expect ( tabLinks [ 2 ] . tabIndex ) . toBe ( - 1 ) ;
394
+ } ) ;
395
+
396
+ it ( 'should setup aria-controls properly' , ( ) => {
397
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
398
+ expect ( tabLinks [ 0 ] . getAttribute ( 'aria-controls' ) ) . toBe ( 'tab-panel' ) ;
399
+ expect ( tabLinks [ 1 ] . getAttribute ( 'aria-controls' ) ) . toBe ( 'tab-panel' ) ;
400
+ expect ( tabLinks [ 2 ] . getAttribute ( 'aria-controls' ) ) . toBe ( 'tab-panel' ) ;
401
+ } ) ;
402
+
403
+ it ( 'should not manage aria-current' , ( ) => {
404
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
405
+ expect ( tabLinks [ 0 ] . getAttribute ( 'aria-current' ) ) . toBe ( null ) ;
406
+ expect ( tabLinks [ 1 ] . getAttribute ( 'aria-current' ) ) . toBe ( null ) ;
407
+ expect ( tabLinks [ 2 ] . getAttribute ( 'aria-current' ) ) . toBe ( null ) ;
408
+ } ) ;
409
+
410
+ it ( 'should manage aria-selected properly' , ( ) => {
411
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
412
+ expect ( tabLinks [ 0 ] . getAttribute ( 'aria-selected' ) ) . toBe ( 'true' ) ;
413
+ expect ( tabLinks [ 1 ] . getAttribute ( 'aria-selected' ) ) . toBe ( 'false' ) ;
414
+ expect ( tabLinks [ 2 ] . getAttribute ( 'aria-selected' ) ) . toBe ( 'false' ) ;
415
+
416
+ tabLinks [ 1 ] . click ( ) ;
417
+ fixture . detectChanges ( ) ;
418
+
419
+ expect ( tabLinks [ 0 ] . getAttribute ( 'aria-selected' ) ) . toBe ( 'false' ) ;
420
+ expect ( tabLinks [ 1 ] . getAttribute ( 'aria-selected' ) ) . toBe ( 'true' ) ;
421
+ expect ( tabLinks [ 2 ] . getAttribute ( 'aria-selected' ) ) . toBe ( 'false' ) ;
422
+ } ) ;
423
+
424
+ it ( 'should activate a link when space is pressed' , ( ) => {
425
+ const tabLinks = fixture . nativeElement . querySelectorAll ( '.mat-mdc-tab-link' ) ;
426
+ expect ( tabLinks [ 1 ] . classList . contains ( 'mdc-tab--active' ) ) . toBe ( false ) ;
427
+
428
+ dispatchKeyboardEvent ( tabLinks [ 1 ] , 'keydown' , SPACE ) ;
429
+ fixture . detectChanges ( ) ;
430
+
431
+ expect ( tabLinks [ 1 ] . classList . contains ( 'mdc-tab--active' ) ) . toBe ( true ) ;
432
+ } ) ;
433
+ } ) ;
434
+
312
435
describe ( 'ripples' , ( ) => {
313
436
let fixture : ComponentFixture < SimpleTabNavBarTestApp > ;
314
437
@@ -532,3 +655,21 @@ class TabLinkWithNativeTabindexAttr {}
532
655
class TabBarWithInactiveTabsOnInit {
533
656
tabs = [ 0 , 1 , 2 ] ;
534
657
}
658
+
659
+ @Component ( {
660
+ template : `
661
+ <nav mat-tab-nav-bar [tabPanel]="tabPanel">
662
+ <a mat-tab-link
663
+ *ngFor="let tab of tabs; let index = index"
664
+ [active]="index === activeIndex"
665
+ (click)="activeIndex = index">
666
+ Tab link
667
+ </a>
668
+ </nav>
669
+ <mat-tab-nav-panel #tabPanel id="tab-panel">Tab panel</mat-tab-nav-panel>
670
+ ` ,
671
+ } )
672
+ class TabBarWithPanel {
673
+ tabs = [ 0 , 1 , 2 ] ;
674
+ activeIndex = 0 ;
675
+ }
0 commit comments