Bug 1636462 [wpt PR 23481] - device orientation: Try to remove flakiness from tests., a=testonly
authorRaphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
Wed, 13 May 2020 09:48:44 +0000
changeset 531162 7143cd0578a92d557e51976c537783f2f988fc9b
parent 531161 c18ec8257b9f3c61a2ce538734b91dd3b2d6e847
child 531163 65e18ed8d76fd4b35f9fdf357507125797a5d4fd
push id37435
push userapavel@mozilla.com
push dateWed, 20 May 2020 15:28:23 +0000
treeherdermozilla-central@5415da14ec9a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1636462, 23481, 2154389, 816462, 1078298, 2190273, 766988
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 1636462 [wpt PR 23481] - device orientation: Try to remove flakiness from tests., a=testonly Automatic update from web-platform-tests device orientation: Try to remove flakiness from tests. https://crrev.com/c/2154389 ("[device-orientation] Simplifies tests by using EventWatcher") ended up introducing some Chromium-specific flakiness to most tests that started using EventWatcher, and the Mac bots in particular seem to trigger this flakiness very often. This comes from the fact that EventWatcher will continue watching for events until the end of the test, and the Blink implementation of the DeviceOrientation Event specification ends up emitting a non-standard null event whenever there are no more events to send. This event can end up being caught by EventWatcher, which correctly reports it as unexpected. For now, replace most usages of EventWatcher with a much simplified version of the waitForEvent() function removed in the CL above that only subscribes to events once. Bug: 816462, 1078298 Change-Id: I181219f2be19bba8a392c2bf64373f01df46c398 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2190273 Commit-Queue: Reilly Grant <reillyg@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Auto-Submit: Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com> Cr-Commit-Position: refs/heads/master@{#766988} -- wpt-commits: 54b6be43d7c1be3393ddf921703e60dee74e7777 wpt-pr: 23481
testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html
testing/web-platform/tests/orientation-event/motion/null-values.https.html
testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html
testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html
testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html
testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html
testing/web-platform/tests/orientation-event/orientation/null-values.https.html
testing/web-platform/tests/orientation-event/orientation/updates.https.html
testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js
--- a/testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html
+++ b/testing/web-platform/tests/orientation-event/motion/multiple-event-listeners.https.html
@@ -6,37 +6,21 @@
 <script src="../resources/orientation-event-helpers.js"></script>
 <script>
 'use strict';
 
 sensor_test(async (t, sensorProvider) => {
   const motionData1 = generateMotionData(1, 2, 3,
                                          4, 5, 6,
                                          7, 8, 9);
+  setMockMotionData(sensorProvider, motionData1);
+  await Promise.all([
+    waitForEvent(getExpectedMotionEvent(motionData1)),
+    waitForEvent(getExpectedMotionEvent(motionData1))
+  ]);
+
   const motionData2 = generateMotionData(11, 12, 13,
                                          14, 15, 16,
                                          17, 18, 19);
-
-  let firstListener = null;
-  let firstEventPromise = new Promise(resolve => {
-    firstListener = resolve;
-  });
-  // We directly add the listener instead of using EventWatcher
-  // because we want to remove listener after the first event fires
-  // but EventWatcher could only stop watching after test done.
-  window.addEventListener('devicemotion', firstListener);
-
-  const watcher = new EventWatcher(t, window, ['devicemotion']);
-  setMockMotionData(sensorProvider, motionData1);
-
-  let firstEvent = await firstEventPromise;
-  assertEventEquals(firstEvent, getExpectedMotionEvent(motionData1));
-  let secondEvent = await watcher.wait_for('devicemotion');
-  assertEventEquals(secondEvent, getExpectedMotionEvent(motionData1));
-
-  window.removeEventListener('devicemotion', firstListener);
-
-  // At this point only the second event listener is active.
   setMockMotionData(sensorProvider, motionData2);
-  let thirdEvent = await watcher.wait_for('devicemotion');
-  assertEventEquals(thirdEvent, getExpectedMotionEvent(motionData2));
+  await waitForEvent(getExpectedMotionEvent(motionData2));
 }, 'Tests using multiple event handlers for the Device Motion API.');
 </script>
