1 <!doctype html>
2 <html>
3 <head>
4 <script src="../../http/tests/inspector/resources/inspector-test.js"></script>
5 <script src="../debugger/resources/log-active-stack-trace.js"></script>
6 <script>
7 function handleBody_click(event) {
8 TestPage.dispatchEventToFrontend("TestPageBody-click");
9 }
10
11 function handleBody_custom(event) {
12 TestPage.dispatchEventToFrontend("TestPageBody-custom");
13 }
14
15 function handleX_click(event) {
16 TestPage.dispatchEventToFrontend("TestPageX-click");
17 }
18
19 function bodyFire_click() {
20 document.body.click();
21 }
22
23 function bodyFire_custom() {
24 document.body.dispatchEvent(new Event("custom"));
25 }
26
27 function xFire_click() {
28 document.getElementById("x").click();
29 }
30
31 function test() {
32 let suite = InspectorTest.createAsyncSuite("DOMDebugger.Event");
33
34 function teardown(resolve, reject) {
35 let breakpoints = WI.domDebuggerManager.eventBreakpoints;
36 for (let breakpoint of breakpoints)
37 WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
38
39 resolve();
40 }
41
42 function awaitBodyEvent(eventName) {
43 return function() {
44 InspectorTest.log(`Firing "${eventName}" on body...`);
45 return InspectorTest.evaluateInPage(`bodyFire_${eventName}()`);
46 };
47 }
48
49 function failOnPause(resolve, eventName, message) {
50 let paused = false;
51
52 let listener = WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
53 paused = true;
54
55 let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);
56 InspectorTest.assert(targetData.pauseReason === WI.DebuggerManager.PauseReason.EventListener, "Pause reason should be EventListener.");
57 InspectorTest.assert(targetData.pauseData.eventName === eventName, `Pause data eventName should be "${eventName}".`);
58
59 InspectorTest.fail(message);
60 logActiveStackTrace();
61
62 WI.debuggerManager.resume()
63 .catch((reason) => {
64 InspectorTest.fail(reason);
65 resolve();
66 });
67 });
68
69 InspectorTest.singleFireEventListener("TestPageBody-" + eventName, (event) => {
70 if (!paused) {
71 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener);
72
73 InspectorTest.pass(message);
74 }
75
76 resolve();
77 });
78 }
79
80 function addBreakpoint(eventName) {
81 InspectorTest.log(`Adding "${eventName}" Event Breakpoint...`);
82
83 return new Promise((resolve, reject) => {
84 let breakpoint = new WI.EventBreakpoint(eventName);
85
86 WI.domDebuggerManager.awaitEvent(WI.DOMDebuggerManager.Event.EventBreakpointAdded)
87 .then((event) => {
88 InspectorTest.assert(event.data.breakpoint.eventName === eventName, "Breakpoint should be for expected event name.");
89 InspectorTest.assert(!breakpoint.disabled, "Breakpoint should not be disabled initially.");
90 resolve(breakpoint);
91 });
92
93 WI.domDebuggerManager.addEventBreakpoint(breakpoint);
94 });
95 }
96
97 function removeBreakpoint(breakpoint) {
98 InspectorTest.log(`Removing "${breakpoint.eventName}" Event Breakpoint...`);
99
100 return new Promise((resolve, reject) => {
101 WI.domDebuggerManager.awaitEvent(WI.DOMDebuggerManager.Event.EventBreakpointRemoved)
102 .then((event) => {
103 InspectorTest.assert(event.data.breakpoint === breakpoint, "Removed Breakpoint should be expected object.");
104 InspectorTest.assert(!WI.domDebuggerManager.eventBreakpoints.includes(breakpoint), "Breakpoint should not be in the list of breakpoints.");
105 resolve(breakpoint);
106 });
107
108 WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
109 });
110 }
111
112 function disableBreakpoint(breakpoint) {
113 InspectorTest.log(`Disabling "${breakpoint.eventName}" Event Breakpoint...`);
114
115 breakpoint.disabled = true;
116 return breakpoint;
117 }
118
119 function addTestCasesForEventName(eventName) {
120 suite.addTestCase({
121 name: `DOMDebugger.Event.AddBreakpoint "${eventName}"`,
122 description: "Check that the debugger pauses for enabled breakpoints.",
123 teardown,
124 test(resolve, reject) {
125 let paused = false;
126
127 let listener = WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
128 paused = true;
129
130 InspectorTest.pass("Should pause before event handler is run.");
131 logActiveStackTrace();
132
133 WI.debuggerManager.resume();
134 });
135
136 InspectorTest.singleFireEventListener(`TestPageBody-${eventName}`, (event) => {
137 if (!paused) {
138 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener);
139
140 InspectorTest.fail("Should pause before event handler is run.");
141 }
142
143 resolve();
144 });
145
146 addBreakpoint(eventName)
147 .then(awaitBodyEvent(eventName))
148 .catch(reject);
149 },
150 });
151
152 suite.addTestCase({
153 name: `DOMDebugger.Event.AddDisabledBreakpoint "${eventName}"`,
154 description: "Check that debugger does the not pause for disabled breakpoints.",
155 teardown,
156 test(resolve, reject) {
157 failOnPause(resolve, eventName, "Should not pause for disabled breakpoint.");
158
159 addBreakpoint(eventName)
160 .then(disableBreakpoint)
161 .then(awaitBodyEvent(eventName))
162 .catch(reject);
163 },
164 });
165
166 suite.addTestCase({
167 name: `DOMDebugger.Event.RemoveBreakpoint "${eventName}"`,
168 description: "Check that debugger does not pause for removed breakpoint.",
169 teardown,
170 test(resolve, reject) {
171 failOnPause(resolve, eventName, "Should not pause for removed breakpoint.");
172
173 addBreakpoint(eventName)
174 .then(removeBreakpoint)
175 .then(awaitBodyEvent(eventName))
176 .catch(reject);
177 },
178 });
179
180 suite.addTestCase({
181 name: `DOMDebugger.Event.RemoveDisabledBreakpoint "${eventName}"`,
182 description: "Check that a disabled breakpoint can be removed.",
183 teardown,
184 test(resolve, reject) {
185 failOnPause(resolve, eventName, "Should not pause for removed disabled breakpoint.");
186
187 addBreakpoint(eventName)
188 .then(disableBreakpoint)
189 .then(removeBreakpoint)
190 .then(awaitBodyEvent(eventName))
191 .catch(reject);
192 },
193 });
194
195 }
196
197 addTestCasesForEventName("click");
198 addTestCasesForEventName("custom");
199
200 suite.addTestCase({
201 name: `DOMDebugger.Event.AddMultipleBreakpoints`,
202 description: "Check that a single breakpoint pauses for every event of that type.",
203 teardown,
204 test(resolve, reject) {
205 let pauseCount = 0;
206
207 let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
208 ++pauseCount;
209
210 InspectorTest.pass("Should pause before event handler is run.");
211 logActiveStackTrace();
212
213 WI.debuggerManager.resume()
214 .catch((reason) => {
215 InspectorTest.fail(reason);
216 resolve();
217 });
218
219 if (pauseCount >= 2) {
220 WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, listener);
221
222 resolve();
223 }
224 });
225
226 addBreakpoint("click")
227 .then(() => {
228 InspectorTest.log("Firing \"click\" on div#x...");
229 return InspectorTest.evaluateInPage(`xFire_click()`);
230 })
231 .catch(reject);
232 },
233 });
234
235 suite.runTestCasesAndFinish();
236 }
237 </script>
238 </head>
239 <body onload="runTest()">
240 <p>Tests for Event Listener breakpoints.</p>
241 <div id="x"></div>
242 <script>
243 document.body.addEventListener("click", handleBody_click);
244 document.body.addEventListener("custom", handleBody_custom);
245
246 document.getElementById("x").addEventListener("click", handleX_click);
247 </script>
248 </body>
249 </html>