Bug 1637068 [wpt PR 23511] - [EventTiming] Test more event types, a=testonly
authorNicolás Peña Moreno <npm@chromium.org>
Thu, 21 May 2020 10:18:22 +0000
changeset 531977 bec11fb80b9f99f12beb29ac79b06e4275a2e9c0
parent 531976 2c930fe5167cac3d207caaab73c9ea4e3039eb56
child 531978 883c2b816562bc54817c45fdfce62e9ae9932c1a
push id37449
push userncsoregi@mozilla.com
push dateTue, 26 May 2020 02:38:57 +0000
treeherdermozilla-central@da2c7b0ac9a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1637068, 23511, 543598, 2191238, 768441
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1637068 [wpt PR 23511] - [EventTiming] Test more event types, a=testonly Automatic update from web-platform-tests [EventTiming] Test more event types Bug: 543598 Change-Id: I8bc74c88a3125bb9c614416e39054668e3466d91 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2191238 Reviewed-by: Yoav Weiss <yoavweiss@chromium.org> Reviewed-by: Navid Zolghadr <nzolghadr@chromium.org> Commit-Queue: Nicolás Peña Moreno <npm@chromium.org> Cr-Commit-Position: refs/heads/master@{#768441} -- wpt-commits: 77585330fd7da01392aec01cf5fed7aa22597180 wpt-pr: 23511
testing/web-platform/tests/event-timing/auxclick.html
testing/web-platform/tests/event-timing/click.html
testing/web-platform/tests/event-timing/contextmenu.html
testing/web-platform/tests/event-timing/dblclick.html
testing/web-platform/tests/event-timing/mousedown.html
testing/web-platform/tests/event-timing/mouseenter.html
testing/web-platform/tests/event-timing/mouseleave.html
testing/web-platform/tests/event-timing/mouseout.html
testing/web-platform/tests/event-timing/mouseover.html
testing/web-platform/tests/event-timing/mouseup.html
testing/web-platform/tests/event-timing/pointerdown.html
testing/web-platform/tests/event-timing/pointerenter.html
testing/web-platform/tests/event-timing/pointerleave.html
testing/web-platform/tests/event-timing/pointerout.html
testing/web-platform/tests/event-timing/pointerover.html
testing/web-platform/tests/event-timing/pointerup.html
testing/web-platform/tests/event-timing/resources/event-timing-test-utils.js
--- a/testing/web-platform/tests/event-timing/auxclick.html
+++ b/testing/web-platform/tests/event-timing/auxclick.html
@@ -4,15 +4,14 @@
 <title>Event Timing auxclick.</title>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
 <script src=/resources/testdriver.js></script>
 <script src=/resources/testdriver-actions.js></script>
 <script src=/resources/testdriver-vendor.js></script>
 <script src=resources/event-timing-test-utils.js></script>
 <div id='target'>Click me</div>
-<button id='button'>Click me</button>
 <script>
   promise_test(async t => {
     return testEventType(t, 'auxclick');
   })
 </script>
 </html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/click.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing click.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div id='target'>Click me</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'click');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/contextmenu.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing contextmenu.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div id='target' contextmenu="mymenu">Menu
