@@ -25,6 +25,7 @@ import {SpyLocation} from '@angular/common/testing';
25
25
import { Directionality } from '@angular/cdk/bidi' ;
26
26
import { MatDialogContainer } from './dialog-container' ;
27
27
import { OverlayContainer , ScrollStrategy } from '@angular/cdk/overlay' ;
28
+ import { A11yModule , FocusOrigin , FocusMonitor } from '@angular/cdk/a11y' ;
28
29
import { A , ESCAPE } from '@angular/cdk/keycodes' ;
29
30
import { dispatchKeyboardEvent } from '@angular/cdk/testing' ;
30
31
import {
@@ -40,14 +41,15 @@ describe('MatDialog', () => {
40
41
let dialog : MatDialog ;
41
42
let overlayContainer : OverlayContainer ;
42
43
let overlayContainerElement : HTMLElement ;
44
+ let focusMonitor : FocusMonitor ;
43
45
44
46
let testViewContainerRef : ViewContainerRef ;
45
47
let viewContainerFixture : ComponentFixture < ComponentWithChildViewContainer > ;
46
48
let mockLocation : SpyLocation ;
47
49
48
50
beforeEach ( fakeAsync ( ( ) => {
49
51
TestBed . configureTestingModule ( {
50
- imports : [ MatDialogModule , DialogTestModule ] ,
52
+ imports : [ MatDialogModule , DialogTestModule , A11yModule ] ,
51
53
providers : [
52
54
{ provide : Location , useClass : SpyLocation }
53
55
] ,
@@ -56,13 +58,14 @@ describe('MatDialog', () => {
56
58
TestBed . compileComponents ( ) ;
57
59
} ) ) ;
58
60
59
- beforeEach ( inject ( [ MatDialog , Location , OverlayContainer ] ,
60
- ( d : MatDialog , l : Location , oc : OverlayContainer ) => {
61
+ beforeEach ( inject ( [ MatDialog , Location , OverlayContainer , FocusMonitor ] ,
62
+ ( d : MatDialog , l : Location , oc : OverlayContainer , fm : FocusMonitor ) => {
61
63
dialog = d ;
62
64
mockLocation = l as SpyLocation ;
63
65
overlayContainer = oc ;
64
66
overlayContainerElement = oc . getContainerElement ( ) ;
65
- } ) ) ;
67
+ focusMonitor = fm ;
68
+ } ) ) ;
66
69
67
70
afterEach ( ( ) => {
68
71
overlayContainer . ngOnDestroy ( ) ;
@@ -900,6 +903,65 @@ describe('MatDialog', () => {
900
903
document . body . removeChild ( button ) ;
901
904
} ) ) ;
902
905
906
+ it ( 'should re-focus the trigger via mouse when dialog closes through escape' , fakeAsync ( ( ) => {
907
+ const button = document . createElement ( 'button' ) ;
908
+ let lastFocusOrigin : FocusOrigin = null ;
909
+
910
+ focusMonitor . monitor ( button , false ) . subscribe ( focusOrigin => lastFocusOrigin = focusOrigin ) ;
911
+ document . body . appendChild ( button ) ;
912
+ button . focus ( ) ;
913
+
914
+ dialog . open ( PizzaMsg , { viewContainerRef : testViewContainerRef } ) ;
915
+
916
+ flushMicrotasks ( ) ;
917
+ viewContainerFixture . detectChanges ( ) ;
918
+ flushMicrotasks ( ) ;
919
+
920
+ expect ( lastFocusOrigin ! ) . toBeNull ( 'Expected the trigger button to be blurred' ) ;
921
+
922
+ dispatchKeyboardEvent ( document . body , 'keydown' , ESCAPE ) ;
923
+
924
+ flushMicrotasks ( ) ;
925
+ viewContainerFixture . detectChanges ( ) ;
926
+ tick ( 500 ) ;
927
+
928
+ expect ( lastFocusOrigin ! )
929
+ . toBe ( 'keyboard' , 'Expected the trigger button to be focused via keyboard' ) ;
930
+
931
+ focusMonitor . stopMonitoring ( button ) ;
932
+ document . body . removeChild ( button ) ;
933
+ } ) ) ;
934
+
935
+ it ( 'should re-focus the trigger via keyboard when backdrop has been clicked' , fakeAsync ( ( ) => {
936
+ const button = document . createElement ( 'button' ) ;
937
+ let lastFocusOrigin : FocusOrigin = null ;
938
+
939
+ focusMonitor . monitor ( button , false ) . subscribe ( focusOrigin => lastFocusOrigin = focusOrigin ) ;
940
+ document . body . appendChild ( button ) ;
941
+ button . focus ( ) ;
942
+
943
+ dialog . open ( PizzaMsg , { viewContainerRef : testViewContainerRef } ) ;
944
+
945
+ flushMicrotasks ( ) ;
946
+ viewContainerFixture . detectChanges ( ) ;
947
+ flushMicrotasks ( ) ;
948
+
949
+ expect ( lastFocusOrigin ! ) . toBeNull ( 'Expected the trigger button to be blurred' ) ;
950
+
951
+ const backdrop = overlayContainerElement
952
+ . querySelector ( '.cdk-overlay-backdrop' ) as HTMLElement ;
953
+
954
+ backdrop . click ( ) ;
955
+ viewContainerFixture . detectChanges ( ) ;
956
+ tick ( 500 ) ;
957
+
958
+ expect ( lastFocusOrigin ! )
959
+ . toBe ( 'mouse' , 'Expected the trigger button to be focused via mouse' ) ;
960
+
961
+ focusMonitor . stopMonitoring ( button ) ;
962
+ document . body . removeChild ( button ) ;
963
+ } ) ) ;
964
+
903
965
it ( 'should allow the consumer to shift focus in afterClosed' , fakeAsync ( ( ) => {
904
966
// Create a element that has focus before the dialog is opened.
905
967
let button = document . createElement ( 'button' ) ;
@@ -922,7 +984,7 @@ describe('MatDialog', () => {
922
984
923
985
tick ( 500 ) ;
924
986
viewContainerFixture . detectChanges ( ) ;
925
- flushMicrotasks ( ) ;
987
+ flush ( ) ;
926
988
927
989
expect ( document . activeElement . id ) . toBe ( 'input-to-be-focused' ,
928
990
'Expected that the trigger was refocused after the dialog is closed.' ) ;
0 commit comments