--- a/testing/web-platform/tests/orientation-event/motion/null-values.https.html
+++ b/testing/web-platform/tests/orientation-event/motion/null-values.https.html
@@ -19,26 +19,21 @@ sensor_test(async (t, sensorProvider) =>
   const motionData3 = generateMotionData(null, null, null,
                                          null, null, null,
                                          1, 2, 3);
 
   const motionData4 = generateMotionData(null, null, null,
                                          null, null, null,
                                          null, null, null);
 
-  const watcher = new EventWatcher(t, window, ['devicemotion']);
   setMockMotionData(sensorProvider, motionData1);
-  const firstEvent = await watcher.wait_for('devicemotion');
-  assertEventEquals(firstEvent, getExpectedMotionEvent(motionData1));
+  await waitForEvent(getExpectedMotionEvent(motionData1));
 
   setMockMotionData(sensorProvider, motionData2);
-  const secondEvent = await watcher.wait_for('devicemotion');
-  assertEventEquals(secondEvent, getExpectedMotionEvent(motionData2));
+  await waitForEvent(getExpectedMotionEvent(motionData2));
 
   setMockMotionData(sensorProvider, motionData3);
-  const thirdEvent = await watcher.wait_for('devicemotion');
-  assertEventEquals(thirdEvent, getExpectedMotionEvent(motionData3));
+  await waitForEvent(getExpectedMotionEvent(motionData3));
 
   setMockMotionData(sensorProvider, motionData4);
-  const fourthEvent = await watcher.wait_for('devicemotion');
-  assertEventEquals(fourthEvent, getExpectedMotionEvent(motionData4));
+  await waitForEvent(getExpectedMotionEvent(motionData4));
 }, 'Tests using null values for some or all of the event properties.');
-</script>
\ No newline at end of file
+</script>
--- a/testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html
+++ b/testing/web-platform/tests/orientation-event/orientation/absolute-fallback.https.html
@@ -4,18 +4,16 @@
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
 <script src="../resources/orientation-event-helpers.js"></script>
 <script>
 'use strict';
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
-  const watcher = new EventWatcher(t, window, ['deviceorientation']);
 
   // Make the relative orientation sensor unavailable and set mock data for
   // the absolute one.
   sensorProvider.setGetSensorShouldFail('RelativeOrientationEulerAngles', true);
   setMockOrientationData(sensorProvider, orientationData);
-  const event = await watcher.wait_for('deviceorientation');
-  assertEventEquals(event, getExpectedOrientationEvent(orientationData));
+  return waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData));
 }, 'Tests that deviceorientation falls back to using absolute orientation data if relative is unavailable.');
 </script>
--- a/testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html
+++ b/testing/web-platform/tests/orientation-event/orientation/basic-operation-absolute.https.html
@@ -4,21 +4,18 @@
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
 <script src="../resources/orientation-event-helpers.js"></script>
 <script>
 'use strict';
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
-  const watcher = new EventWatcher(t, window, ['deviceorientationabsolute']);
-
   setMockOrientationData(sensorProvider, orientationData);
-  const event = await watcher.wait_for('deviceorientationabsolute');
-  assertEventEquals(event, getExpectedAbsoluteOrientationEvent(orientationData));
+  return waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData));
 }, 'Tests basic operation of deviceorientationabsolute event using mock data.');
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData = generateOrientationData(null, null, null, true);
   const watcher = new EventWatcher(t, window, ['deviceorientationabsolute']);
 
   // Make the absolute orientation sensor unavailable
   sensorProvider.setGetSensorShouldFail('AbsoluteOrientationEulerAngles', true);
--- a/testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html
+++ b/testing/web-platform/tests/orientation-event/orientation/basic-operation.https.html
@@ -4,21 +4,18 @@
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
 <script src="../resources/orientation-event-helpers.js"></script>
 <script>
 'use strict';
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
-  const watcher = new EventWatcher(t, window, ['deviceorientation']);
-
   setMockOrientationData(sensorProvider, orientationData);
-  const event = await watcher.wait_for('deviceorientation');
-  assertEventEquals(event, getExpectedOrientationEvent(orientationData));
+  return waitForEvent(getExpectedOrientationEvent(orientationData));
 }, 'Tests basic operation of deviceorientation event using mock data.');
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData = generateOrientationData(null, null, null, false);
   const watcher = new EventWatcher(t, window, ['deviceorientation']);
 
   // Make the orientation sensor unavailable
   sensorProvider.setGetSensorShouldFail('AbsoluteOrientationEulerAngles', true);
--- a/testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html
+++ b/testing/web-platform/tests/orientation-event/orientation/multiple-event-listeners.https.html
@@ -4,35 +4,19 @@
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
 <script src="../resources/orientation-event-helpers.js"></script>
 <script>
 'use strict';
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData1 = generateOrientationData(1, 2, 3, false);
-  const orientationData2 = generateOrientationData(11, 12, 13, false);
-
-  let firstListener = null;
-  let firstEventPromise = new Promise(resolve => {
-    firstListener = resolve;
-  });
-  // We directly add the listener instead of using EventWatcher
-  // because we want to remove listener after the first event fires
-  // but EventWatcher could only stop watching after test done.
-  window.addEventListener('deviceorientation', firstListener);
+  setMockOrientationData(sensorProvider, orientationData1);
+  await Promise.all([
+    waitForEvent(getExpectedOrientationEvent(orientationData1)),
+    waitForEvent(getExpectedOrientationEvent(orientationData1))
+  ]);
 
