@@ -34,6 +34,9 @@ describe('MatSnackBar', () => {
34
34
let simpleMessage = 'Burritos are here!' ;
35
35
let simpleActionLabel = 'pickup' ;
36
36
37
+ /** The tick count to reach the next animation frame when using `requestAnimationFrame` */
38
+ const animationFrameDelay = 16 ;
39
+
37
40
beforeEach ( fakeAsync ( ( ) => {
38
41
TestBed . configureTestingModule ( {
39
42
imports : [ MatSnackBarModule , SnackBarTestModule , NoopAnimationsModule ] ,
@@ -60,44 +63,101 @@ describe('MatSnackBar', () => {
60
63
testViewContainerRef = viewContainerFixture . componentInstance . childViewContainer ;
61
64
} ) ;
62
65
63
- it ( 'should have the role of `alert` with an `assertive` politeness if no announcement message ' +
64
- 'is provided' , ( ) => {
66
+ it ( 'should open with content first in the non-live region' , ( ) => {
67
+ snackBar . open ( 'Snack time!' , 'Chew' ) ;
68
+ viewContainerFixture . detectChanges ( ) ;
69
+
70
+ const containerElement = overlayContainerElement . querySelector ( 'mat-mdc-snack-bar-container' ) ! ;
71
+ const nonLiveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-non-live' ) ! ;
72
+
73
+ expect ( nonLiveElement . getAttribute ( 'aria-hidden' ) )
74
+ . toBe ( 'true' , 'Expected the non-live region to be aria-hidden' ) ;
75
+ expect ( nonLiveElement . textContent ) . toContain ( 'Snack time!' ,
76
+ 'Expected non-live region to contain the snack bar content' ) ;
77
+
78
+ const liveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-live' ) ! ;
79
+ expect ( liveElement . childNodes . length )
80
+ . toBe ( 0 , 'Expected live region to not contain any content' ) ;
81
+ } ) ;
82
+
83
+ it ( 'should move content to the live region after entrance animation ends' , fakeAsync ( ( ) => {
84
+ snackBar . open ( 'Snack time!' , 'Chew' ) ;
85
+ viewContainerFixture . detectChanges ( ) ;
86
+
87
+ const containerElement = overlayContainerElement . querySelector ( 'mat-mdc-snack-bar-container' ) ! ;
88
+ const liveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-live' ) ! ;
89
+ tick ( animationFrameDelay ) ;
90
+ flush ( ) ;
91
+
92
+ expect ( liveElement . textContent ) . toContain ( 'Snack time!' ,
93
+ 'Expected live region to contain the snack bar content' ) ;
94
+
95
+ const nonLiveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-non-live' ) ! ;
96
+ expect ( nonLiveElement . childNodes . length )
97
+ . toBe ( 0 , 'Expected non-live region to not contain any content' ) ;
98
+ } ) ) ;
99
+
100
+ it ( 'should preserve focus when moving content to the live region' , fakeAsync ( ( ) => {
101
+ snackBar . open ( 'Snack time!' , 'Chew' ) ;
102
+ viewContainerFixture . detectChanges ( ) ;
103
+
104
+ const actionButton = overlayContainerElement
105
+ . querySelector ( '.mat-mdc-simple-snack-bar .mat-mdc-snack-bar-action' ) ! as HTMLElement ;
106
+ actionButton . focus ( ) ;
107
+ tick ( animationFrameDelay ) ;
108
+ flush ( ) ;
109
+
110
+ expect ( document . activeElement )
111
+ . toBe ( actionButton , 'Expected the focus to remain on the action button' ) ;
112
+ } ) ) ;
113
+
114
+ it ( 'should have aria-live of `assertive` with an `assertive` politeness if no announcement ' +
115
+ 'message is provided' , ( ) => {
65
116
snackBar . openFromComponent ( BurritosNotification ,
66
117
{ announcementMessage : '' , politeness : 'assertive' } ) ;
67
118
68
119
viewContainerFixture . detectChanges ( ) ;
69
120
70
121
const containerElement = overlayContainerElement . querySelector ( 'mat-mdc-snack-bar-container' ) ! ;
71
- expect ( containerElement . getAttribute ( 'role' ) )
72
- . toBe ( 'alert' , 'Expected snack bar container to have role="alert"' ) ;
122
+ const liveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-live' ) ! ;
123
+
124
+ expect ( liveElement . getAttribute ( 'aria-live' ) ) . toBe ( 'assertive' ,
125
+ 'Expected snack bar container live region to have aria-live="assertive"' ) ;
73
126
} ) ;
74
127
75
- it ( 'should have the role of `status ` with an `assertive` politeness if an announcement message ' +
76
- 'is provided' , ( ) => {
128
+ it ( 'should have aria-live of `polite ` with an `assertive` politeness if an announcement ' +
129
+ 'message is provided' , ( ) => {
77
130
snackBar . openFromComponent ( BurritosNotification ,
78
131
{ announcementMessage : 'Yay Burritos' , politeness : 'assertive' } ) ;
79
132
viewContainerFixture . detectChanges ( ) ;
80
133
81
134
const containerElement = overlayContainerElement . querySelector ( 'mat-mdc-snack-bar-container' ) ! ;
82
- expect ( containerElement . getAttribute ( 'role' ) )
83
- . toBe ( 'status' , 'Expected snack bar container to have role="status"' ) ;
135
+ const liveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-live' ) ! ;
136
+
137
+ expect ( liveElement . getAttribute ( 'aria-live' ) )
138
+ . toBe ( 'polite' , 'Expected snack bar container live region to have aria-live="polite"' ) ;
84
139
} ) ;
85
140
86
- it ( 'should have the role of `status ` with a `polite` politeness' , ( ) => {
141
+ it ( 'should have aria-live of `polite ` with a `polite` politeness' , ( ) => {
87
142
snackBar . openFromComponent ( BurritosNotification , { politeness : 'polite' } ) ;
88
143
viewContainerFixture . detectChanges ( ) ;
89
144
90
145
const containerElement = overlayContainerElement . querySelector ( 'mat-mdc-snack-bar-container' ) ! ;
91
- expect ( containerElement . getAttribute ( 'role' ) )
92
- . toBe ( 'status' , 'Expected snack bar container to have role="status"' ) ;
146
+ const liveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-live' ) ! ;
147
+
148
+ expect ( liveElement . getAttribute ( 'aria-live' ) )
149
+ . toBe ( 'polite' , 'Expected snack bar container live region to have aria-live="polite"' ) ;
93
150
} ) ;
94
151
95
152
it ( 'should remove the role if the politeness is turned off' , ( ) => {
96
153
snackBar . openFromComponent ( BurritosNotification , { politeness : 'off' } ) ;
97
154
viewContainerFixture . detectChanges ( ) ;
98
155
99
156
const containerElement = overlayContainerElement . querySelector ( 'mat-mdc-snack-bar-container' ) ! ;
100
- expect ( containerElement . getAttribute ( 'role' ) ) . toBeFalsy ( 'Expected role to be removed' ) ;
157
+ const liveElement = containerElement . querySelector ( '.mat-mdc-snack-bar-container-live' ) ! ;
158
+
159
+ expect ( liveElement . getAttribute ( 'aria-live' ) )
160
+ . toBe ( 'off' , 'Expected snack bar container live region to have aria-live="off"' ) ;
101
161
} ) ;
102
162
103
163
it ( 'should have exactly one MDC label element when opened through simple snack bar' , ( ) => {
@@ -197,6 +257,8 @@ describe('MatSnackBar', () => {
197
257
198
258
snackBar . open ( simpleMessage , undefined , { announcementMessage : simpleMessage } ) ;
199
259
viewContainerFixture . detectChanges ( ) ;
260
+ tick ( animationFrameDelay ) ;
261
+ flush ( ) ;
200
262
201
263
expect ( overlayContainerElement . childElementCount )
202
264
. toBe ( 1 , 'Expected the overlay with the default announcement message to be added' ) ;
@@ -212,6 +274,8 @@ describe('MatSnackBar', () => {
212
274
politeness : 'assertive'
213
275
} ) ;
214
276
viewContainerFixture . detectChanges ( ) ;
277
+ tick ( animationFrameDelay ) ;
278
+ flush ( ) ;
215
279
216
280
expect ( overlayContainerElement . childElementCount )
217
281
. toBe ( 1 , 'Expected the overlay with a custom `announcementMessage` to be added' ) ;
0 commit comments