+<menu type="context" id="mymenu">
+  <menuitem label="label"></menuitem>
+</menu>
+</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'contextmenu');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/dblclick.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing dblclick.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Click me</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'dblclick');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/mousedown.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing mousedown.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div id='target'>Click me</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'mousedown');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/mouseenter.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing mouseenter.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'mouseenter');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/mouseleave.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing mouseleave.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'mouseleave');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/mouseout.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing mouseout.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'mouseout', true /* looseCount */);
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/mouseover.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing mouseover.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'mouseover', true /* looseCount */);
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/mouseup.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing mouseup.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'mouseup');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/pointerdown.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing pointerdown.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'pointerdown');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/pointerenter.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing pointerenter.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'pointerenter');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/pointerleave.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing pointerleave.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'pointerleave');
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/pointerout.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing pointerout.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'pointerout', true /* looseCount */);
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/pointerover.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing pointerover.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div>Outside target!</div>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'pointerover', true /* looseCount */);
+  })
+</script>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/event-timing/pointerup.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing pointerup.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-actions.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script src=resources/event-timing-test-utils.js></script>
+<div id='target'>Target</div>
+<script>
+  promise_test(async t => {
+    return testEventType(t, 'pointerup');
+  })
+</script>
+</html>
--- a/testing/web-platform/tests/event-timing/resources/event-timing-test-utils.js
+++ b/testing/web-platform/tests/event-timing/resources/event-timing-test-utils.js
@@ -17,18 +17,18 @@ function mainThreadBusy(duration) {
   const now = performance.now();
   while (performance.now() < now + duration);
 }
 
 // This method should receive an entry of type 'event'. |isFirst| is true only when we want
 // to check that the event also happens to correspond to the first event. In this case, the
 // timings of the 'first-input' entry should be equal to those of this entry. |minDuration|
 // is used to compared against entry.duration.
-function verifyEvent(entry, eventType, targetId, isFirst=false, minDuration=104) {
-  assert_true(entry.cancelable);
+function verifyEvent(entry, eventType, targetId, isFirst=false, minDuration=104, notCancelable=false) {
+  assert_equals(entry.cancelable, !notCancelable, 'cancelable property');
   assert_equals(entry.name, eventType);
   assert_equals(entry.entryType, 'event');
   assert_greater_than_equal(entry.duration, minDuration,
       "The entry's duration should be greater than or equal to " + minDuration + " ms.");
   assert_greater_than(entry.processingStart, entry.startTime,
       "The entry's processingStart should be greater than startTime.");
   assert_greater_than_equal(entry.processingEnd, entry.processingStart,
       "The entry's processingEnd must be at least as large as processingStart.");
@@ -117,56 +117,124 @@ async function testDuration(t, id, numEn
         await test_driver.click(document.getElementById(id));
       }
     }
     resolve();
   });
   return Promise.all([observerPromise, clicksPromise]);
 }
 