-  const watcher = new EventWatcher(t, window, ['deviceorientation']);
-  setMockOrientationData(sensorProvider, orientationData1);
-
-  let firstEvent = await firstEventPromise;
-  assertEventEquals(firstEvent, getExpectedOrientationEvent(orientationData1));
-  let secondEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(secondEvent, getExpectedOrientationEvent(orientationData1));
-
-  window.removeEventListener('deviceorientation', firstListener);
-  // At this point only the second event listener is still active.
+  const orientationData2 = generateOrientationData(11, 12, 13, false);
   setMockOrientationData(sensorProvider, orientationData2);
-
-  let thirdEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(thirdEvent, getExpectedOrientationEvent(orientationData2));
+  await waitForEvent(getExpectedOrientationEvent(orientationData2));
 }, 'Tests using multiple event handlers for the Device Orientation API.');
 </script>
--- a/testing/web-platform/tests/orientation-event/orientation/null-values.https.html
+++ b/testing/web-platform/tests/orientation-event/orientation/null-values.https.html
@@ -10,26 +10,21 @@
 sensor_test(async (t, sensorProvider) => {
   const orientationData1 = generateOrientationData(1.1, null, null, false);
   const orientationData2 = generateOrientationData(null, 2.2, null, false);
   const orientationData3 = generateOrientationData(null, null, 3.3, false);
   // The all null event is last because DeviceSingleWindowEventController
   // will stop updating the sensor when it sees a null event.
   const orientationData4 = generateOrientationData(null, null, null, false);
 
-  const watcher = new EventWatcher(t, window, ['deviceorientation']);
   setMockOrientationData(sensorProvider, orientationData1);
-  const firstEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(firstEvent, getExpectedOrientationEvent(orientationData1));
+  await waitForEvent(getExpectedOrientationEvent(orientationData1));
 
   setMockOrientationData(sensorProvider, orientationData2);
-  const secondEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(secondEvent, getExpectedOrientationEvent(orientationData2));
+  await waitForEvent(getExpectedOrientationEvent(orientationData2));
 
   setMockOrientationData(sensorProvider, orientationData3);
-  const thirdEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(thirdEvent, getExpectedOrientationEvent(orientationData3));
+  await waitForEvent(getExpectedOrientationEvent(orientationData3));
 
   setMockOrientationData(sensorProvider, orientationData4);
-  const fourthEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(fourthEvent, getExpectedOrientationEvent(orientationData4));
+  await waitForEvent(getExpectedOrientationEvent(orientationData4));
 }, 'Tests using null values for some of the event properties.');
 </script>
--- a/testing/web-platform/tests/orientation-event/orientation/updates.https.html
+++ b/testing/web-platform/tests/orientation-event/orientation/updates.https.html
@@ -4,20 +4,16 @@
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
 <script src="../resources/orientation-event-helpers.js"></script>
 <script>
 'use strict';
 
 sensor_test(async (t, sensorProvider) => {
   const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
-  const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
+  setMockOrientationData(sensorProvider, orientationData1);
+  await waitForEvent(getExpectedOrientationEvent(orientationData1));
 
-  const watcher = new EventWatcher(t, window, ['deviceorientation']);
-  setMockOrientationData(sensorProvider, orientationData1);
-  const firstEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(firstEvent, getExpectedOrientationEvent(orientationData1));
-
+  const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
   setMockOrientationData(sensorProvider, orientationData2);
-  const secondEvent = await watcher.wait_for('deviceorientation');
-  assertEventEquals(secondEvent, getExpectedOrientationEvent(orientationData2));
+  await waitForEvent(getExpectedOrientationEvent(orientationData2));
 }, 'Tests that updates to the orientation causes new events to fire.');
 </script>
--- a/testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js
+++ b/testing/web-platform/tests/orientation-event/resources/orientation-event-helpers.js
@@ -174,8 +174,17 @@ function getExpectedMotionEvent(expected
     rotationRate: {
       alpha: expectedMotionData.rotationRateAlpha,
       beta: expectedMotionData.rotationRateBeta,
       gamma: expectedMotionData.rotationRateGamma,
     },
     interval: expectedMotionData.interval,
   });
 }
+
+function waitForEvent(expected_event) {
+  return new Promise(resolve => {
+    window.addEventListener(expected_event.type, (event) => {
+      assertEventEquals(event, expected_event);
+      resolve();
+    }, { once: true });
+  });
+}