File tree 4 files changed +122
-2
lines changed
4 files changed +122
-2
lines changed Original file line number Diff line number Diff line change
1
+ import { SpectatorHost , createHostFactory } from '@ngneat/spectator/jest' ;
2
+
3
+ import { TestFocusComponent } from '../../../test/focus/test-focus.component' ;
4
+
5
+ describe ( 'SpectatorHost.focus() in jest' , ( ) => {
6
+
7
+ const createHost = createHostFactory ( TestFocusComponent ) ;
8
+ let host : SpectatorHost < TestFocusComponent > ;
9
+
10
+ beforeEach ( ( ) => {
11
+ host = createHost ( '<app-test-focus></app-test-focus>' ) ;
12
+ } )
13
+
14
+ it ( 'sets document.activeElement' , ( ) => {
15
+ host . focus ( '#button1' ) ;
16
+
17
+ expect ( host . query ( '#button1' ) ) . toBeFocused ( ) ;
18
+ } ) ;
19
+
20
+ it ( 'causes blur events' , ( ) => {
21
+ host . focus ( ) ;
22
+ host . focus ( '#button1' ) ;
23
+ host . focus ( '#button2' ) ;
24
+
25
+ expect ( host . component . focusCount ( 'app-test-focus' ) ) . toBe ( 1 ) ;
26
+ expect ( host . component . blurCount ( 'app-test-focus' ) ) . toBe ( 1 ) ;
27
+ expect ( host . component . focusCount ( 'button1' ) ) . toBe ( 1 ) ;
28
+ expect ( host . component . blurCount ( 'button1' ) ) . toBe ( 1 ) ;
29
+ expect ( host . component . focusCount ( 'button2' ) ) . toBe ( 1 ) ;
30
+ expect ( host . component . blurCount ( 'button2' ) ) . toBe ( 0 ) ;
31
+ } ) ;
32
+
33
+ } ) ;
Original file line number Diff line number Diff line change 1
1
import { dispatchFakeEvent } from '../dispatch-events' ;
2
+ import { isRunningInJsDom } from '../utils' ;
3
+
4
+ /** Property name added to HTML Elements to ensure we don't double-patch focus methods on an element. */
5
+ const IS_FOCUS_PATCHED_PROP = '_patched_focus' ;
2
6
3
7
/**
4
8
* Patches an elements focus and blur methods to emit events consistently and predictably.
@@ -8,6 +12,22 @@ import { dispatchFakeEvent } from '../dispatch-events';
8
12
* patchElementFocus(triggerEl);
9
13
*/
10
14
export function patchElementFocus ( element : HTMLElement ) : void {
11
- element . focus = ( ) => dispatchFakeEvent ( element , 'focus' ) ;
12
- element . blur = ( ) => dispatchFakeEvent ( element , 'blur' ) ;
15
+
16
+ // https://github.com/ngneat/spectator/issues/373 - Don't patch when using JSDOM, eg in Jest
17
+ if ( ! isRunningInJsDom ( ) && ( element [ IS_FOCUS_PATCHED_PROP ] === undefined ) ) {
18
+ const baseFocus = element . focus . bind ( element ) ;
19
+ element . focus = ( options ) => {
20
+ // Blur current active
21
+ const active = element . ownerDocument . activeElement ;
22
+ if ( active ) {
23
+ dispatchFakeEvent ( active , 'blur' ) ;
24
+ }
25
+
26
+ // Focus
27
+ baseFocus ( options ) ; // Needed to set document.activeElement
28
+ dispatchFakeEvent ( element , 'focus' ) ; // Needed to cause focus event
29
+ }
30
+ element . blur = ( ) => dispatchFakeEvent ( element , 'blur' ) ;
31
+ element [ IS_FOCUS_PATCHED_PROP ] = true ;
32
+ }
13
33
}
Original file line number Diff line number Diff line change
1
+ import { SpectatorHost , createHostFactory } from '@ngneat/spectator' ;
2
+ import { TestFocusComponent } from './test-focus.component' ;
3
+
4
+ describe ( 'SpectatorHost.focus() ' , ( ) => {
5
+
6
+ const createHost = createHostFactory ( TestFocusComponent ) ;
7
+ let host : SpectatorHost < TestFocusComponent > ;
8
+
9
+ beforeEach ( ( ) => {
10
+ host = createHost ( '<app-test-focus></app-test-focus>' ) ;
11
+ } )
12
+
13
+ it ( 'sets document.activeElement' , ( ) => {
14
+ host . focus ( '#button1' ) ;
15
+
16
+ expect ( host . query ( '#button1' ) ) . toBeFocused ( ) ;
17
+ } ) ;
18
+
19
+ it ( 'causes blur events' , ( ) => {
20
+ host . focus ( ) ;
21
+ host . focus ( '#button1' ) ;
22
+ host . focus ( '#button2' ) ;
23
+
24
+ expect ( host . component . focusCount ( 'app-test-focus' ) ) . toBe ( 1 ) ;
25
+ expect ( host . component . blurCount ( 'app-test-focus' ) ) . toBe ( 1 ) ;
26
+ expect ( host . component . focusCount ( 'button1' ) ) . toBe ( 1 ) ;
27
+ expect ( host . component . blurCount ( 'button1' ) ) . toBe ( 1 ) ;
28
+ expect ( host . component . focusCount ( 'button2' ) ) . toBe ( 1 ) ;
29
+ expect ( host . component . blurCount ( 'button2' ) ) . toBe ( 0 ) ;
30
+ } ) ;
31
+
32
+ } ) ;
Original file line number Diff line number Diff line change
1
+ import { ChangeDetectionStrategy , Component } from '@angular/core' ;
2
+
3
+ @Component ( {
4
+ selector : 'app-test-focus' ,
5
+ template : `<button id="button1" (focus)="countFocus('button1')" (blur)="countBlur('button1')">Button1</button>
6
+ <button id="button2" (focus)="countFocus('button2')" (blur)="countBlur('button2')">Button2</button>` ,
7
+ changeDetection : ChangeDetectionStrategy . OnPush ,
8
+ host : {
9
+ '[attr.tabindex]' : '0' ,
10
+ '(focus)' : 'countFocus("app-test-focus")' ,
11
+ '(blur)' : 'countBlur("app-test-focus")'
12
+ }
13
+ } )
14
+ export class TestFocusComponent {
15
+
16
+ private readonly focusCounts = new Map < string , number > ( ) ;
17
+ private readonly blurCounts = new Map < string , number > ( ) ;
18
+
19
+ public countFocus ( id : string ) {
20
+ this . focusCounts . set ( id , this . focusCount ( id ) + 1 ) ;
21
+ }
22
+
23
+ public countBlur ( id : string ) {
24
+ this . blurCounts . set ( id , this . blurCount ( id ) + 1 ) ;
25
+ }
26
+
27
+ public focusCount ( id : string ) : number {
28
+ return this . focusCounts . get ( id ) ?? 0 ;
29
+ }
30
+
31
+ public blurCount ( id : string ) : number {
32
+ return this . blurCounts . get ( id ) ?? 0 ;
33
+ }
34
+
35
+ }
You can’t perform that action at this time.
0 commit comments