1- import { Component , ViewChild } from '@angular/core' ;
1+ import { Component , ViewChild , ElementRef } from '@angular/core' ;
22import { async , fakeAsync , TestBed , tick , flush , ComponentFixture } from '@angular/core/testing' ;
33import { FormsModule } from '@angular/forms' ;
44import { By } from '@angular/platform-browser' ;
@@ -30,7 +30,8 @@ describe('IgxDatePicker', () => {
3030 IgxDatePickerEditableComponent ,
3131 IgxDatePickerCustomizedComponent ,
3232 IgxDropDownDatePickerRetemplatedComponent ,
33- IgxDatePickerOpeningComponent
33+ IgxDatePickerOpeningComponent ,
34+ IgxDatePickerDropdownButtonsComponent
3435 ] ,
3536 imports : [ IgxDatePickerModule , FormsModule , NoopAnimationsModule , IgxInputGroupModule , IgxCalendarModule , IgxButtonModule ]
3637 } )
@@ -179,7 +180,7 @@ describe('IgxDatePicker', () => {
179180 expect ( overlays . length ) . toEqual ( 0 ) ;
180181 } ) ) ;
181182
182- it ( 'When datepicker is closed and the dialog disappear, the focus should remain on the input' ,
183+ it ( 'When modal datepicker is closed via `Escape` Key and the dialog disappear, the focus should remain on the input' ,
183184 fakeAsync ( ( ) => {
184185 const datePickerDom = fixture . debugElement . query ( By . css ( 'igx-date-picker' ) ) ;
185186 let overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
@@ -203,6 +204,56 @@ describe('IgxDatePicker', () => {
203204 expect ( input ) . toEqual ( document . activeElement ) ;
204205 } ) ) ;
205206
207+ it ( 'When a modal datepicker is closed via outside click, the focus should remain on the input' ,
208+ fakeAsync ( ( ) => {
209+ const datePickerDom = fixture . debugElement . query ( By . css ( 'igx-date-picker' ) ) ;
210+ let overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
211+ expect ( overlayToggle . length ) . toEqual ( 0 ) ;
212+
213+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
214+ flush ( ) ;
215+ fixture . detectChanges ( ) ;
216+
217+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
218+ expect ( overlayToggle [ 0 ] ) . not . toBeNull ( ) ;
219+ expect ( overlayToggle [ 0 ] ) . not . toBeUndefined ( ) ;
220+
221+ UIInteractions . clickElement ( overlayToggle [ 0 ] ) ;
222+ flush ( ) ;
223+ fixture . detectChanges ( ) ;
224+
225+ const input = fixture . debugElement . query ( By . directive ( IgxInputDirective ) ) . nativeElement ;
226+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
227+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
228+ expect ( input ) . toEqual ( document . activeElement ) ;
229+ } ) ) ;
230+
231+ it ( 'When datepicker is closed upon selecting a date, the focus should remain on the input' ,
232+ fakeAsync ( ( ) => {
233+ const datePickerDom = fixture . debugElement . query ( By . css ( 'igx-date-picker' ) ) ;
234+ let overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
235+ expect ( overlayToggle . length ) . toEqual ( 0 ) ;
236+
237+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
238+ flush ( ) ;
239+ fixture . detectChanges ( ) ;
240+
241+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
242+ expect ( overlayToggle [ 0 ] ) . not . toBeNull ( ) ;
243+ expect ( overlayToggle [ 0 ] ) . not . toBeUndefined ( ) ;
244+
245+ // select a date
246+ const dateElemToSelect = document . getElementsByClassName ( 'igx-calendar__date' ) [ 10 ] ;
247+ UIInteractions . clickElement ( dateElemToSelect ) ;
248+ flush ( ) ;
249+ fixture . detectChanges ( ) ;
250+
251+ const input = fixture . debugElement . query ( By . directive ( IgxInputDirective ) ) . nativeElement ;
252+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper--modal' ) ;
253+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
254+ expect ( input ) . toEqual ( document . activeElement ) ;
255+ } ) ) ;
256+
206257 } ) ;
207258
208259 describe ( 'DatePicker with passed date' , ( ) => {
@@ -247,6 +298,99 @@ describe('IgxDatePicker', () => {
247298 } ) ;
248299 } ) ;
249300
301+ it ( 'When datepicker in "dropdown" mode is closed via outside click, the input should not receive focus' ,
302+ fakeAsync ( ( ) => {
303+ const fixture = TestBed . createComponent ( IgxDatePickerDropdownButtonsComponent ) ;
304+ fixture . detectChanges ( ) ;
305+
306+ const datePickerDom = fixture . debugElement . query ( By . css ( 'igx-date-picker' ) ) ;
307+ const input = fixture . debugElement . query ( By . directive ( IgxInputDirective ) ) . nativeElement ;
308+ let overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
309+
310+ expect ( overlayToggle . length ) . toEqual ( 0 ) ;
311+
312+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
313+ flush ( ) ;
314+ fixture . detectChanges ( ) ;
315+
316+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
317+ expect ( overlayToggle [ 0 ] ) . not . toBeNull ( ) ;
318+ expect ( overlayToggle [ 0 ] ) . not . toBeUndefined ( ) ;
319+
320+ const dummyInput = fixture . componentInstance . dummyInput . nativeElement ;
321+ dummyInput . focus ( ) ;
322+ dummyInput . click ( ) ;
323+ tick ( ) ;
324+ fixture . detectChanges ( ) ;
325+
326+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
327+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
328+ expect ( input ) . not . toEqual ( document . activeElement ) ;
329+ expect ( dummyInput ) . toEqual ( document . activeElement ) ;
330+ } ) ) ;
331+
332+ it ( 'When datepicker in "dropdown" mode, should focus input on user interaction with Today btn, Cancel btn, Enter Key, Escape key' ,
333+ fakeAsync ( ( ) => {
334+ const fixture = TestBed . createComponent ( IgxDatePickerDropdownButtonsComponent ) ;
335+ fixture . detectChanges ( ) ;
336+ const datePickerDom = fixture . debugElement . query ( By . css ( 'igx-date-picker' ) ) ;
337+ const input = fixture . debugElement . query ( By . directive ( IgxInputDirective ) ) . nativeElement ;
338+ let overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
339+ expect ( overlayToggle . length ) . toEqual ( 0 ) ;
340+
341+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
342+ flush ( ) ;
343+ fixture . detectChanges ( ) ;
344+ const buttons = document . getElementsByClassName ( 'igx-button--flat' ) ;
345+ expect ( buttons . length ) . toEqual ( 2 ) ;
346+
347+ // Today btn
348+ const todayBtn = buttons [ 1 ] as HTMLElement ;
349+ expect ( todayBtn . innerText ) . toBe ( 'Today' ) ;
350+ todayBtn . click ( ) ;
351+ tick ( ) ;
352+ fixture . detectChanges ( ) ;
353+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
354+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
355+ expect ( input ) . toEqual ( document . activeElement ) ;
356+
357+ // Cancel btn
358+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
359+ flush ( ) ;
360+ fixture . detectChanges ( ) ;
361+ const cancelBtn = buttons [ 0 ] as HTMLElement ;
362+ expect ( cancelBtn . innerText ) . toBe ( 'Cancel' ) ;
363+ cancelBtn . click ( ) ;
364+ tick ( ) ;
365+ fixture . detectChanges ( ) ;
366+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
367+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
368+ expect ( input ) . toEqual ( document . activeElement ) ;
369+
370+ // Enter key
371+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
372+ flush ( ) ;
373+ fixture . detectChanges ( ) ;
374+ document . activeElement . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' , bubbles : true } ) ) ;
375+ tick ( ) ;
376+ fixture . detectChanges ( ) ;
377+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
378+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
379+ expect ( input ) . toEqual ( document . activeElement ) ;
380+
381+ // Esc key
382+ UIInteractions . triggerKeyDownEvtUponElem ( 'space' , datePickerDom . nativeElement , false ) ;
383+ flush ( ) ;
384+ fixture . detectChanges ( ) ;
385+ document . activeElement . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' , bubbles : true } ) ) ;
386+ tick ( ) ;
387+ fixture . detectChanges ( ) ;
388+
389+ overlayToggle = document . getElementsByClassName ( 'igx-overlay__wrapper' ) ;
390+ expect ( overlayToggle [ 0 ] ) . toEqual ( undefined ) ;
391+ expect ( input ) . toEqual ( document . activeElement ) ;
392+ } ) ) ;
393+
250394 it ( 'Datepicker week start day (Monday)' , ( ) => {
251395 const fixture = TestBed . createComponent ( IgxDatePickerWithWeekStartComponent ) ;
252396 fixture . detectChanges ( ) ;
@@ -1234,3 +1378,18 @@ export class IgxDatePickerCustomizedComponent {
12341378export class IgxDatePickerOpeningComponent {
12351379 @ViewChild ( IgxDatePickerComponent , { static : true } ) public datePicker : IgxDatePickerComponent ;
12361380}
1381+
1382+ @Component ( {
1383+ template : `
1384+ <input class="dummyInput" #dummyInput/>
1385+ <igx-date-picker id="dropdownButtonsDatePicker" mode="dropdown" cancelButtonLabel="Cancel" todayButtonLabel="Today" >
1386+ </igx-date-picker>
1387+ `
1388+ } )
1389+ class IgxDatePickerDropdownButtonsComponent {
1390+ @ViewChild ( 'dropdownButtonsDatePicker' , { read : IgxDatePickerComponent , static : true } )
1391+ public datePicker : IgxDatePickerComponent ;
1392+
1393+ @ViewChild ( 'dummyInput' , { static : true } ) public dummyInput : ElementRef ;
1394+ }
1395+
0 commit comments