browser_EventUtils.js (7986B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 "use strict"; 4 5 const gChromeBaseURL = getRootDirectory(gTestPath); 6 const gBaseURL = gChromeBaseURL.replace( 7 "chrome://mochitests/content", 8 "https://example.com" 9 ); 10 11 async function synthesizeMouseFromParent( 12 aBrowser, 13 aOffsetX, 14 aOffsetY, 15 aAsyncEnabled 16 ) { 17 info( 18 `synthesizeMouse with asyncEnabled=${aAsyncEnabled} from parent process` 19 ); 20 21 let haveReceiveMouseEvent = false; 22 const onMousemove = event => { 23 info( 24 `Received mouse event: ${event.type} ${event.offsetX} ${event.offsetY} ${event.button} ${event.buttons}` 25 ); 26 haveReceiveMouseEvent = true; 27 }; 28 aBrowser.addEventListener("mousemove", onMousemove, { once: true }); 29 await new Promise(resolve => { 30 EventUtils.synthesizeMouse( 31 aBrowser, 32 aOffsetX, 33 aOffsetY, 34 { 35 type: "mousemove", 36 asyncEnabled: aAsyncEnabled, 37 }, 38 window, 39 () => { 40 ok(haveReceiveMouseEvent, "Should have received mouse event"); 41 aBrowser.removeEventListener("mousemove", onMousemove); 42 resolve(); 43 } 44 ); 45 }); 46 } 47 48 add_task(async function synthesizeEventFromParent() { 49 async function testSynthesizeWheelFromParent(aBrowser, aAsyncEnabled) { 50 info(`Testing synthesizeWheel with asyncEnabled=${aAsyncEnabled}`); 51 52 let haveReceiveWheelEvent = false; 53 const onWheel = event => { 54 info( 55 `Received wheel event: ${event.type} ${event.deltaX} ${event.deltaY} ${event.deltaZ} ${event.deltaMode} ${event.detail}` 56 ); 57 haveReceiveWheelEvent = true; 58 }; 59 aBrowser.addEventListener("wheel", onWheel, { once: true }); 60 await new Promise(resolve => { 61 EventUtils.synthesizeWheel( 62 aBrowser, 63 10, 64 10, 65 { 66 deltaMode: WheelEvent.DOM_DELTA_LINE, 67 deltaY: 1.0, 68 asyncEnabled: aAsyncEnabled, 69 }, 70 window, 71 () => { 72 ok(haveReceiveWheelEvent, "Should have received wheel event"); 73 aBrowser.removeEventListener("wheel", onWheel); 74 resolve(); 75 } 76 ); 77 }); 78 } 79 80 async function testSynthesizeMouseFromParent(aBrowser, aAsyncEnabled) { 81 info(`Testing synthesizeMouse with asyncEnabled=${aAsyncEnabled}`); 82 83 // Should throw error if the synthesized mouse evet might be coaslesced. 84 await new Promise(resolve => { 85 try { 86 EventUtils.synthesizeMouse( 87 aBrowser, 88 10, 89 10, 90 { 91 type: "mousemove", 92 asyncEnabled: aAsyncEnabled, 93 isSynthesized: false, 94 }, 95 window, 96 () => { 97 ok(false, "callback should not be called"); 98 } 99 ); 100 ok(false, "synthesizeMouse with should throw"); 101 } catch (e) { 102 ok(true, `synthesizeMouse should throw error: ${e}`); 103 } 104 // Wait a bit to ensure the callback is not called. 105 SimpleTest.executeSoon(resolve); 106 }); 107 108 await synthesizeMouseFromParent(aBrowser, 10, 10, aAsyncEnabled); 109 } 110 111 await BrowserTestUtils.withNewTab( 112 gBaseURL + "dummy.html", 113 async function (browser) { 114 await testSynthesizeWheelFromParent(browser, false); 115 await testSynthesizeWheelFromParent(browser, true); 116 await testSynthesizeMouseFromParent(browser, false); 117 await testSynthesizeMouseFromParent(browser, true); 118 } 119 ); 120 }); 121 122 add_task(async function synthesizeEventFromContent() { 123 async function testSynthesizeWheelFromContent(aBrowser, aAsyncEnabled) { 124 info(`Testing synthesizeWheel with asyncEnabled=${aAsyncEnabled}`); 125 126 await SpecialPowers.spawn( 127 aBrowser, 128 [aAsyncEnabled], 129 async aAsyncEnabled => { 130 let haveReceiveWheelEvent = false; 131 const onWheel = event => { 132 info( 133 `Received wheel event: ${event.type} ${event.deltaX} ${event.deltaY} ${event.deltaZ} ${event.deltaMode} ${event.detail}` 134 ); 135 haveReceiveWheelEvent = true; 136 }; 137 content.document.addEventListener("wheel", onWheel, { once: true }); 138 await new Promise(resolve => { 139 try { 140 EventUtils.synthesizeWheel( 141 content.document.body, 142 10, 143 10, 144 { 145 deltaMode: content.WheelEvent.DOM_DELTA_LINE, 146 deltaY: 1.0, 147 asyncEnabled: aAsyncEnabled, 148 }, 149 content.window, 150 () => { 151 ok(haveReceiveWheelEvent, "Should have received wheel event"); 152 content.document.removeEventListener("wheel", onWheel); 153 resolve(); 154 } 155 ); 156 ok(!aAsyncEnabled, "synthesizeWheel should not throw"); 157 } catch (e) { 158 ok(aAsyncEnabled, `synthesizeWheel should throw error: ${e}`); 159 content.document.removeEventListener("wheel", onWheel); 160 resolve(); 161 } 162 }); 163 } 164 ); 165 } 166 167 async function testSynthesizeMouseFromContent(aBrowser) { 168 info(`Testing synthesizeMouse`); 169 170 await SpecialPowers.spawn(aBrowser, [], async () => { 171 try { 172 EventUtils.synthesizeMouse( 173 content.document.body, 174 10, 175 10, 176 { 177 type: "mousemove", 178 }, 179 content.window, 180 () => { 181 ok(false, "callback should not be called"); 182 } 183 ); 184 ok(false, "synthesizeMouse should not throw"); 185 } catch (e) { 186 ok(true, `synthesizeMouse should throw error: ${e}`); 187 } 188 }); 189 } 190 191 await BrowserTestUtils.withNewTab( 192 gBaseURL + "dummy.html", 193 async function (browser) { 194 await testSynthesizeWheelFromContent(browser, false); 195 await testSynthesizeWheelFromContent(browser, true); 196 await testSynthesizeMouseFromContent(browser); 197 } 198 ); 199 }); 200 201 add_task(async function testCallbackForCrossProcressIframe() { 202 const iframeBaseURL = gChromeBaseURL.replace( 203 "chrome://mochitests/content", 204 "https://example.org/" 205 ); 206 207 async function synthesizeMouseFromParentAndWait( 208 aBrowser, 209 aOffsetX, 210 aOffsetY, 211 aBrowsingContext 212 ) { 213 let eventPromise = SpecialPowers.spawn(aBrowsingContext, [], async () => { 214 await new Promise(resolve => { 215 content.document.addEventListener( 216 "mousemove", 217 () => { 218 info("Received mousemove event in the target browsing context"); 219 resolve(); 220 }, 221 { once: true } 222 ); 223 }); 224 }); 225 // Enuse the event listener is registered on remote target. 226 await SpecialPowers.spawn(aBrowsingContext, [], async () => { 227 await new Promise(resolve => { 228 SpecialPowers.executeSoon(resolve); 229 }); 230 }); 231 232 await Promise.all([ 233 synthesizeMouseFromParent(aBrowser, aOffsetX, aOffsetY, true), 234 eventPromise, 235 ]); 236 } 237 238 await BrowserTestUtils.withNewTab( 239 gBaseURL + "empty.html", 240 async function (browser) { 241 // Synthesize mouse event to the parent document. 242 await synthesizeMouseFromParentAndWait( 243 browser, 244 10, 245 5, 246 browser.browsingContext 247 ); 248 249 // Add an iframe. 250 await SpecialPowers.spawn( 251 browser, 252 [iframeBaseURL + "empty.html"], 253 async url => { 254 content.document.body.appendChild( 255 content.document.createElement("br") 256 ); 257 let iframe = content.document.createElement("iframe"); 258 iframe.src = url; 259 let loadPromise = new Promise(resolve => { 260 iframe.addEventListener("load", resolve, { once: true }); 261 }); 262 content.document.body.appendChild(iframe); 263 await loadPromise; 264 } 265 ); 266 267 // Synthesize mouse event to the iframe document. 268 await synthesizeMouseFromParentAndWait( 269 browser, 270 10, 271 35, 272 browser.browsingContext.children[0] 273 ); 274 } 275 ); 276 });