@@ -2731,6 +2731,217 @@ describe('MDC-based MatAutocomplete', () => {
27312731 } ) ) ;
27322732 } ) ;
27332733
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+
27342945 it ( 'should have correct width when opened' , ( ) => {
27352946 const widthFixture = createComponent ( SimpleAutocomplete ) ;
27362947 widthFixture . componentInstance . width = 300 ;
0 commit comments