browser_tooltip.js (4095B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const TEST_CONTENT = `<h1 title="test title" style="margin: 5px">test h1</h1>`; 7 const TEST_URL = `data:text/html;charset=utf-8,${TEST_CONTENT}`; 8 9 // Test for the tooltip coordinate on the browsing document in RDM. 10 11 addRDMTask(TEST_URL, async ({ ui }) => { 12 // Make this synthesize mouse events via the parent process because some 13 // code may cache the mouse cursor position like PresShell. That may prevent 14 // unexpected DOM events coming from the parent process. 15 await pushPref("test.events.async.enabled", true); 16 17 info("Create a promise which waits until the tooltip will be shown"); 18 const tooltip = ui.browserWindow.gBrowser.ownerDocument.getElementById( 19 "remoteBrowserTooltip" 20 ); 21 const onTooltipShown = BrowserTestUtils.waitForEvent(tooltip, "popupshown"); 22 const onTooltipHidden = BrowserTestUtils.waitForEvent(tooltip, "popuphidden"); 23 24 info("Show a tooltip"); 25 await spawnViewportTask(ui, {}, async () => { 26 const target = content.document.querySelector("h1"); 27 28 // First, make sure to move mouse cursor outside the target. 29 info("Waiting for initial mousemove"); 30 { 31 // FYI: Some `mousemove` events may not be sent to the content process 32 // until all preparations done in the main process and the content 33 // process. Therefore, we need to synthesize `mousemove`s until we 34 // get it in the remote process at least once. Therefore, we cannot 35 // use a promise to wait a `mousemove` here and we need to use the while 36 // loop below. 37 let mouseMoveFired = false; 38 content.document.addEventListener( 39 "mousemove", 40 event => { 41 isnot( 42 event.target, 43 target, 44 "The first mousemove should be fired outside the target" 45 ); 46 mouseMoveFired = true; 47 }, 48 { 49 once: true, 50 } 51 ); 52 while (!mouseMoveFired) { 53 await EventUtils.synthesizeMouse( 54 target, 55 -2, 56 -2, 57 { type: "mousemove" }, 58 content 59 ); 60 await EventUtils.synthesizeMouse( 61 target, 62 -1, 63 -1, 64 { type: "mousemove" }, 65 content 66 ); 67 // Wait for the tooltip for the target is hidden even if it was visible. 68 await new Promise(resolve => 69 content.window.requestAnimationFrame(() => 70 content.window.requestAnimationFrame(resolve) 71 ) 72 ); 73 } 74 } 75 76 const eventLogger = event => 77 info( 78 `${event.type}: path=[${event.composedPath()}], outerHTML=${ 79 event.target.outerHTML 80 }, relatedTarget=${event.relatedTarget?.outerHTML}` 81 ); 82 target.addEventListener("mouseover", eventLogger); 83 target.addEventListener("mouseout", eventLogger); 84 content.document.addEventListener("mousemove", eventLogger); 85 // Then, move cursor over the target. 86 await EventUtils.synthesizeMouse( 87 target, 88 1, 89 1, 90 { type: "mousemove", isSynthesized: false }, 91 content 92 ); 93 await EventUtils.synthesizeMouse( 94 target, 95 2, 96 1, 97 { type: "mousemove", isSynthesized: false }, 98 content 99 ); 100 await EventUtils.synthesizeMouse( 101 target, 102 3, 103 1, 104 { type: "mousemove", isSynthesized: false }, 105 content 106 ); 107 }); 108 109 info("Wait for showing the tooltip"); 110 await onTooltipShown; 111 112 info("Test the X coordinate of the tooltip"); 113 isnot(tooltip.screenX, 0, "The X coordinate of tooltip should not be 0"); 114 115 // Finally, clean up the tooltip if we're running in the verify mode. 116 info("Wait for hiding the tooltip"); 117 await spawnViewportTask(ui, {}, async () => { 118 info("Cleaning up the tooltip with moving the cursor"); 119 const target = content.document.querySelector("h1"); 120 await EventUtils.synthesizeMouse( 121 target, 122 -1, 123 -1, 124 { type: "mousemove", isSynthesized: false }, 125 content 126 ); 127 }); 128 await onTooltipHidden; 129 });