@@ -2731,6 +2731,217 @@ describe('MDC-based MatAutocomplete', () => {
2731
2731
} ) ) ;
2732
2732
} ) ;
2733
2733
2734
+ describe ( 'automatically selecting the active option' , ( ) => {
2735
+ let fixture : ComponentFixture < SimpleAutocomplete > ;
2736
+
2737
+ beforeEach ( ( ) => {
2738
+ fixture = createComponent ( SimpleAutocomplete ) ;
2739
+ fixture . detectChanges ( ) ;
2740
+ fixture . componentInstance . trigger . autocomplete . autoSelectActiveOption = true ;
2741
+ } ) ;
2742
+
2743
+ it (
2744
+ 'should update the input value as the user is navigating, without changing the model ' +
2745
+ 'value or closing the panel' ,
2746
+ fakeAsync ( ( ) => {
2747
+ const { trigger, stateCtrl, closedSpy} = fixture . componentInstance ;
2748
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2749
+
2750
+ trigger . openPanel ( ) ;
2751
+ fixture . detectChanges ( ) ;
2752
+ zone . simulateZoneExit ( ) ;
2753
+ fixture . detectChanges ( ) ;
2754
+
2755
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2756
+ expect ( input . value ) . toBeFalsy ( ) ;
2757
+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2758
+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2759
+
2760
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2761
+ fixture . detectChanges ( ) ;
2762
+
2763
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2764
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2765
+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2766
+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2767
+
2768
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2769
+ fixture . detectChanges ( ) ;
2770
+
2771
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2772
+ expect ( input . value ) . toBe ( 'California' ) ;
2773
+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2774
+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2775
+ } ) ,
2776
+ ) ;
2777
+
2778
+ it ( 'should revert back to the last typed value if the user presses escape' , fakeAsync ( ( ) => {
2779
+ const { trigger, stateCtrl, closedSpy} = fixture . componentInstance ;
2780
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2781
+
2782
+ trigger . openPanel ( ) ;
2783
+ fixture . detectChanges ( ) ;
2784
+ zone . simulateZoneExit ( ) ;
2785
+ fixture . detectChanges ( ) ;
2786
+ typeInElement ( input , 'al' ) ;
2787
+ fixture . detectChanges ( ) ;
2788
+ tick ( ) ;
2789
+
2790
+ expect ( stateCtrl . value ) . toBe ( 'al' ) ;
2791
+ expect ( input . value ) . toBe ( 'al' ) ;
2792
+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2793
+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2794
+
2795
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2796
+ fixture . detectChanges ( ) ;
2797
+
2798
+ expect ( stateCtrl . value ) . toBe ( 'al' ) ;
2799
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2800
+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2801
+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2802
+
2803
+ dispatchKeyboardEvent ( document . body , 'keydown' , ESCAPE ) ;
2804
+ fixture . detectChanges ( ) ;
2805
+
2806
+ expect ( stateCtrl . value ) . toBe ( 'al' ) ;
2807
+ expect ( input . value ) . toBe ( 'al' ) ;
2808
+ expect ( trigger . panelOpen ) . toBe ( false ) ;
2809
+ expect ( closedSpy ) . toHaveBeenCalledTimes ( 1 ) ;
2810
+ } ) ) ;
2811
+
2812
+ it (
2813
+ 'should clear the input if the user presses escape while there was a pending ' +
2814
+ 'auto selection and there is no previous value' ,
2815
+ fakeAsync ( ( ) => {
2816
+ const { trigger, stateCtrl} = fixture . componentInstance ;
2817
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2818
+
2819
+ trigger . openPanel ( ) ;
2820
+ fixture . detectChanges ( ) ;
2821
+ zone . simulateZoneExit ( ) ;
2822
+ fixture . detectChanges ( ) ;
2823
+
2824
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2825
+ expect ( input . value ) . toBeFalsy ( ) ;
2826
+
2827
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2828
+ fixture . detectChanges ( ) ;
2829
+
2830
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2831
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2832
+
2833
+ dispatchKeyboardEvent ( document . body , 'keydown' , ESCAPE ) ;
2834
+ fixture . detectChanges ( ) ;
2835
+
2836
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2837
+ expect ( input . value ) . toBeFalsy ( ) ;
2838
+ } ) ,
2839
+ ) ;
2840
+
2841
+ it ( 'should propagate the auto-selected value if the user clicks away' , fakeAsync ( ( ) => {
2842
+ const { trigger, stateCtrl} = fixture . componentInstance ;
2843
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2844
+
2845
+ trigger . openPanel ( ) ;
2846
+ fixture . detectChanges ( ) ;
2847
+ zone . simulateZoneExit ( ) ;
2848
+ fixture . detectChanges ( ) ;
2849
+
2850
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2851
+ expect ( input . value ) . toBeFalsy ( ) ;
2852
+
2853
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2854
+ fixture . detectChanges ( ) ;
2855
+
2856
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2857
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2858
+
2859
+ dispatchFakeEvent ( document , 'click' ) ;
2860
+ fixture . detectChanges ( ) ;
2861
+
2862
+ expect ( stateCtrl . value ) . toEqual ( { code : 'AL' , name : 'Alabama' } ) ;
2863
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2864
+ } ) ) ;
2865
+
2866
+ it ( 'should propagate the auto-selected value if the user tabs away' , fakeAsync ( ( ) => {
2867
+ const { trigger, stateCtrl} = fixture . componentInstance ;
2868
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2869
+
2870
+ trigger . openPanel ( ) ;
2871
+ fixture . detectChanges ( ) ;
2872
+ zone . simulateZoneExit ( ) ;
2873
+ fixture . detectChanges ( ) ;
2874
+
2875
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2876
+ expect ( input . value ) . toBeFalsy ( ) ;
2877
+
2878
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2879
+ fixture . detectChanges ( ) ;
2880
+
2881
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2882
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2883
+
2884
+ dispatchKeyboardEvent ( input , 'keydown' , TAB ) ;
2885
+ fixture . detectChanges ( ) ;
2886
+
2887
+ expect ( stateCtrl . value ) . toEqual ( { code : 'AL' , name : 'Alabama' } ) ;
2888
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2889
+ } ) ) ;
2890
+
2891
+ it ( 'should propagate the auto-selected value if the user presses enter on it' , fakeAsync ( ( ) => {
2892
+ const { trigger, stateCtrl} = fixture . componentInstance ;
2893
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2894
+
2895
+ trigger . openPanel ( ) ;
2896
+ fixture . detectChanges ( ) ;
2897
+ zone . simulateZoneExit ( ) ;
2898
+ fixture . detectChanges ( ) ;
2899
+
2900
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2901
+ expect ( input . value ) . toBeFalsy ( ) ;
2902
+
2903
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2904
+ fixture . detectChanges ( ) ;
2905
+
2906
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2907
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2908
+
2909
+ dispatchKeyboardEvent ( input , 'keydown' , ENTER ) ;
2910
+ fixture . detectChanges ( ) ;
2911
+
2912
+ expect ( stateCtrl . value ) . toEqual ( { code : 'AL' , name : 'Alabama' } ) ;
2913
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2914
+ } ) ) ;
2915
+
2916
+ it ( 'should allow the user to click on an option different from the auto-selected one' , fakeAsync ( ( ) => {
2917
+ const { trigger, stateCtrl} = fixture . componentInstance ;
2918
+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2919
+
2920
+ trigger . openPanel ( ) ;
2921
+ fixture . detectChanges ( ) ;
2922
+ zone . simulateZoneExit ( ) ;
2923
+ fixture . detectChanges ( ) ;
2924
+
2925
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2926
+ expect ( input . value ) . toBeFalsy ( ) ;
2927
+
2928
+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2929
+ fixture . detectChanges ( ) ;
2930
+
2931
+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2932
+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2933
+
2934
+ const options = overlayContainerElement . querySelectorAll (
2935
+ 'mat-option' ,
2936
+ ) as NodeListOf < HTMLElement > ;
2937
+ options [ 2 ] . click ( ) ;
2938
+ fixture . detectChanges ( ) ;
2939
+
2940
+ expect ( stateCtrl . value ) . toEqual ( { code : 'FL' , name : 'Florida' } ) ;
2941
+ expect ( input . value ) . toBe ( 'Florida' ) ;
2942
+ } ) ) ;
2943
+ } ) ;
2944
+
2734
2945
it ( 'should have correct width when opened' , ( ) => {
2735
2946
const widthFixture = createComponent ( SimpleAutocomplete ) ;
2736
2947
widthFixture . componentInstance . width = 300 ;
0 commit comments