-function applyAction(actions, eventType, target) {
+// Apply events that trigger an event of the given |eventType| to be dispatched to the |target|. Some
+//  of these assume that the target is not on the top left corner of the screen, which means that
+// (0, 0) of the viewport is outside of the |target|.
+function applyAction(eventType, target) {
+  const actions = new test_driver.Actions();
   if (eventType === 'auxclick') {
     actions.pointerMove(0, 0, {origin: target})
     .pointerDown({button: actions.ButtonType.MIDDLE})
     .pointerUp({button: actions.ButtonType.MIDDLE});
+  } else if (eventType === 'click' || eventType === 'mousedown' || eventType === 'mouseup'
+      || eventType === 'pointerdown' || eventType === 'pointerup'
+      || eventType === 'touchstart' || eventType === 'touchend') {
+    actions.pointerMove(0, 0, {origin: target})
+    .pointerDown()
+    .pointerUp();
+  } else if (eventType === 'contextmenu') {
+    actions.pointerMove(0, 0, {origin: target})
+    .pointerDown({button: actions.ButtonType.RIGHT})
+    .pointerUp({button: actions.ButtonType.RIGHT});
+  } else if (eventType === 'dblclick') {
+    actions.pointerMove(0, 0, {origin: target})
+    .pointerDown()
+    .pointerUp()
+    .pointerDown()
+    .pointerUp()
+    // Reset by clicking outside of the target.
+    .pointerMove(0, 0)
+    .pointerDown()
+    .pointerUp();
+  } else if (eventType === 'mouseenter' || eventType === 'mouseover'
+      || eventType === 'pointerenter' || eventType === 'pointerover') {
+    // Move outside of the target and then back inside.
+    actions.pointerMove(0, 0)
+    .pointerMove(0, 0, {origin: target});
+  } else if (eventType === 'mouseleave' || eventType === 'mouseout'
+      || eventType === 'pointerleave' || eventType === 'pointerout') {
+    actions.pointerMove(0, 0, {origin: target})
+    .pointerMove(0, 0);
   } else {
     assert_unreached('The event type ' + eventType + ' is not supported.');
   }
+  return actions.send();
+}
+
+function requiresListener(eventType) {
+  return ['mouseenter', 'mouseleave', 'pointerdown', 'pointerenter', 'pointerleave', 'pointerout', 'pointerover', 'pointerup'].includes(eventType);
+}
+
+function notCancelable(eventType) {
+  return ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave'].includes(eventType);
 }
 
 // Tests the given |eventType| by creating events whose target are the element with id 'target'.
-// The test assumes that such element already exists.
-async function testEventType(t, eventType) {
+// The test assumes that such element already exists. |looseCount| is set for events for which
+// events would occur for other elements besides the target, so the counts will be larger.
+async function testEventType(t, eventType, looseCount=false) {
   assert_implements(window.EventCounts, "Event Counts isn't supported");
   assert_equals(performance.eventCounts.get(eventType), 0);
   const target = document.getElementById('target');
-  const actions = new test_driver.Actions();
+  if (requiresListener(eventType)) {
+    target.addEventListener(eventType, () =>{});
+  }
+  assert_equals(performance.eventCounts.get(eventType), 0, 'No events yet.');
   // Trigger two 'fast' events of the type.
-  applyAction(actions, eventType, target);
-  applyAction(actions, eventType, target);
-  await actions.send();
-  assert_equals(performance.eventCounts.get('auxclick'), 2);
+  await applyAction(eventType, target);
+  await applyAction(eventType, target);
+  if (looseCount) {
+    assert_greater_than_equal(performance.eventCounts.get(eventType), 2,
+        `Should have at least 2 ${eventType} events`)
+  } else {
+    assert_equals(performance.eventCounts.get(eventType), 2, `Should have 2 ${eventType} events`);
+  }
   // The durationThreshold used by the observer. A slow events needs to be slower than that.
   const durationThreshold = 16;
   // Now add an event handler to cause a slow event.
   target.addEventListener(eventType, () => {
     mainThreadBusy(durationThreshold + 4);
   });
-  return new Promise(async resolve => {
+  const observerPromise = new Promise(async resolve => {
     new PerformanceObserver(t.step_func(entryList => {
       let eventTypeEntries = entryList.getEntriesByName(eventType);
       if (eventTypeEntries.length === 0)
         return;
 
-      assert_equals(eventTypeEntries.length, 1);
-      verifyEvent(eventTypeEntries[0],
+      let entry = null;
+      if (!looseCount) {
+        entry = eventTypeEntries[0];
+        assert_equals(eventTypeEntries.length, 1);
+      } else {
+        // The other events could also be considered slow. Find the one with the correct target.
+        eventTypeEntries.forEach(e => {
+          if (e.target === document.getElementById('target'))
+            entry = e;
+        });
+        if (!entry)
+          return;
+      }
+      verifyEvent(entry,
                   eventType,
                   'target',
                   false /* isFirst */,
-                  durationThreshold);
-      assert_equals(performance.eventCounts.get(eventType), 3);
+                  durationThreshold,
+                  notCancelable(eventType));
+      if (looseCount) {
+        assert_greater_than_equal(performance.eventCounts.get(eventType), 3,
+            `Should have at least 3 ${eventType} events`)
+      } else {
+        assert_equals(performance.eventCounts.get(eventType), 3, `Should have 3 ${eventType} events`);
+      }
       resolve();
     })).observe({type: 'event', durationThreshold: durationThreshold});
-    // Cause a slow event.
-    applyAction(actions, eventType, target);
-    actions.send();
   });
+  // Cause a slow event.
+  let actionPromise = applyAction(eventType, target);
+  return Promise.all([actionPromise, observerPromise]);
 }
\ No newline at end of file