@@ -2,6 +2,8 @@ import {fakeAsync, async, tick, ComponentFixture, TestBed} from '@angular/core/t
22import { Component } from '@angular/core' ;
33import { By } from '@angular/platform-browser' ;
44import { MdSidenav , MdSidenavModule , MdSidenavToggleResult } from './sidenav' ;
5+ import { A11yModule } from '../core/a11y/index' ;
6+ import { PlatformModule } from '../core/platform/platform' ;
57
68
79function endSidenavTransition ( fixture : ComponentFixture < any > ) {
@@ -15,17 +17,17 @@ function endSidenavTransition(fixture: ComponentFixture<any>) {
1517
1618
1719describe ( 'MdSidenav' , ( ) => {
18-
1920 beforeEach ( async ( ( ) => {
2021 TestBed . configureTestingModule ( {
21- imports : [ MdSidenavModule . forRoot ( ) ] ,
22+ imports : [ MdSidenavModule . forRoot ( ) , A11yModule . forRoot ( ) , PlatformModule . forRoot ( ) ] ,
2223 declarations : [
2324 BasicTestApp ,
2425 SidenavLayoutTwoSidenavTestApp ,
2526 SidenavLayoutNoSidenavTestApp ,
2627 SidenavSetToOpenedFalse ,
2728 SidenavSetToOpenedTrue ,
2829 SidenavDynamicAlign ,
30+ SidenavWitFocusableElements ,
2931 ] ,
3032 } ) ;
3133
@@ -236,7 +238,6 @@ describe('MdSidenav', () => {
236238 } ) ;
237239
238240 describe ( 'attributes' , ( ) => {
239-
240241 it ( 'should correctly parse opened="false"' , ( ) => {
241242 let fixture = TestBed . createComponent ( SidenavSetToOpenedFalse ) ;
242243 fixture . detectChanges ( ) ;
@@ -290,6 +291,55 @@ describe('MdSidenav', () => {
290291 } ) ;
291292 } ) ;
292293
294+ describe ( 'focus trapping behavior' , ( ) => {
295+ let fixture : ComponentFixture < SidenavWitFocusableElements > ;
296+ let testComponent : SidenavWitFocusableElements ;
297+ let sidenav : MdSidenav ;
298+ let firstFocusableElement : HTMLElement ;
299+ let lastFocusableElement : HTMLElement ;
300+
301+ beforeEach ( ( ) => {
302+ fixture = TestBed . createComponent ( SidenavWitFocusableElements ) ;
303+ testComponent = fixture . debugElement . componentInstance ;
304+ sidenav = fixture . debugElement . query ( By . directive ( MdSidenav ) ) . componentInstance ;
305+ firstFocusableElement = fixture . debugElement . query ( By . css ( '.link1' ) ) . nativeElement ;
306+ lastFocusableElement = fixture . debugElement . query ( By . css ( '.link1' ) ) . nativeElement ;
307+ lastFocusableElement . focus ( ) ;
308+ } ) ;
309+
310+ it ( 'should trap focus when opened in "over" mode' , fakeAsync ( ( ) => {
311+ testComponent . mode = 'over' ;
312+ lastFocusableElement . focus ( ) ;
313+
314+ sidenav . open ( ) ;
315+ endSidenavTransition ( fixture ) ;
316+ tick ( ) ;
317+
318+ expect ( document . activeElement ) . toBe ( firstFocusableElement ) ;
319+ } ) ) ;
320+
321+ it ( 'should trap focus when opened in "push" mode' , fakeAsync ( ( ) => {
322+ testComponent . mode = 'push' ;
323+ lastFocusableElement . focus ( ) ;
324+
325+ sidenav . open ( ) ;
326+ endSidenavTransition ( fixture ) ;
327+ tick ( ) ;
328+
329+ expect ( document . activeElement ) . toBe ( firstFocusableElement ) ;
330+ } ) ) ;
331+
332+ it ( 'should not trap focus when opened in "side" mode' , fakeAsync ( ( ) => {
333+ testComponent . mode = 'side' ;
334+ lastFocusableElement . focus ( ) ;
335+
336+ sidenav . open ( ) ;
337+ endSidenavTransition ( fixture ) ;
338+ tick ( ) ;
339+
340+ expect ( document . activeElement ) . toBe ( lastFocusableElement ) ;
341+ } ) ) ;
342+ } ) ;
293343} ) ;
294344
295345
@@ -381,3 +431,16 @@ class SidenavDynamicAlign {
381431 sidenav1Align = 'start' ;
382432 sidenav2Align = 'end' ;
383433}
434+
435+ @Component ( {
436+ template : `
437+ <md-sidenav-layout>
438+ <md-sidenav align="start" [mode]="mode">
439+ <a class="link1" href="#">link1</a>
440+ </md-sidenav>
441+ <a class="link2" href="#">link2</a>
442+ </md-sidenav-layout>` ,
443+ } )
444+ class SidenavWitFocusableElements {
445+ mode : string = 'over' ;
446+ }
0 commit comments