@@ -2706,6 +2706,217 @@ describe('MDC-based MatAutocomplete', () => {
27062706 } ) ) ;
27072707 } ) ;
27082708
2709+ describe ( 'automatically selecting the active option' , ( ) => {
2710+ let fixture : ComponentFixture < SimpleAutocomplete > ;
2711+
2712+ beforeEach ( ( ) => {
2713+ fixture = createComponent ( SimpleAutocomplete ) ;
2714+ fixture . detectChanges ( ) ;
2715+ fixture . componentInstance . trigger . autocomplete . autoSelectActiveOption = true ;
2716+ } ) ;
2717+
2718+ it (
2719+ 'should update the input value as the user is navigating, without changing the model ' +
2720+ 'value or closing the panel' ,
2721+ fakeAsync ( ( ) => {
2722+ const { trigger, stateCtrl, closedSpy} = fixture . componentInstance ;
2723+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2724+
2725+ trigger . openPanel ( ) ;
2726+ fixture . detectChanges ( ) ;
2727+ zone . simulateZoneExit ( ) ;
2728+ fixture . detectChanges ( ) ;
2729+
2730+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2731+ expect ( input . value ) . toBeFalsy ( ) ;
2732+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2733+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2734+
2735+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2736+ fixture . detectChanges ( ) ;
2737+
2738+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2739+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2740+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2741+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2742+
2743+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2744+ fixture . detectChanges ( ) ;
2745+
2746+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2747+ expect ( input . value ) . toBe ( 'California' ) ;
2748+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2749+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2750+ } ) ,
2751+ ) ;
2752+
2753+ it ( 'should revert back to the last typed value if the user presses escape' , fakeAsync ( ( ) => {
2754+ const { trigger, stateCtrl, closedSpy} = fixture . componentInstance ;
2755+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2756+
2757+ trigger . openPanel ( ) ;
2758+ fixture . detectChanges ( ) ;
2759+ zone . simulateZoneExit ( ) ;
2760+ fixture . detectChanges ( ) ;
2761+ typeInElement ( input , 'al' ) ;
2762+ fixture . detectChanges ( ) ;
2763+ tick ( ) ;
2764+
2765+ expect ( stateCtrl . value ) . toBe ( 'al' ) ;
2766+ expect ( input . value ) . toBe ( 'al' ) ;
2767+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2768+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2769+
2770+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2771+ fixture . detectChanges ( ) ;
2772+
2773+ expect ( stateCtrl . value ) . toBe ( 'al' ) ;
2774+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2775+ expect ( trigger . panelOpen ) . toBe ( true ) ;
2776+ expect ( closedSpy ) . not . toHaveBeenCalled ( ) ;
2777+
2778+ dispatchKeyboardEvent ( document . body , 'keydown' , ESCAPE ) ;
2779+ fixture . detectChanges ( ) ;
2780+
2781+ expect ( stateCtrl . value ) . toBe ( 'al' ) ;
2782+ expect ( input . value ) . toBe ( 'al' ) ;
2783+ expect ( trigger . panelOpen ) . toBe ( false ) ;
2784+ expect ( closedSpy ) . toHaveBeenCalledTimes ( 1 ) ;
2785+ } ) ) ;
2786+
2787+ it (
2788+ 'should clear the input if the user presses escape while there was a pending ' +
2789+ 'auto selection and there is no previous value' ,
2790+ fakeAsync ( ( ) => {
2791+ const { trigger, stateCtrl} = fixture . componentInstance ;
2792+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2793+
2794+ trigger . openPanel ( ) ;
2795+ fixture . detectChanges ( ) ;
2796+ zone . simulateZoneExit ( ) ;
2797+ fixture . detectChanges ( ) ;
2798+
2799+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2800+ expect ( input . value ) . toBeFalsy ( ) ;
2801+
2802+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2803+ fixture . detectChanges ( ) ;
2804+
2805+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2806+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2807+
2808+ dispatchKeyboardEvent ( document . body , 'keydown' , ESCAPE ) ;
2809+ fixture . detectChanges ( ) ;
2810+
2811+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2812+ expect ( input . value ) . toBeFalsy ( ) ;
2813+ } ) ,
2814+ ) ;
2815+
2816+ it ( 'should propagate the auto-selected value if the user clicks away' , fakeAsync ( ( ) => {
2817+ const { trigger, stateCtrl} = fixture . componentInstance ;
2818+ const input : HTMLInputElement = fixture . nativeElement . querySelector ( 'input' ) ;
2819+
2820+ trigger . openPanel ( ) ;
2821+ fixture . detectChanges ( ) ;
2822+ zone . simulateZoneExit ( ) ;
2823+ fixture . detectChanges ( ) ;
2824+
2825+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2826+ expect ( input . value ) . toBeFalsy ( ) ;
2827+
2828+ dispatchKeyboardEvent ( input , 'keydown' , DOWN_ARROW ) ;
2829+ fixture . detectChanges ( ) ;
2830+
2831+ expect ( stateCtrl . value ) . toBeFalsy ( ) ;
2832+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2833+
2834+ dispatchFakeEvent ( document , 'click' ) ;
2835+ fixture . detectChanges ( ) ;
2836+
2837+ expect ( stateCtrl . value ) . toEqual ( { code : 'AL' , name : 'Alabama' } ) ;
2838+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2839+ } ) ) ;
2840+
2841+ it ( 'should propagate the auto-selected value if the user tabs 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+ dispatchKeyboardEvent ( input , 'keydown' , TAB ) ;
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 presses enter on it' , 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' , ENTER ) ;
2885+ fixture . detectChanges ( ) ;
2886+
2887+ expect ( stateCtrl . value ) . toEqual ( { code : 'AL' , name : 'Alabama' } ) ;
2888+ expect ( input . value ) . toBe ( 'Alabama' ) ;
2889+ } ) ) ;
2890+
2891+ it ( 'should allow the user to click on an option different from the auto-selected one' , 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+ const options = overlayContainerElement . querySelectorAll (
2910+ 'mat-option' ,
2911+ ) as NodeListOf < HTMLElement > ;
2912+ options [ 2 ] . click ( ) ;
2913+ fixture . detectChanges ( ) ;
2914+
2915+ expect ( stateCtrl . value ) . toEqual ( { code : 'FL' , name : 'Florida' } ) ;
2916+ expect ( input . value ) . toBe ( 'Florida' ) ;
2917+ } ) ) ;
2918+ } ) ;
2919+
27092920 it ( 'should have correct width when opened' , ( ) => {
27102921 const widthFixture = createComponent ( SimpleAutocomplete ) ;
27112922 widthFixture . componentInstance . width = 300 ;
0 commit comments