Skip to content

Commit

Permalink
refactor: cleanup fake event dispatch utilities (angular#19151)
Browse files Browse the repository at this point in the history
Cleans up the fake event dispatch utiltities:

1. `dispatchMouseEvent` accepts an actual mouse event. This has been
introduced with [this commit](04bf3d1).
If a mouse event has already been created, then it can be just
dispatched, but doesn't need to go through `dispatchMouseEvent` which
primarily is a shorthand for creating an event and dispatching it.

2. `dispatchEvent` helper should use a generic so that we don't
need to cast events unnecessarily.

3. `createMouseEvent` should not accept `x` and `y`. This is ambiguous.
It's not clear what coordinates are expected. To improve this,
parameters are now explicit, and a better comment has been added.
  • Loading branch information
devversion authored Apr 24, 2020
1 parent 70036cb commit ed4e91d
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
9 changes: 4 additions & 5 deletions src/cdk/testing/testbed/fake-events/dispatch-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
* Utility to dispatch any event on a Node.
* @docs-private
*/
export function dispatchEvent(node: Node | Window, event: Event): Event {
export function dispatchEvent<T extends Event>(node: Node | Window, event: T): T {
node.dispatchEvent(event);
return event;
}
Expand All @@ -38,16 +38,15 @@ export function dispatchFakeEvent(node: Node | Window, type: string, canBubble?:
export function dispatchKeyboardEvent(node: Node, type: string, keyCode?: number, key?: string,
target?: Element, modifiers?: ModifierKeys): KeyboardEvent {
return dispatchEvent(node,
createKeyboardEvent(type, keyCode, key, target, modifiers)) as KeyboardEvent;
createKeyboardEvent(type, keyCode, key, target, modifiers));
}

/**
* Shorthand to dispatch a mouse event on the specified coordinates.
* @docs-private
*/
export function dispatchMouseEvent(node: Node, type: string, x = 0, y = 0,
event = createMouseEvent(type, x, y)): MouseEvent {
return dispatchEvent(node, event) as MouseEvent;
export function dispatchMouseEvent(node: Node, type: string, clientX = 0, clientY = 0): MouseEvent {
return dispatchEvent(node, createMouseEvent(type, clientX, clientY));
}

/**
Expand Down
37 changes: 22 additions & 15 deletions src/cdk/testing/testbed/fake-events/event-objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,32 @@ import {ModifierKeys} from '@angular/cdk/testing';
* Creates a browser MouseEvent with the specified options.
* @docs-private
*/
export function createMouseEvent(type: string, x = 0, y = 0, button = 0) {
export function createMouseEvent(type: string, clientX = 0, clientY = 0, button = 0) {
const event = document.createEvent('MouseEvent');
const originalPreventDefault = event.preventDefault.bind(event);

// Note: We cannot determine the position of the mouse event based on the screen
// because the dimensions and position of the browser window are not available
// To provide reasonable `screenX` and `screenY` coordinates, we simply use the
// client coordinates as if the browser is opened in fullscreen.
const screenX = clientX;
const screenY = clientY;

event.initMouseEvent(type,
true, /* canBubble */
true, /* cancelable */
window, /* view */
0, /* detail */
x, /* screenX */
y, /* screenY */
x, /* clientX */
y, /* clientY */
false, /* ctrlKey */
false, /* altKey */
false, /* shiftKey */
false, /* metaKey */
button, /* button */
null /* relatedTarget */);
/* canBubble */ true,
/* cancelable */ true,
/* view */ window,
/* detail */ 0,
/* screenX */ screenX,
/* screenY */ screenY,
/* clientX */ clientX,
/* clientY */ clientY,
/* ctrlKey */ false,
/* altKey */ false,
/* shiftKey */ false,
/* metaKey */ false,
/* button */ button,
/* relatedTarget */ null);

// `initMouseEvent` doesn't allow us to pass the `buttons` and
// defaults it to 0 which looks like a fake event.
Expand Down
2 changes: 1 addition & 1 deletion src/material-experimental/mdc-menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2035,7 +2035,7 @@ describe('MDC-based MatMenu', () => {
Object.defineProperty(event, 'buttons', {get: () => 1});
event.preventDefault = jasmine.createSpy('preventDefault spy');

dispatchMouseEvent(overlay.querySelector('[mat-menu-item]')!, 'mousedown', 0, 0, event);
dispatchEvent(overlay.querySelector('[mat-menu-item]')!, event);
expect(event.preventDefault).toHaveBeenCalled();
});

Expand Down
4 changes: 2 additions & 2 deletions src/material/menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
dispatchFakeEvent,
dispatchKeyboardEvent,
dispatchMouseEvent,
patchElementFocus,
MockNgZone,
patchElementFocus,
} from '@angular/cdk/testing/private';
import {
ChangeDetectionStrategy,
Expand Down Expand Up @@ -2031,7 +2031,7 @@ describe('MatMenu', () => {
Object.defineProperty(event, 'buttons', {get: () => 1});
event.preventDefault = jasmine.createSpy('preventDefault spy');

dispatchMouseEvent(overlay.querySelector('[mat-menu-item]')!, 'mousedown', 0, 0, event);
dispatchEvent(overlay.querySelector('[mat-menu-item]')!, event);
expect(event.preventDefault).toHaveBeenCalled();
});

Expand Down

0 comments on commit ed4e91d

Please sign in to comment.