browser_mouseout_notification_panel.js (4975B)
1 "use strict"; 2 3 async function showNotification(aBrowser, aId) { 4 info(`Show notification ${aId}`); 5 let promise = BrowserTestUtils.waitForEvent( 6 PopupNotifications.panel, 7 "popupshown" 8 ); 9 let notification = PopupNotifications.show( 10 aBrowser /* browser */, 11 "test-notification-" + aId /* id */, 12 aId + ": Will you allow <> to perform this action?" /* message */, 13 null /* anchorID */, 14 { 15 label: "Main Action", 16 accessKey: "M", 17 callback: () => {}, 18 } /* mainAction */, 19 [ 20 { 21 label: "Secondary Action", 22 accessKey: "S", 23 callback: () => {}, 24 }, 25 ] /* secondaryActions */ 26 ); 27 await promise; 28 29 let rect = PopupNotifications.panel.getBoundingClientRect(); 30 return { notification, rect }; 31 } 32 33 function waitForMouseEvent(aType, aElement) { 34 return new Promise(resolve => { 35 aElement.addEventListener( 36 aType, 37 e => { 38 resolve({ 39 screenX: e.screenX, 40 screenY: e.screenY, 41 clientX: e.clientX, 42 clientY: e.clientY, 43 }); 44 }, 45 { once: true } 46 ); 47 }); 48 } 49 50 function waitForRemoteMouseEvent(aType, aBrowser) { 51 return SpecialPowers.spawn(aBrowser, [aType], async aType => { 52 return new Promise( 53 resolve => { 54 content.document.addEventListener(aType, e => { 55 resolve({ 56 screenX: e.screenX, 57 screenY: e.screenY, 58 clientX: e.clientX, 59 clientY: e.clientY, 60 }); 61 }); 62 }, 63 { once: true } 64 ); 65 }); 66 } 67 68 function executeSoonRemote(aBrowser) { 69 return SpecialPowers.spawn(aBrowser, [], () => { 70 return new Promise(resolve => { 71 SpecialPowers.executeSoon(resolve); 72 }); 73 }); 74 } 75 76 function synthesizeMouseAtCenter(aRect) { 77 EventUtils.synthesizeMouseAtPoint( 78 aRect.left + aRect.width / 2, 79 aRect.top + aRect.height / 2, 80 { 81 type: "mousemove", 82 } 83 ); 84 } 85 86 let notificationRect; 87 88 add_setup(async function init() { 89 ok(PopupNotifications, "PopupNotifications object exists"); 90 ok(PopupNotifications.panel, "PopupNotifications panel exists"); 91 92 await SpecialPowers.pushPrefEnv({ 93 set: [ 94 ["test.wait300msAfterTabSwitch", true], 95 ["test.events.async.enabled", true], 96 // This test aims to synthesize mousemove events at specific times, so 97 // disable the automatically synthesized mousemove events during reflow. 98 ["layout.reflow.synthMouseMove", false], 99 ], 100 }); 101 102 info(`Show notification to get its size and position`); 103 let { notification, rect } = await showNotification( 104 gBrowser.selectedBrowser, 105 "Test#Init" 106 ); 107 PopupNotifications.remove(notification); 108 notificationRect = rect; 109 }); 110 111 add_task(async function test_mouseout_chrome() { 112 await BrowserTestUtils.withNewTab("about:blank", async browser => { 113 info(`Generate mousemove event on browser`); 114 let mousemovePromise = waitForMouseEvent("mousemove", browser); 115 synthesizeMouseAtCenter(notificationRect); 116 let mousemoveCoordinate = await mousemovePromise; 117 info(`mousemove event: ${JSON.stringify(mousemoveCoordinate)}`); 118 119 info(`Showing notification should generate mouseout event on browser`); 120 let mouseoutPromise = waitForMouseEvent("mouseout", browser); 121 let { notification } = await showNotification(browser, "Test#Chrome"); 122 synthesizeMouseAtCenter(notificationRect); 123 let mouseoutCoordinate = await mouseoutPromise; 124 info(`mouseout event: ${JSON.stringify(mouseoutCoordinate)}`); 125 126 SimpleTest.isDeeply( 127 mouseoutCoordinate, 128 mousemoveCoordinate, 129 "Test event coordinate" 130 ); 131 info(`Remove notification`); 132 PopupNotifications.remove(notification); 133 }); 134 }); 135 136 add_task(async function test_mouseout_content() { 137 await BrowserTestUtils.withNewTab("about:blank", async browser => { 138 info(`Generate mousemove event on content`); 139 let mousemovePromise = waitForRemoteMouseEvent("mousemove", browser); 140 // Ensure the event listener is registered in remote before synthesizing mouse event. 141 await executeSoonRemote(browser); 142 synthesizeMouseAtCenter(notificationRect); 143 let mousemoveCoordinate = await mousemovePromise; 144 info(`mousemove event on content: ${JSON.stringify(mousemoveCoordinate)}`); 145 146 info(`Showing notification should generate mouseout event on content`); 147 let mouseoutPromise = waitForRemoteMouseEvent("mouseout", browser); 148 // Ensure the event listener is registered in remote before showing notification. 149 await executeSoonRemote(browser); 150 let { notification } = await showNotification(browser, "Test#Content"); 151 synthesizeMouseAtCenter(notificationRect); 152 let mouseoutCoordinate = await mouseoutPromise; 153 info(`remote mouseout event: ${JSON.stringify(mouseoutCoordinate)}`); 154 155 SimpleTest.isDeeply( 156 mouseoutCoordinate, 157 mousemoveCoordinate, 158 "Test event coordinate" 159 ); 160 info(`Remove notification`); 161 PopupNotifications.remove(notification); 162 }); 163 });