Skip to content

Commit a38fcc2

Browse files
crisbetommalerba
authored andcommitted
fix(cdk/testing): fake events not propagating through shadow DOM
Adds the `composed` flag to the fake event objects so that they can propagate through a `mode: 'open'` shadow root. (cherry picked from commit 48df9d6)
1 parent e5c589d commit a38fcc2

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import {
2+
dispatchMouseEvent,
3+
dispatchKeyboardEvent,
4+
dispatchPointerEvent,
5+
dispatchFakeEvent,
6+
} from './dispatch-events';
17
import {createKeyboardEvent, createMouseEvent} from './event-objects';
28

39
describe('event objects', () => {
@@ -40,4 +46,70 @@ describe('event objects', () => {
4046
expect(preventDefaultSpy).toHaveBeenCalledTimes(2);
4147
});
4248
});
49+
50+
describe('shadow DOM', () => {
51+
it('should allow dispatched mouse events to propagate through the shadow root', () => {
52+
if (!testElement.attachShadow) {
53+
return;
54+
}
55+
56+
const spy = jasmine.createSpy('listener');
57+
const shadowRoot = testElement.attachShadow({mode: 'open'});
58+
const child = document.createElement('div');
59+
shadowRoot.appendChild(child);
60+
61+
testElement.addEventListener('mousedown', spy);
62+
dispatchMouseEvent(child, 'mousedown');
63+
64+
expect(spy).toHaveBeenCalled();
65+
});
66+
67+
it('should allow dispatched keyboard events to propagate through the shadow root', () => {
68+
if (!testElement.attachShadow) {
69+
return;
70+
}
71+
72+
const spy = jasmine.createSpy('listener');
73+
const shadowRoot = testElement.attachShadow({mode: 'open'});
74+
const child = document.createElement('div');
75+
shadowRoot.appendChild(child);
76+
77+
testElement.addEventListener('keydown', spy);
78+
dispatchKeyboardEvent(child, 'keydown');
79+
80+
expect(spy).toHaveBeenCalled();
81+
});
82+
83+
it('should allow dispatched pointer events to propagate through the shadow root', () => {
84+
if (!testElement.attachShadow) {
85+
return;
86+
}
87+
88+
const spy = jasmine.createSpy('listener');
89+
const shadowRoot = testElement.attachShadow({mode: 'open'});
90+
const child = document.createElement('div');
91+
shadowRoot.appendChild(child);
92+
93+
testElement.addEventListener('pointerdown', spy);
94+
dispatchPointerEvent(child, 'pointerdown');
95+
96+
expect(spy).toHaveBeenCalled();
97+
});
98+
99+
it('should allow dispatched fake events to propagate through the shadow root', () => {
100+
if (!testElement.attachShadow) {
101+
return;
102+
}
103+
104+
const spy = jasmine.createSpy('listener');
105+
const shadowRoot = testElement.attachShadow({mode: 'open'});
106+
const child = document.createElement('div');
107+
shadowRoot.appendChild(child);
108+
109+
testElement.addEventListener('fake', spy);
110+
dispatchFakeEvent(child, 'fake');
111+
112+
expect(spy).toHaveBeenCalled();
113+
});
114+
});
43115
});

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function createMouseEvent(
3232
const event = new MouseEvent(type, {
3333
bubbles: true,
3434
cancelable: true,
35+
composed: true, // Required for shadow DOM events.
3536
view: window,
3637
detail: 0,
3738
relatedTarget: null,
@@ -74,6 +75,7 @@ export function createPointerEvent(
7475
return new PointerEvent(type, {
7576
bubbles: true,
7677
cancelable: true,
78+
composed: true, // Required for shadow DOM events.
7779
view: window,
7880
clientX,
7981
clientY,
@@ -116,6 +118,7 @@ export function createKeyboardEvent(
116118
return new KeyboardEvent(type, {
117119
bubbles: true,
118120
cancelable: true,
121+
composed: true, // Required for shadow DOM events.
119122
view: window,
120123
keyCode: keyCode,
121124
key: key,
@@ -130,8 +133,8 @@ export function createKeyboardEvent(
130133
* Creates a fake event object with any desired event type.
131134
* @docs-private
132135
*/
133-
export function createFakeEvent(type: string, bubbles = false, cancelable = true) {
134-
return new Event(type, {bubbles, cancelable});
136+
export function createFakeEvent(type: string, bubbles = false, cancelable = true, composed = true) {
137+
return new Event(type, {bubbles, cancelable, composed});
135138
}
136139

137140
/**

0 commit comments

Comments
 (0)