Bug 1478776 - Part 4: Add basic tests for visual viewport events. r=botond
authorJan Henning <jh+bugzilla@buttercookie.de>
Thu, 20 Dec 2018 21:35:04 +0000
changeset 451695 b056dade814dc2018a7fb3114b21ab33301a44fe
parent 451694 e6b186bffed79a39f5a3694679ec853a4943ca8c
child 451696 24951c9d732d81bc1747f089c683e2ffecd78ea0
push id35251
push userccoroiu@mozilla.com
push dateFri, 21 Dec 2018 21:54:30 +0000
treeherdermozilla-central@74101900e7d4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1478776
milestone66.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 1478776 - Part 4: Add basic tests for visual viewport events. r=botond This will use the existing APZ basic pan/pinch-zoom tests to check that scrolling/zooming will also generate the expected visual viewport events. Because the various scroll-related events are throttled by the refresh driver and only fire once per tick, merely flushing APZ repaints is no longer enough. We now have to actually wait for the paints themselves, so we're sure that we've had an opportunity to receive the corresponding events, too. Differential Revision: https://phabricator.services.mozilla.com/D14041
gfx/layers/apz/test/mochitest/helper_basic_pan.html
gfx/layers/apz/test/mochitest/helper_basic_zoom.html
gfx/layers/apz/test/mochitest/test_group_touchevents.html
gfx/layers/apz/test/mochitest/test_group_zoom.html
--- a/gfx/layers/apz/test/mochitest/helper_basic_pan.html
+++ b/gfx/layers/apz/test/mochitest/helper_basic_pan.html
@@ -2,37 +2,70 @@
 <html>
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width; initial-scale=1.0">
   <title>Sanity panning test</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
+  let scrEvt = new EventCounter(window, "scroll");
+  let visScrEvt = new EventCounter(window.visualViewport, "scroll");
+  // Our internal visual viewport events aren't restricted to the visual view-
+  // port itself, so we can listen on the window itself, however the event
+  // listener needs to be in the system group.
+  let visScrEvtInternal = new EventCounter(window, "mozvisualscroll",
+                                           { mozSystemGroup: true });
+
   // This listener will trigger the test to continue once APZ is done with
   // processing the scroll.
   SpecialPowers.Services.obs.addObserver(testDriver, "APZ:TransformEnd");
 
   synthesizeNativeTouchDrag(document.body, 10, 100, 0, -50);
   dump("Finished native drag, waiting for transform-end observer...\n");
 
   // Wait for the APZ:TransformEnd to be fired after touch events are processed.
   yield true;
 
   // We get here once the APZ:TransformEnd has fired, so we don't need that
   // observer any more.
   SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
 
   // Flush state.
-  yield flushApzRepaints(testDriver);
+  yield waitForApzFlushedRepaints(testDriver);
 
   is(window.scrollY, 50, "check that the window scrolled");
