11import { async , ComponentFixture , TestBed } from '@angular/core/testing' ;
22import { ReactiveFormsModule , FormControl } from '@angular/forms' ;
33import { Component , DebugElement } from '@angular/core' ;
4- import { By } from '@angular/platform-browser' ;
4+ import { By , HAMMER_GESTURE_CONFIG } from '@angular/platform-browser' ;
55import { MdSlider , MdSliderModule } from './slider' ;
6- import { HAMMER_GESTURE_CONFIG } from '@angular/platform-browser' ;
76import { TestGestureConfig } from './test-gesture-config' ;
7+ import {
8+ UP_ARROW ,
9+ RIGHT_ARROW ,
10+ DOWN_ARROW ,
11+ PAGE_DOWN ,
12+ PAGE_UP ,
13+ END ,
14+ HOME , LEFT_ARROW
15+ } from '../core/keyboard/keycodes' ;
816
917
1018describe ( 'MdSlider' , ( ) => {
@@ -746,6 +754,90 @@ describe('MdSlider', () => {
746754 expect ( testComponent . onChange ) . toHaveBeenCalledTimes ( 1 ) ;
747755 } ) ;
748756 } ) ;
757+
758+ describe ( 'keyboard support' , ( ) => {
759+ let fixture : ComponentFixture < StandardSlider > ;
760+ let sliderDebugElement : DebugElement ;
761+ let sliderNativeElement : HTMLElement ;
762+ let sliderTrackElement : HTMLElement ;
763+ let testComponent : StandardSlider ;
764+ let sliderInstance : MdSlider ;
765+
766+ beforeEach ( ( ) => {
767+ fixture = TestBed . createComponent ( StandardSlider ) ;
768+ fixture . detectChanges ( ) ;
769+
770+ testComponent = fixture . debugElement . componentInstance ;
771+ sliderDebugElement = fixture . debugElement . query ( By . directive ( MdSlider ) ) ;
772+ sliderNativeElement = sliderDebugElement . nativeElement ;
773+ sliderTrackElement = < HTMLElement > sliderNativeElement . querySelector ( '.md-slider-track' ) ;
774+ sliderInstance = sliderDebugElement . injector . get ( MdSlider ) ;
775+ } ) ;
776+
777+ it ( 'should increment slider by 1 on up arrow pressed' , ( ) => {
778+ dispatchKeydownEvent ( sliderNativeElement , UP_ARROW ) ;
779+ fixture . detectChanges ( ) ;
780+
781+ expect ( sliderInstance . value ) . toBe ( 1 ) ;
782+ } ) ;
783+
784+ it ( 'should increment slider by 1 on right arrow pressed' , ( ) => {
785+ dispatchKeydownEvent ( sliderNativeElement , RIGHT_ARROW ) ;
786+ fixture . detectChanges ( ) ;
787+
788+ expect ( sliderInstance . value ) . toBe ( 1 ) ;
789+ } ) ;
790+
791+ it ( 'should decrement slider by 1 on down arrow pressed' , ( ) => {
792+ sliderInstance . value = 100 ;
793+
794+ dispatchKeydownEvent ( sliderNativeElement , DOWN_ARROW ) ;
795+ fixture . detectChanges ( ) ;
796+
797+ expect ( sliderInstance . value ) . toBe ( 99 ) ;
798+ } ) ;
799+
800+ it ( 'should decrement slider by 1 on left arrow pressed' , ( ) => {
801+ sliderInstance . value = 100 ;
802+
803+ dispatchKeydownEvent ( sliderNativeElement , LEFT_ARROW ) ;
804+ fixture . detectChanges ( ) ;
805+
806+ expect ( sliderInstance . value ) . toBe ( 99 ) ;
807+ } ) ;
808+
809+ it ( 'should increment slider by 10 on page up pressed' , ( ) => {
810+ dispatchKeydownEvent ( sliderNativeElement , PAGE_UP ) ;
811+ fixture . detectChanges ( ) ;
812+
813+ expect ( sliderInstance . value ) . toBe ( 10 ) ;
814+ } ) ;
815+
816+ it ( 'should decrement slider by 10 on page down pressed' , ( ) => {
817+ sliderInstance . value = 100 ;
818+
819+ dispatchKeydownEvent ( sliderNativeElement , PAGE_DOWN ) ;
820+ fixture . detectChanges ( ) ;
821+
822+ expect ( sliderInstance . value ) . toBe ( 90 ) ;
823+ } ) ;
824+
825+ it ( 'should set slider to max on end pressed' , ( ) => {
826+ dispatchKeydownEvent ( sliderNativeElement , END ) ;
827+ fixture . detectChanges ( ) ;
828+
829+ expect ( sliderInstance . value ) . toBe ( 100 ) ;
830+ } ) ;
831+
832+ it ( 'should set slider to min on home pressed' , ( ) => {
833+ sliderInstance . value = 100 ;
834+
835+ dispatchKeydownEvent ( sliderNativeElement , HOME ) ;
836+ fixture . detectChanges ( ) ;
837+
838+ expect ( sliderInstance . value ) . toBe ( 0 ) ;
839+ } ) ;
840+ } ) ;
749841} ) ;
750842
751843// Disable animations and make the slider an even 100px (+ 8px padding on either side)
@@ -843,7 +935,7 @@ class SliderWithChangeHandler {
843935}
844936
845937/**
846- * Dispatches a click event from an element.
938+ * Dispatches a click event sequence (consisting of moueseenter, click) from an element.
847939 * Note: The mouse event truncates the position for the click.
848940 * @param sliderElement The md-slider element from which the event will be dispatched.
849941 * @param percentage The percentage of the slider where the click should occur. Used to find the
@@ -909,6 +1001,8 @@ function dispatchSlideStartEvent(sliderElement: HTMLElement, percent: number,
9091001 let dimensions = trackElement . getBoundingClientRect ( ) ;
9101002 let x = dimensions . left + ( dimensions . width * percent ) ;
9111003
1004+ dispatchMouseenterEvent ( sliderElement ) ;
1005+
9121006 gestureConfig . emitEventForElement ( 'slidestart' , sliderElement , {
9131007 center : { x : x } ,
9141008 srcEvent : { preventDefault : jasmine . createSpy ( 'preventDefault' ) }
@@ -936,10 +1030,7 @@ function dispatchSlideEndEvent(sliderElement: HTMLElement, percent: number,
9361030/**
9371031 * Dispatches a mouseenter event from an element.
9381032 * Note: The mouse event truncates the position for the click.
939- * @param trackElement The track element from which the event location will be calculated.
940- * @param containerElement The container element from which the event will be dispatched.
941- * @param percentage The percentage of the slider where the click should occur. Used to find the
942- * physical location of the click.
1033+ * @param element The element from which the event will be dispatched.
9431034 */
9441035function dispatchMouseenterEvent ( element : HTMLElement ) : void {
9451036 let dimensions = element . getBoundingClientRect ( ) ;
@@ -951,3 +1042,18 @@ function dispatchMouseenterEvent(element: HTMLElement): void {
9511042 'mouseenter' , true , true , window , 0 , x , y , x , y , false , false , false , false , 0 , null ) ;
9521043 element . dispatchEvent ( event ) ;
9531044}
1045+
1046+ /**
1047+ * Dispatches a keydown event from an element.
1048+ * @param element The element from which the event will be dispatched.
1049+ * @param keyCode The key code of the key being pressed.
1050+ */
1051+ function dispatchKeydownEvent ( element : HTMLElement , keyCode : number ) : void {
1052+ let event : any = document . createEvent ( 'KeyboardEvent' ) ;
1053+ ( event . initKeyEvent || event . initKeyboardEvent ) . bind ( event ) (
1054+ 'keydown' , true , true , window , 0 , 0 , 0 , 0 , 0 , keyCode ) ;
1055+ Object . defineProperty ( event , 'keyCode' , {
1056+ get : function ( ) { return keyCode ; }
1057+ } ) ;
1058+ element . dispatchEvent ( event ) ;
1059+ }
0 commit comments