@@ -90,6 +90,25 @@ describe('FocusOriginMonitor', () => {
9090 } , 0 ) ;
9191 } ) ) ;
9292
93+ it ( 'should detect focus via touch' , async ( ( ) => {
94+ // Simulate focus via touch.
95+ dispatchTouchstartEvent ( document ) ;
96+ buttonElement . focus ( ) ;
97+ fixture . detectChanges ( ) ;
98+
99+ setTimeout ( ( ) => {
100+ fixture . detectChanges ( ) ;
101+
102+ expect ( buttonElement . classList . length )
103+ . toBe ( 2 , 'button should have exactly 2 focus classes' ) ;
104+ expect ( buttonElement . classList . contains ( 'cdk-focused' ) )
105+ . toBe ( true , 'button should have cdk-focused class' ) ;
106+ expect ( buttonElement . classList . contains ( 'cdk-touch-focused' ) )
107+ . toBe ( true , 'button should have cdk-touch-focused class' ) ;
108+ expect ( changeHandler ) . toHaveBeenCalledWith ( 'touch' ) ;
109+ } , 650 ) ;
110+ } ) ) ;
111+
93112 it ( 'should detect programmatic focus' , async ( ( ) => {
94113 // Programmatically focus.
95114 buttonElement . focus ( ) ;
@@ -142,6 +161,23 @@ describe('FocusOriginMonitor', () => {
142161 } , 0 ) ;
143162 } ) ) ;
144163
164+ it ( 'focusVia mouse should simulate mouse focus' , async ( ( ) => {
165+ focusOriginMonitor . focusVia ( buttonElement , buttonRenderer , 'touch' ) ;
166+ fixture . detectChanges ( ) ;
167+
168+ setTimeout ( ( ) => {
169+ fixture . detectChanges ( ) ;
170+
171+ expect ( buttonElement . classList . length )
172+ . toBe ( 2 , 'button should have exactly 2 focus classes' ) ;
173+ expect ( buttonElement . classList . contains ( 'cdk-focused' ) )
174+ . toBe ( true , 'button should have cdk-focused class' ) ;
175+ expect ( buttonElement . classList . contains ( 'cdk-touch-focused' ) )
176+ . toBe ( true , 'button should have cdk-touch-focused class' ) ;
177+ expect ( changeHandler ) . toHaveBeenCalledWith ( 'touch' ) ;
178+ } , 0 ) ;
179+ } ) ) ;
180+
145181 it ( 'focusVia program should simulate programmatic focus' , async ( ( ) => {
146182 focusOriginMonitor . focusVia ( buttonElement , buttonRenderer , 'program' ) ;
147183 fixture . detectChanges ( ) ;
@@ -251,6 +287,25 @@ describe('cdkFocusClasses', () => {
251287 } , 0 ) ;
252288 } ) ) ;
253289
290+ it ( 'should detect focus via touch' , async ( ( ) => {
291+ // Simulate focus via touch.
292+ dispatchTouchstartEvent ( document ) ;
293+ buttonElement . focus ( ) ;
294+ fixture . detectChanges ( ) ;
295+
296+ setTimeout ( ( ) => {
297+ fixture . detectChanges ( ) ;
298+
299+ expect ( buttonElement . classList . length )
300+ . toBe ( 2 , 'button should have exactly 2 focus classes' ) ;
301+ expect ( buttonElement . classList . contains ( 'cdk-focused' ) )
302+ . toBe ( true , 'button should have cdk-focused class' ) ;
303+ expect ( buttonElement . classList . contains ( 'cdk-touch-focused' ) )
304+ . toBe ( true , 'button should have cdk-touch-focused class' ) ;
305+ expect ( changeHandler ) . toHaveBeenCalledWith ( 'touch' ) ;
306+ } , 650 ) ;
307+ } ) ) ;
308+
254309 it ( 'should detect programmatic focus' , async ( ( ) => {
255310 // Programmatically focus.
256311 buttonElement . focus ( ) ;
@@ -312,6 +367,13 @@ function dispatchMousedownEvent(element: Node) {
312367 element . dispatchEvent ( event ) ;
313368}
314369
370+ /** Dispatches a mousedown event on the specified element. */
371+ function dispatchTouchstartEvent ( element : Node ) {
372+ let event = document . createEvent ( 'MouseEvent' ) ;
373+ event . initMouseEvent (
374+ 'touchstart' , true , true , window , 0 , 0 , 0 , 0 , 0 , false , false , false , false , 0 , null ) ;
375+ element . dispatchEvent ( event ) ;
376+ }
315377
316378/** Dispatches a keydown event on the specified element. */
317379function dispatchKeydownEvent ( element : Node , keyCode : number ) {
0 commit comments