mouseevents-after-touchend.tentative.html (9800B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="timeout" content="long"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Mouse events for compatibility after a tap</title> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="/resources/testdriver.js"></script> 11 <script src="/resources/testdriver-actions.js"></script> 12 <script src="/resources/testdriver-vendor.js"></script> 13 <style> 14 #parent, #child { 15 width: 300px; 16 height: 64px; 17 padding: 16px; 18 } 19 #parent { 20 background-color: black; 21 } 22 #child { 23 background-color: gray; 24 } 25 </style> 26 <script> 27 "use strict"; 28 29 addEventListener("load", t => { 30 let events = []; 31 for (const type of ["mousemove", 32 "mousedown", 33 "mouseup", 34 "click", 35 "dblclick", 36 "contextmenu", 37 "touchend"]) { 38 if (type == "touchend") { 39 addEventListener(type, event => { 40 events.push({type: type, target: event.target}); 41 }, {capture: true}); 42 } else { 43 addEventListener(type, event => { 44 events.push({ 45 type: event.type, 46 target: event.target, 47 detail: event.detail, 48 button: event.button, 49 buttons: event.buttons, 50 }); 51 }, {capture: true}); 52 } 53 } 54 55 function stringifyEvents(arrayOfEvents) { 56 if (!arrayOfEvents.length) { 57 return "[]"; 58 } 59 function stringifyEvent(event) { 60 return `{ type: ${event.type}, target: ${ 61 event.target.id || event.target.nodeName 62 }${ 63 event.detail !== undefined ? `, detail: ${event.detail}` : "" 64 }${ 65 event.button !== undefined ? `, button: ${event.button}` : "" 66 }${ 67 event.buttons !== undefined ? `, buttons: ${event.buttons}` : "" 68 } }`; 69 } 70 let ret = ""; 71 for (const event of arrayOfEvents) { 72 if (ret === "") { 73 ret = "[ "; 74 } else { 75 ret += ", "; 76 } 77 ret += stringifyEvent(event); 78 } 79 return ret + " ]"; 80 } 81 const child = document.getElementById("child"); 82 const parent = child.parentNode; 83 84 function promiseInitPointer() { 85 return new test_driver.Actions() 86 .addPointer("touchPointer", "touch") 87 .pointerMove(0, 0, {origin: document.body}) 88 .send(); 89 } 90 promise_test(async () => { 91 await promiseInitPointer(); 92 events = []; 93 await new test_driver.Actions() 94 .addPointer("touchPointer", "touch") 95 .pointerMove(5, 5, {origin: child}) 96 .pointerDown() 97 .pointerUp() 98 .send(); 99 assert_equals( 100 stringifyEvents(events), 101 stringifyEvents([ 102 { type: "touchend", target: child }, 103 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 104 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 105 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 106 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 107 ]) 108 ); 109 }, "Single tap should cause a click"); 110 111 promise_test(async () => { 112 await promiseInitPointer(); 113 events = []; 114 child.addEventListener("touchstart", event => { 115 event.preventDefault(); 116 }, {once: true}); 117 await new test_driver.Actions() 118 .addPointer("touchPointer", "touch") 119 .pointerMove(105, 5, {origin: child}) 120 .pointerDown() 121 .pointerUp() 122 .send(); 123 assert_equals( 124 stringifyEvents(events), 125 stringifyEvents([ 126 { type: "touchend", target: child }, 127 ]) 128 ); 129 }, "Single tap whose touchstart is consumed should not cause a click"); 130 131 promise_test(async () => { 132 await promiseInitPointer(); 133 events = []; 134 child.addEventListener("touchend", event => { 135 event.preventDefault(); 136 }, {once: true}); 137 await new test_driver.Actions() 138 .addPointer("touchPointer", "touch") 139 .pointerMove(105, 5, {origin: child}) 140 .pointerDown() 141 .pointerUp() 142 .send(); 143 assert_equals( 144 stringifyEvents(events), 145 stringifyEvents([ 146 { type: "touchend", target: child }, 147 ]) 148 ); 149 }, "Single tap whose touchend is consumed should not cause a click"); 150 151 promise_test(async () => { 152 await promiseInitPointer(); 153 events = []; 154 await new test_driver.Actions() 155 .addPointer("touchPointer", "touch") 156 .pointerMove(5, 5, {origin: child}) 157 .pointerDown() 158 .pointerUp() 159 .pointerDown() 160 .pointerUp() 161 .send(); 162 assert_in_array( 163 stringifyEvents(events), 164 [ 165 // Currently, WebDriver does not have a strict way to synthesize a 166 // double click, therefore, it's fine either single click twice or 167 // a set of a double-click. 168 stringifyEvents([ 169 { type: "touchend", target: child }, 170 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 171 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 172 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 173 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 174 { type: "touchend", target: child }, 175 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 176 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 177 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 178 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 179 ]), 180 stringifyEvents([ 181 { type: "touchend", target: child }, 182 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 183 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 184 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 185 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 186 { type: "touchend", target: child }, 187 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 188 { type: "mousedown", target: child, detail: 2, button: 0, buttons: 1 }, 189 { type: "mouseup", target: child, detail: 2, button: 0, buttons: 0 }, 190 { type: "click", target: child, detail: 2, button: 0, buttons: 0 }, 191 { type: "dblclick", target: child, detail: 2, button: 0, buttons: 0 }, 192 ]), 193 ], 194 ); 195 }, "Double tap should cause single-click twice or a double-click"); 196 197 promise_test(async () => { 198 await promiseInitPointer(); 199 events = []; 200 await new test_driver.Actions() 201 .addPointer("touchPointer", "touch") 202 .pointerMove(105, 5, {origin: child}) 203 .pointerDown() 204 .pointerUp() 205 .pause(1000) 206 .pointerDown() 207 .pointerUp() 208 .send(); 209 assert_equals( 210 stringifyEvents(events), 211 stringifyEvents([ 212 { type: "touchend", target: child }, 213 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 214 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 215 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 216 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 217 { type: "touchend", target: child }, 218 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 219 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 220 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 221 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 222 ]) 223 ); 224 }, "Tapping twice slowly should not cause a dblclick"); 225 226 promise_test(async () => { 227 await promiseInitPointer(); 228 events = []; 229 await new test_driver.Actions() 230 .addPointer("touchPointer", "touch") 231 .pointerMove(5, 5, {origin: child}) 232 .pointerDown() 233 .pointerUp() 234 .pointerMove(100, 5, {origin: child}) 235 .pointerDown() 236 .pointerUp() 237 .send(); 238 assert_equals( 239 stringifyEvents(events), 240 stringifyEvents([ 241 { type: "touchend", target: child }, 242 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 243 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 244 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 245 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 246 { type: "touchend", target: child }, 247 { type: "mousemove", target: child, detail: 0, button: 0, buttons: 0 }, 248 { type: "mousedown", target: child, detail: 1, button: 0, buttons: 1 }, 249 { type: "mouseup", target: child, detail: 1, button: 0, buttons: 0 }, 250 { type: "click", target: child, detail: 1, button: 0, buttons: 0 }, 251 ]) 252 ); 253 }, "Tapping too far points should not cause a dblclick"); 254 255 promise_test(async () => { 256 await promiseInitPointer(); 257 events = []; 258 await new test_driver.Actions() 259 .addPointer("touchPointer", "touch") 260 .addPointer("touchPointer2", "touch") 261 .pointerMove(5, 5, {origin: child, sourceName: "touchPointer"}) 262 .pointerMove(25, 25, {origin: child, sourceName: "touchPointer2"}) 263 .pointerDown({sourceName: "touchPointer"}) 264 .pointerDown({sourceName: "touchPointer2"}) 265 .pointerUp({sourceName: "touchPointer"}) 266 .pointerUp({sourceName: "touchPointer2"}) 267 .send(); 268 assert_equals( 269 stringifyEvents(events), 270 stringifyEvents([ 271 { type: "touchend", target: child }, 272 { type: "touchend", target: child }, 273 ]) 274 ); 275 }, "Multi tap should not cause mouse events"); 276 }, {once: true}); 277 </script> 278 </head> 279 <body><div id="parent"><div id="child"></div></div></body> 280 </html>