Skip to content

Commit d7b1bbe

Browse files
devversionjelbourn
authored andcommitted
feat(cdk/testing/testbed): emit pointer events for test element click
Currently, test elements for the testbed harness environment only emit `mousedown` and `mouseup` events when a click is simulated. Authors of components technically could already rely on the more convenient pointer events. To handle this, we also emit pointer events similar to what actual browsers do.
1 parent 328de59 commit d7b1bbe

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

src/cdk/testing/testbed/fake-events/dispatch-events.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
createFakeEvent,
1212
createKeyboardEvent,
1313
createMouseEvent,
14+
createPointerEvent,
1415
createTouchEvent,
1516
} from './event-objects';
1617

@@ -49,6 +50,15 @@ export function dispatchMouseEvent(node: Node, type: string, clientX = 0, client
4950
return dispatchEvent(node, createMouseEvent(type, clientX, clientY));
5051
}
5152

53+
/**
54+
* Shorthand to dispatch a pointer event on the specified coordinates.
55+
* @docs-private
56+
*/
57+
export function dispatchPointerEvent(node: Node, type: string, clientX = 0, clientY = 0,
58+
options?: PointerEventInit): PointerEvent {
59+
return dispatchEvent(node, createPointerEvent(type, clientX, clientY, options)) as PointerEvent;
60+
}
61+
5262
/**
5363
* Shorthand to dispatch a touch event on the specified coordinates.
5464
* @docs-private

src/cdk/testing/testbed/fake-events/event-objects.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@ export function createMouseEvent(type: string, clientX = 0, clientY = 0, button
5252
return event;
5353
}
5454

55+
/**
56+
* Creates a browser `PointerEvent` with the specified options. Pointer events
57+
* by default will appear as if they are the primary pointer of their type.
58+
* https://www.w3.org/TR/pointerevents2/#dom-pointerevent-isprimary.
59+
*
60+
* For example, if pointer events for a multi-touch interaction are created, the non-primary
61+
* pointer touches would need to be represented by non-primary pointer events.
62+
*
63+
* @docs-private
64+
*/
65+
export function createPointerEvent(type: string, clientX = 0, clientY = 0,
66+
options: PointerEventInit = {isPrimary: true}) {
67+
return new PointerEvent(type, {
68+
bubbles: true,
69+
cancelable: true,
70+
view: window,
71+
clientX,
72+
clientY,
73+
...options,
74+
});
75+
}
76+
5577
/**
5678
* Creates a browser TouchEvent with the specified pointer coordinates.
5779
* @docs-private

src/cdk/testing/testbed/unit-test-element.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {ElementDimensions, ModifierKeys, TestElement, TestKey} from '@angular/cd
1111
import {
1212
clearElement,
1313
dispatchMouseEvent,
14+
dispatchPointerEvent,
1415
isTextInput,
1516
triggerBlur,
1617
triggerFocus,
@@ -77,9 +78,23 @@ export class UnitTestElement implements TestElement {
7778
// supported by mouse events and could lead to unexpected results.
7879
const clientX = Math.round(left + relativeX);
7980
const clientY = Math.round(top + relativeY);
81+
82+
// The latest versions of all browsers we support have the new `PointerEvent` API.
83+
// Though since we capture the two most recent versions of these browsers, we also
84+
// need to support Safari 12 at time of writing. Safari 12 does not have support for this,
85+
// so we need to conditionally create and dispatch these events based on feature detection.
86+
const emitPointerEvents = window.PointerEvent !== undefined;
87+
88+
if (emitPointerEvents) {
89+
dispatchPointerEvent(this.element, 'pointerdown', clientX, clientY);
90+
}
8091
dispatchMouseEvent(this.element, 'mousedown', clientX, clientY);
92+
if (emitPointerEvents) {
93+
dispatchMouseEvent(this.element, 'pointerup', clientX, clientY);
94+
}
8195
dispatchMouseEvent(this.element, 'mouseup', clientX, clientY);
8296
dispatchMouseEvent(this.element, 'click', clientX, clientY);
97+
8398
await this._stabilize();
8499
}
85100

0 commit comments

Comments
 (0)