browser_pointerlock_popup.js (4698B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 6 "use strict"; 7 8 const TEST_URL = 9 "data:text/html,<body><div style='width: 100px; height: 100px; background-color: red;'></div></body>"; 10 11 function waitForEventRemote(aRemote, aEvent) { 12 info(`Wait for ${aEvent} event`); 13 return SpecialPowers.spawn(aRemote, [aEvent], function (aEvent) { 14 return new Promise(resolve => { 15 content.document.addEventListener( 16 aEvent, 17 _e => { 18 info(`Received ${aEvent} event`); 19 resolve(); 20 }, 21 { once: true } 22 ); 23 }); 24 }); 25 } 26 27 function executeSoonRemote(aRemote) { 28 return SpecialPowers.spawn(aRemote, [], function () { 29 return new Promise(resolve => { 30 SpecialPowers.executeSoon(resolve); 31 }); 32 }); 33 } 34 35 function requestPointerLockRemote(aRemote) { 36 info(`Request pointerlock`); 37 return SpecialPowers.spawn(aRemote, [], function () { 38 SpecialPowers.wrap(content.document).notifyUserGestureActivation(); 39 content.document.body.requestPointerLock(); 40 }); 41 } 42 43 function exitPointerLockRemote(aRemote) { 44 info(`Exit pointerlock`); 45 return SpecialPowers.spawn(aRemote, [], function () { 46 return new Promise(resolve => { 47 if (!content.document.pointerLockElement) { 48 resolve(); 49 return; 50 } 51 52 content.document.addEventListener( 53 "pointerlockchange", 54 _e => { 55 info(`Received pointerlockchange event`); 56 resolve(); 57 }, 58 { once: true } 59 ); 60 content.document.exitPointerLock(); 61 }); 62 }); 63 } 64 65 function isPointerLockedRemote(aRemote) { 66 return SpecialPowers.spawn(aRemote, [], function () { 67 return !!content.document.pointerLockElement; 68 }); 69 } 70 71 function getPopup(aDocument, aPopupType) { 72 let popup = aDocument.getElementById(aPopupType); 73 if (!popup) { 74 let menuitem = aDocument.createXULElement("menuitem"); 75 menuitem.label = "This is a test popup"; 76 77 popup = aDocument.createXULElement(aPopupType); 78 popup.id = aPopupType; 79 popup.appendChild(menuitem); 80 aDocument.documentElement.appendChild(popup); 81 } 82 return popup; 83 } 84 85 async function waitForPopupOpen(aDocument, aPopupType) { 86 let popup = getPopup(aDocument, aPopupType); 87 let promise = BrowserTestUtils.waitForPopupEvent(popup, "shown"); 88 popup.openPopup(); 89 await promise; 90 91 return popup; 92 } 93 94 async function waitForPopupHide(aPopup) { 95 let promise = BrowserTestUtils.waitForPopupEvent(aPopup, "hidden"); 96 aPopup.hidePopup(true); 97 await promise; 98 } 99 100 function testPointerLockPopup(aPopupType, aShouldBlockPointerLock) { 101 add_task(async function test_open_menu_popup_when_pointer_is_locked() { 102 info(`Test ${aPopupType}`); 103 await BrowserTestUtils.withNewTab(TEST_URL, async browser => { 104 let promise = waitForEventRemote(browser, "pointerlockchange"); 105 await requestPointerLockRemote(browser); 106 await promise; 107 ok(await isPointerLockedRemote(browser), "pointer should be locked"); 108 109 if (aShouldBlockPointerLock) { 110 promise = waitForEventRemote(browser, "pointerlockchange"); 111 // Wait for the event listener to get registered on the remote. 112 await executeSoonRemote(browser); 113 } 114 115 info(`Open popup`); 116 let popup = await waitForPopupOpen(document, aPopupType); 117 118 if (!aShouldBlockPointerLock) { 119 promise = executeSoonRemote(browser); 120 } 121 122 await promise; 123 is( 124 await isPointerLockedRemote(browser), 125 !aShouldBlockPointerLock, 126 "check if pointer is still locked" 127 ); 128 129 await exitPointerLockRemote(browser); 130 131 info(`Hide popup`); 132 await waitForPopupHide(popup); 133 }); 134 }); 135 136 add_task(async function test_request_pointerlock_when_popup_is_opened() { 137 info(`Test ${aPopupType}`); 138 await BrowserTestUtils.withNewTab(TEST_URL, async browser => { 139 info(`Open popup`); 140 let popup = await waitForPopupOpen(document, aPopupType); 141 142 let promise = aShouldBlockPointerLock 143 ? waitForEventRemote(browser, "pointerlockerror") 144 : waitForEventRemote(browser, "pointerlockchange"); 145 // Wait for the event listener to get registered on the remote. 146 await executeSoonRemote(browser); 147 await requestPointerLockRemote(browser); 148 await promise; 149 is( 150 await isPointerLockedRemote(browser), 151 !aShouldBlockPointerLock, 152 "check if pointer is still locked" 153 ); 154 155 await exitPointerLockRemote(browser); 156 157 info(`Hide popup`); 158 await waitForPopupHide(popup); 159 }); 160 }); 161 } 162 163 testPointerLockPopup("menupopup", true); 164 testPointerLockPopup("panel", true); 165 testPointerLockPopup("tooltip", false);