+
+  // Check we've got the expected events.
+  // This page is using "width=device-width; initial-scale=1.0" and we haven't
+  // pinch-zoomed any further, so layout and visual viewports have the same
+  // size and will scroll together. Therefore we should be getting layout
+  // viewport "scroll" events as well.
+  scrEvt.unregister();
+  ok(scrEvt.count > 0, "Got some layout viewport scroll events");
+  // This one is a bit tricky: Visual viewport "scroll" events are supposed to
+  // fire only when the relative offset between layout and visual viewport
+  // changes. Even when they're both scrolling together, we may update their
+  // positions independently, though, leading to some jitter in the offset and
+  // triggering the event after all.
+  // At least for the case here, where both viewports are the same size and we
+  // have a freshly loaded page, we should however be able to keep the offset at
+  // a constant zero and therefore not cause any visual viewport scroll events
+  // to fire.
+  visScrEvt.unregister();
+  is(visScrEvt.count, 0, "Got no visual viewport scroll events");
+  visScrEvtInternal.unregister();
+  // Our internal visual viewport scroll event on the other hand only cares
+  // about the absolute offset of the visual viewport and should therefore
+  // definitively fire.
+  todo(visScrEvtInternal.count > 0, "Got some mozvisualscroll events");
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
 .then(subtestDone);
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/helper_basic_zoom.html
+++ b/gfx/layers/apz/test/mochitest/helper_basic_zoom.html
@@ -2,19 +2,32 @@
 <html>
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width">
   <title>Sanity check for zooming</title>
   <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="application/javascript">
 
 function* test(testDriver) {
+  let visResEvt = new EventCounter(window.visualViewport, "resize");
+  let visScrEvt = new EventCounter(window.visualViewport, "scroll");
+  // Our internal visual viewport events aren't restricted to the visual view-
+  // port itself, so we can listen on the window itself, however the event
+  // listener needs to be in the system group.
+  let visResEvtInternal = new EventCounter(window, "mozvisualresize",
+                                           { mozSystemGroup: true });
+  let visScrEvtInternal = new EventCounter(window, "mozvisualscroll",
+                                           { mozSystemGroup: true });
+  let visResEvtContent = new EventCounter(window, "mozvisualresize");
+  let visScrEvtContent = new EventCounter(window, "mozvisualscroll");
+
   var initial_resolution = getResolution();
   ok(initial_resolution > 0,
       'The initial_resolution is ' + initial_resolution + ', which is some sane value');
 
   // This listener will trigger the test to continue once APZ is done with
   // processing the scroll.
   SpecialPowers.Services.obs.addObserver(testDriver, "APZ:TransformEnd");
 
@@ -33,19 +46,41 @@ function* test(testDriver) {
   // Wait for the APZ:TransformEnd to be fired after touch events are processed.
   yield true;
 
   // We get here once the APZ:TransformEnd has fired, so we don't need that
   // observer any more.
   SpecialPowers.Services.obs.removeObserver(testDriver, "APZ:TransformEnd", false);
 
   // Flush state and get the resolution we're at now
-  yield flushApzRepaints(testDriver);
+  yield waitForApzFlushedRepaints(testDriver);
   let final_resolution = getResolution();
   ok(final_resolution > initial_resolution, 'The final resolution (' + final_resolution + ') is greater after zooming in');
+
+  // Check we've got the expected events.
+  // Pinch-zooming the page should fire visual viewport resize events:
+  visResEvt.unregister();
+  todo(visResEvt.count > 0, "Got some visual viewport resize events");
+  visResEvtInternal.unregister();
+  todo(visResEvtInternal.count > 0, "Got some mozvisualresize events");
+
+  // We're pinch-zooming somewhere in the middle of the page, so the visual
+  // viewport's coordinates change, too.
+  // This is true both relative to the page (mozvisualscroll), as well as
+  // relative to the layout viewport (visual viewport "scroll" event).
+  visScrEvt.unregister();
+  todo(visScrEvt.count > 0, "Got some visual viewport scroll events");
+  visScrEvtInternal.unregister();
+  todo(visScrEvtInternal.count > 0, "Got some mozvisualscroll events");
+
+  // Our internal events shouldn't leak to normal content.
+  visResEvtContent.unregister();
+  is(visResEvtContent.count, 0, "Got no mozvisualresize events in content");
+  visScrEvtContent.unregister();
+  is(visScrEvtContent.count, 0, "Got no mozvisualscroll events in content");
 }
 
 waitUntilApzStable()
 .then(runContinuation(test))
 .then(subtestDone);
 
   </script>
 </head>
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents.html
@@ -8,17 +8,18 @@
   <script type="application/javascript" src="apz_test_utils.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript">
 
 var basic_pan_prefs = getPrefs("TOUCH_EVENTS:PAN");
 
 var subtests = [
   // Simple tests to exercise basic panning behaviour
-  {'file': 'helper_basic_pan.html', 'prefs': basic_pan_prefs},
+  // The visual viewport isn't yet enabled by default and we want to test its events, too.
+  {'file': 'helper_basic_pan.html', 'prefs': basic_pan_prefs.concat([["dom.visualviewport.enabled", true]])},
   {'file': 'helper_div_pan.html', 'prefs': basic_pan_prefs},
   {'file': 'helper_iframe_pan.html', 'prefs': basic_pan_prefs},
 
   // Simple test to exercise touch-tapping behaviour
   {'file': 'helper_tap.html'},
   // Tapping, but with a full-zoom applied
   {'file': 'helper_tap_fullzoom.html'},
 
--- a/gfx/layers/apz/test/mochitest/test_group_zoom.html
+++ b/gfx/layers/apz/test/mochitest/test_group_zoom.html
@@ -34,16 +34,18 @@ var prefs = [
   ["dom.meta-viewport.enabled", true],
   // Pinch-zooming currently requires container scrolling (this requirement
   // will eventually be removed).
   ["layout.scroll.root-frame-containers", 1],
   // Retained displaylists don't work well with container scrolling, so
   // they too need to be disabled for now.
   ["layout.display-list.retain", false],
   ["layout.display-list.retain.chrome", false],
+  // The VisualViewport API currently isn't enabled by default.
+  ["dom.visualviewport.enabled", true],
 ];
 
 // Increase the tap timeouts so the double-tap is still detected in case of
 // random delays during testing.
 var doubletap_prefs = [
   ...prefs,
   ["ui.click_hold_context_menus.delay", 10000],
   ["apz.max_tap_time", 10000],