helper_touch_synthesized_mouseevents.html (2830B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <script src="apz_test_utils.js"></script> 6 <script src="apz_test_native_event_utils.js"></script> 7 <script src="/tests/SimpleTest/EventUtils.js"></script> 8 <script src="/tests/SimpleTest/paint_listener.js"></script> 9 <style> 10 html, body { margin: 0; } 11 12 #scrollable { 13 height: 50vh; 14 width: 50vw; 15 background: yellow; 16 overflow: scroll; 17 } 18 19 #scrollabletarget { 20 height: 200vh; 21 width: 200vh; 22 background: green; 23 } 24 25 #scrollabletarget:active { 26 background: red; 27 } 28 29 #notscrollable { 30 height: 50vh; 31 width: 50vw; 32 background: green; 33 } 34 35 #notscrollable:active { 36 background: red; 37 } 38 </style> 39 </head> 40 <body> 41 <div id="scrollable"> 42 <div id="scrollabletarget"> 43 </div> 44 </div> 45 <div id="notscrollable"> 46 </div> 47 </body> 48 <script> 49 50 const searchParams = new URLSearchParams(location.search); 51 52 async function test() { 53 let activeQuery = null; 54 let targetElem = null; 55 56 switch (searchParams.get("scrollable")) { 57 case "true": 58 activeQuery = "#scrollabletarget:active" 59 targetElem = scrollabletarget 60 break; 61 case "false": 62 activeQuery = "#notscrollable:active" 63 targetElem = notscrollable; 64 break; 65 default: 66 ok(false, "Unsupported scrollable value: " + searchParams.get("scrollable")); 67 break; 68 } 69 70 // Create a promise for each of the expected mouse events that are 71 // synthesized for a tap gesture 72 let mouseEventPromises = [ 73 promiseOneEvent(targetElem, "mousemove"), 74 promiseOneEvent(targetElem, "mousedown"), 75 promiseOneEvent(targetElem, "mouseup"), 76 promiseOneEvent(targetElem, "click"), 77 ]; 78 79 // Create a promise for :active state change since in the case where the 80 // target element is inside a scrollable container, APZ delays :active state 81 // change, it sometimes happens after all the relavant events above. 82 const activePromise = SimpleTest.promiseWaitForCondition( 83 () => targetElem.matches(":active"), 84 "Waiting for :active state change"); 85 86 // Perform a tap gesture 87 await synthesizeNativeTap(targetElem, 50, 50); 88 89 // Set a timeout that will fail the test if the synthesized events 90 // are not immediately dispatched. 91 let failTimeout = setTimeout(() => { 92 ok(false, "The synthesized mouse events should be emitted in a timely manner"); 93 }, 45000); 94 95 // The value of ui.touch_activation.duration_ms should be set to 96 // a large value. If we did not delay sending the synthesized 97 // mouse events, this test will not timeout. 98 await Promise.all([...mouseEventPromises, activePromise]); 99 100 clearTimeout(failTimeout); 101 102 isnot(document.querySelector(activeQuery), null, 103 "Target element should still be active due to the large activation duration"); 104 } 105 waitUntilApzStable() 106 .then(test) 107 .then(subtestDone, subtestFailed); 108 </script> 109 </head> 110 </html>