Skip to content

Commit

Permalink
Provide consistent testing API
Browse files Browse the repository at this point in the history
  • Loading branch information
devversion committed Feb 27, 2017
1 parent c0d8448 commit 250204d
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 119 deletions.
2 changes: 1 addition & 1 deletion src/lib/autocomplete/autocomplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ class AutocompleteWithoutForms {
* @param value Value to be set on the input.
* @param element Element onto which to set the value.
*/
function typeInElement(value: string, element: HTMLInputElement) {
function typeInElement(value: string, element: HTMLInputElement, autoFocus = true) {
element.focus();
element.value = value;
dispatchFakeEvent(element, 'input');
Expand Down
8 changes: 1 addition & 7 deletions src/lib/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {By} from '@angular/platform-browser';
import {MdCheckbox, MdCheckboxChange, MdCheckboxModule} from './checkbox';
import {ViewportRuler} from '../core/overlay/position/viewport-ruler';
import {FakeViewportRuler} from '../core/overlay/position/fake-viewport-ruler';
import {dispatchFakeEvent} from '../core/testing/dispatch-events';


describe('MdCheckbox', () => {
Expand Down Expand Up @@ -785,10 +786,3 @@ class CheckboxWithChangeEvent {
class CheckboxWithFormControl {
formControl = new FormControl();
}

// TODO(devversion): replace with global utility once pull request #2943 is merged.
function dispatchFakeEvent(element: HTMLElement, eventName: string): void {
let event = document.createEvent('Event');
event.initEvent(eventName, true, true);
element.dispatchEvent(event);
}
42 changes: 6 additions & 36 deletions src/lib/core/ripple/ripple.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,6 @@ import {ViewportRuler} from '../overlay/position/viewport-ruler';
import {RIPPLE_FADE_OUT_DURATION, RIPPLE_FADE_IN_DURATION} from './ripple-renderer';
import {dispatchMouseEvent} from '../testing/dispatch-events';


/** Creates a DOM mouse event. */
const createMouseEvent = (eventType: string, dict: any = {}) => {
// Ideally this would just be "return new MouseEvent(eventType, dict)". But IE11 doesn't support
// the MouseEvent constructor, and Edge inexplicably divides clientX and clientY by 100 to get
// pageX and pageY. (Really. After "e = new MouseEvent('click', {clientX: 200, clientY: 300})",
// e.clientX is 200, e.pageX is 2, e.clientY is 300, and e.pageY is 3.)
// So instead we use the deprecated createEvent/initMouseEvent API, which works everywhere.
const event = document.createEvent('MouseEvents');
event.initMouseEvent(eventType,
false, /* canBubble */
false, /* cancelable */
window, /* view */
0, /* detail */
dict.screenX || 0,
dict.screenY || 0,
dict.clientX || 0,
dict.clientY || 0,
false, /* ctrlKey */
false, /* altKey */
false, /* shiftKey */
false, /* metaKey */
0, /* button */
null /* relatedTarget */);
return event;
};

/** Extracts the numeric value of a pixel size string like '123px'. */
const pxStringToFloat = (s: string) => {
return parseFloat(s.replace('px', ''));
Expand Down Expand Up @@ -176,8 +149,8 @@ describe('MdRipple', () => {
const spy = jasmine.createSpy('zone unstable callback');
const subscription = fixture.ngZone.onUnstable.subscribe(spy);

dispatchMouseEvent('mousedown');
dispatchMouseEvent('mouseup');
dispatchMouseEvent(rippleTarget, 'mousedown');
dispatchMouseEvent(rippleTarget, 'mouseup');

expect(spy).not.toHaveBeenCalled();
subscription.unsubscribe();
Expand Down Expand Up @@ -314,20 +287,17 @@ describe('MdRipple', () => {
let alternateTrigger = fixture.debugElement.nativeElement
.querySelector('.alternateTrigger') as HTMLElement;

let mousedownEvent = createMouseEvent('mousedown');
let mouseupEvent = createMouseEvent('mouseup');

alternateTrigger.dispatchEvent(mousedownEvent);
alternateTrigger.dispatchEvent(mouseupEvent);
dispatchMouseEvent(alternateTrigger, 'mousedown');
dispatchMouseEvent(alternateTrigger, 'mouseup');

expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(0);

// Set the trigger element, and now events should create ripples.
controller.trigger = alternateTrigger;
fixture.detectChanges();

alternateTrigger.dispatchEvent(mousedownEvent);
alternateTrigger.dispatchEvent(mouseupEvent);
dispatchMouseEvent(alternateTrigger, 'mousedown');
dispatchMouseEvent(alternateTrigger, 'mouseup');

expect(rippleTarget.querySelectorAll('.mat-ripple-element').length).toBe(1);
});
Expand Down
6 changes: 3 additions & 3 deletions src/lib/core/style/focus-origin-monitor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('FocusOriginMonitor', () => {

it('should detect focus via keyboard', async(() => {
// Simulate focus via keyboard.
dispatchKeyboardEvent(document, TAB);
dispatchKeyboardEvent(document, 'keydown', TAB);
buttonElement.focus();
fixture.detectChanges();

Expand Down Expand Up @@ -95,7 +95,7 @@ describe('FocusOriginMonitor', () => {

it('should detect focus via touch', async(() => {
// Simulate focus via touch.
dispatchTouchstartEvent(buttonElement);
dispatchMouseEvent(buttonElement, 'touchstart');
buttonElement.focus();
fixture.detectChanges();

Expand Down Expand Up @@ -272,7 +272,7 @@ describe('cdkMonitorFocus', () => {

it('should detect focus via keyboard', async(() => {
// Simulate focus via keyboard.
dispatchKeyboardEvent(document, TAB, 'keydown');
dispatchKeyboardEvent(document, 'keydown', TAB);
buttonElement.focus();
fixture.detectChanges();

Expand Down
14 changes: 4 additions & 10 deletions src/lib/core/testing/dispatch-events.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import {
createFakeEvent,
createKeyboardEvent,
createMouseEvent,
createTransitionEndEvent
createMouseEvent
} from './event-objects';

/** Shorthand to dispatch a fake event on a specified node. */
export function dispatchFakeEvent(node: Node, eventName: string) {
node.dispatchEvent(createFakeEvent(eventName));
export function dispatchFakeEvent(node: Node, type: string) {
node.dispatchEvent(createFakeEvent(type));
}

/** Shorthand to dispatch a keyboard event with a specified key code. */
export function dispatchKeyboardEvent(node: Node, keyCode: number, type = 'keydown') {
export function dispatchKeyboardEvent(node: Node, type: string, keyCode: number) {
node.dispatchEvent(createKeyboardEvent(type, keyCode));
}

/** Shorthand to dispatch a mouse event on the specified coordinates. */
export function dispatchMouseEvent(node: Node, type: string, x = 0, y = 0) {
node.dispatchEvent(createMouseEvent(type, x, y));
}

/** Shorthand to dispatch a transition event with a specified property. */
export function dispatchTransitionEndEvent(node: Node, propertyName: string, elapsedTime = 0) {
node.dispatchEvent(createTransitionEndEvent(propertyName, elapsedTime));
}
24 changes: 4 additions & 20 deletions src/lib/core/testing/event-objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ export function createMouseEvent(type: string, x = 0, y = 0) {
}

/** Dispatches a keydown event from an element. */
export function createKeyboardEvent(eventType: string, keyCode: number) {
export function createKeyboardEvent(type: string, keyCode: number) {
let event = document.createEvent('KeyboardEvent') as any;
// Firefox does not support `initKeyboardEvent`, but supports `initKeyEvent`.
let initEventFn = (event.initKeyEvent || event.initKeyboardEvent).bind(event);

initEventFn(eventType, true, true, window, 0, 0, 0, 0, 0, keyCode);
initEventFn(type, true, true, window, 0, 0, 0, 0, 0, keyCode);

// Webkit Browsers don't set the keyCode when calling the init function.
// See related bug https://bugs.webkit.org/show_bug.cgi?id=16735
Expand All @@ -38,25 +38,9 @@ export function createKeyboardEvent(eventType: string, keyCode: number) {
return event;
}

/** Creates a transition event with the specified property name. */
export function createTransitionEndEvent(propertyName: string, elapsedTime = 0) {
// Some browsers have the TransitionEvent class, but once the class is being instantiated
// the browser will throw an exception. Those browsers don't support the constructor yet.
// To ensure that those browsers also work, the TransitionEvent is created by using the
// deprecated `initTransitionEvent` function.
try {
// TypeScript does not have valid types for the TransitionEvent class, so use `any`.
return new (TransitionEvent as any)('transitionend', {propertyName, elapsedTime});
} catch (e) {
let event = document.createEvent('TransitionEvent');
event.initTransitionEvent('transitionend', false, false, propertyName, elapsedTime);
return event;
}
}

/** Creates a fake event object with any desired event type. */
export function createFakeEvent(eventName: string) {
export function createFakeEvent(type: string) {
let event = document.createEvent('Event');
event.initEvent(eventName, true, true);
event.initEvent(type, true, true);
return event;
}
17 changes: 3 additions & 14 deletions src/lib/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {MdDialogContainer} from './dialog-container';
import {OverlayContainer, ESCAPE} from '../core';
import {MdDialogRef} from './dialog-ref';
import {MD_DIALOG_DATA} from './dialog-injector';
import {dispatchKeyboardEvent} from '../core/testing/dispatch-events';


describe('MdDialog', () => {
Expand Down Expand Up @@ -130,7 +131,7 @@ describe('MdDialog', () => {
viewContainerRef: testViewContainerRef
});

dispatchKeydownEvent(document, ESCAPE);
dispatchKeyboardEvent(document, 'keydown', ESCAPE);
viewContainerFixture.detectChanges();

viewContainerFixture.whenStable().then(() => {
Expand Down Expand Up @@ -366,7 +367,7 @@ describe('MdDialog', () => {
});

viewContainerFixture.detectChanges();
dispatchKeydownEvent(document, ESCAPE);
dispatchKeyboardEvent(document, 'keydown', ESCAPE);

expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy();
});
Expand Down Expand Up @@ -613,15 +614,3 @@ const TEST_DIRECTIVES = [
],
})
class DialogTestModule { }


// TODO(crisbeto): switch to using function from common testing utils once #2943 is merged.
function dispatchKeydownEvent(element: Node, keyCode: number) {
let event: any = document.createEvent('KeyboardEvent');
(event.initKeyEvent || event.initKeyboardEvent).bind(event)(
'keydown', true, true, window, 0, 0, 0, 0, 0, keyCode);
Object.defineProperty(event, 'keyCode', {
get: function() { return keyCode; }
});
element.dispatchEvent(event);
}
7 changes: 0 additions & 7 deletions src/lib/slide-toggle/slide-toggle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,10 +684,3 @@ class SlideToggleFormsTestApp {
class SlideToggleWithFormControl {
formControl = new FormControl();
}

// TODO(devversion): replace with global utility once pull request #2943 is merged.
function dispatchFakeEvent(element: HTMLElement, eventName: string): void {
let event = document.createEvent('Event');
event.initEvent(eventName, true, true);
element.dispatchEvent(event);
}
30 changes: 15 additions & 15 deletions src/lib/slider/slider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ describe('MdSlider', () => {
it('should update the model on keydown', () => {
expect(testComponent.val).toBe(0);

dispatchKeyboardEvent(sliderNativeElement, UP_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', UP_ARROW);
fixture.detectChanges();

expect(testComponent.val).toBe(1);
Expand Down Expand Up @@ -949,14 +949,14 @@ describe('MdSlider', () => {
});

it('should increment slider by 1 on up arrow pressed', () => {
dispatchKeyboardEvent(sliderNativeElement, UP_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', UP_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(1);
});

it('should increment slider by 1 on right arrow pressed', () => {
dispatchKeyboardEvent(sliderNativeElement, RIGHT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', RIGHT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(1);
Expand All @@ -965,7 +965,7 @@ describe('MdSlider', () => {
it('should decrement slider by 1 on down arrow pressed', () => {
sliderInstance.value = 100;

dispatchKeyboardEvent(sliderNativeElement, DOWN_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', DOWN_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(99);
Expand All @@ -974,14 +974,14 @@ describe('MdSlider', () => {
it('should decrement slider by 1 on left arrow pressed', () => {
sliderInstance.value = 100;

dispatchKeyboardEvent(sliderNativeElement, LEFT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(99);
});

it('should increment slider by 10 on page up pressed', () => {
dispatchKeyboardEvent(sliderNativeElement, PAGE_UP);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', PAGE_UP);
fixture.detectChanges();

expect(sliderInstance.value).toBe(10);
Expand All @@ -990,14 +990,14 @@ describe('MdSlider', () => {
it('should decrement slider by 10 on page down pressed', () => {
sliderInstance.value = 100;

dispatchKeyboardEvent(sliderNativeElement, PAGE_DOWN);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', PAGE_DOWN);
fixture.detectChanges();

expect(sliderInstance.value).toBe(90);
});

it('should set slider to max on end pressed', () => {
dispatchKeyboardEvent(sliderNativeElement, END);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', END);
fixture.detectChanges();

expect(sliderInstance.value).toBe(100);
Expand All @@ -1006,7 +1006,7 @@ describe('MdSlider', () => {
it('should set slider to min on home pressed', () => {
sliderInstance.value = 100;

dispatchKeyboardEvent(sliderNativeElement, HOME);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', HOME);
fixture.detectChanges();

expect(sliderInstance.value).toBe(0);
Expand Down Expand Up @@ -1067,7 +1067,7 @@ describe('MdSlider', () => {
testComponent.invert = true;
fixture.detectChanges();

dispatchKeyboardEvent(sliderNativeElement, RIGHT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', RIGHT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(1);
Expand All @@ -1078,7 +1078,7 @@ describe('MdSlider', () => {
sliderInstance.value = 100;
fixture.detectChanges();

dispatchKeyboardEvent(sliderNativeElement, LEFT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(99);
Expand All @@ -1089,7 +1089,7 @@ describe('MdSlider', () => {
sliderInstance.value = 100;
fixture.detectChanges();

dispatchKeyboardEvent(sliderNativeElement, RIGHT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', RIGHT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(99);
Expand All @@ -1099,7 +1099,7 @@ describe('MdSlider', () => {
testComponent.dir = 'rtl';
fixture.detectChanges();

dispatchKeyboardEvent(sliderNativeElement, LEFT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(1);
Expand All @@ -1111,7 +1111,7 @@ describe('MdSlider', () => {
sliderInstance.value = 100;
fixture.detectChanges();

dispatchKeyboardEvent(sliderNativeElement, RIGHT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', RIGHT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(99);
Expand All @@ -1122,7 +1122,7 @@ describe('MdSlider', () => {
testComponent.invert = true;
fixture.detectChanges();

dispatchKeyboardEvent(sliderNativeElement, LEFT_ARROW);
dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW);
fixture.detectChanges();

expect(sliderInstance.value).toBe(1);
Expand Down
Loading

0 comments on commit 250204d

Please sign in to comment.