Bug 1288799 - Add a test_touch_action.html which runs all of the W3C touch-action tests as mochitests. rs=smaug
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 29 Jul 2016 14:27:39 -0400
changeset 347391 8fb07560ca17cb3d4b2483d448e8fa78a9ed7c15
parent 347390 57a85939e44a75e496fda385bd2cc24503e23102
child 347392 3a248e721aa179549a8b5a7b78c0ac8fed4603be
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1288799
milestone50.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 1288799 - Add a test_touch_action.html which runs all of the W3C touch-action tests as mochitests. rs=smaug MozReview-Commit-ID: CA0XMnQepVD
dom/events/test/pointerevents/mochitest.ini
dom/events/test/pointerevents/test_touch_action.html
dom/events/test/pointerevents/touch_action_helpers.js
--- a/dom/events/test/pointerevents/mochitest.ini
+++ b/dom/events/test/pointerevents/mochitest.ini
@@ -96,10 +96,34 @@ support-files =
   support-files = pointerevent_setpointercapture_disconnected-manual.html
 [test_pointerevent_setpointercapture_inactive_button_mouse-manual.html]
   support-files = pointerevent_setpointercapture_inactive_button_mouse-manual.html
   skip-if = (os == 'win') || (os == 'linux') # see bug1270903
 [test_pointerevent_setpointercapture_invalid_pointerid-manual.html]
   support-files = pointerevent_setpointercapture_invalid_pointerid-manual.html
 [test_pointerevent_setpointercapture_relatedtarget-manual.html]
   support-files = pointerevent_setpointercapture_relatedtarget-manual.html
+[test_touch_action.html]
+  # Windows touch injection doesn't work in automation, but this test can be run locally on a windows touch device.
+  skip-if = (toolkit == 'windows')
+  support-files =
+    ../../../../gfx/layers/apz/test/mochitest/apz_test_utils.js
+    ../../../../gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
+    touch_action_helpers.js
+    pointerevent_touch-action-auto-css_touch-manual.html
+    pointerevent_touch-action-button-test_touch-manual.html
+    pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html
+    pointerevent_touch-action-inherit_child-none_touch-manual.html
+    pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html
+    pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html
+    pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html
+    pointerevent_touch-action-inherit_parent-none_touch-manual.html
+    pointerevent_touch-action-none-css_touch-manual.html
+    pointerevent_touch-action-pan-x-css_touch-manual.html
+    pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html
+    pointerevent_touch-action-pan-x-pan-y_touch-manual.html
+    pointerevent_touch-action-pan-y-css_touch-manual.html
+    pointerevent_touch-action-span-test_touch-manual.html
+    pointerevent_touch-action-svg-test_touch-manual.html
+    pointerevent_touch-action-table-test_touch-manual.html
+
 [test_empty_file.html]
   disabled = disabled # Bug 1150091 - Issue with support-files
new file mode 100644
--- /dev/null
+++ b/dom/events/test/pointerevents/test_touch_action.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <meta charset="utf-8">
+  <title>W3C pointerevents/*touch-action*.html tests in Mochitest form</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+var apz_touch_action_prefs = [
+  // Obviously we need touch-action support enabled for testing touch-action.
+  ["layout.css.touch_action.enabled", true],
+  // Dropping the touch slop to 0 makes the tests easier to write because
+  // we can just do a one-pixel drag to get over the pan threshold rather
+  // than having to hard-code some larger value.
+  ["apz.touch_start_tolerance", "0.0"],
+  // The touchstart from the drag can turn into a long-tap if the touch-move
+  // events get held up. Try to prevent that by making long-taps require
+  // a 10 second hold. Note that we also cannot enable chaos mode on this
+  // test for this reason, since chaos mode can cause the long-press timer
+  // to fire sooner than the pref dictates.
+  ["ui.click_hold_context_menus.delay", 10000],
+  // The subtests in this test do touch-drags to pan the page, but we don't
+  // want those pans to turn into fling animations, so we increase the
+  // fling-stop threshold velocity to absurdly high.
+  ["apz.fling_stopped_threshold", "10000"],
+  // The helper_div_pan's div gets a displayport on scroll, but if the
+  // test takes too long the displayport can expire before the new scroll
+  // position is synced back to the main thread. So we disable displayport
+  // expiry for these tests.
+  ["apz.displayport_expiry_ms", 0],
+];
+
+function apzScriptInjector(name) {
+  return function(childWin) {
+    childWin._ACTIVE_TEST_NAME = name;
+    injectScript('/tests/SimpleTest/paint_listener.js', childWin)()
+    .then(injectScript('apz_test_utils.js', childWin))
+    .then(injectScript('apz_test_native_event_utils.js', childWin))
+    .then(injectScript('touch_action_helpers.js', childWin));
+  };
+}
+
+// Each of these test names is turned into an entry in the |subtests| array
+// below.
+var testnames = [
+  'pointerevent_touch-action-auto-css_touch-manual',
+  'pointerevent_touch-action-button-test_touch-manual',
+  // this one runs as a web-platform-test since it's not a manual test
+  // 'pointerevent_touch-action-illegal',
+  'pointerevent_touch-action-inherit_child-auto-child-none_touch-manual',
+  'pointerevent_touch-action-inherit_child-none_touch-manual',
+  'pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual',
+  'pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual',
+  'pointerevent_touch-action-inherit_highest-parent-none_touch-manual',
+  'pointerevent_touch-action-inherit_parent-none_touch-manual',
+  // the keyboard-manual and mouse-manual tests require simulating keyboard/
+  // mouse input, rather than touch, so we're not going to do that here.
+  //'pointerevent_touch-action-keyboard-manual',
+  //'pointerevent_touch-action-mouse-manual',
+  'pointerevent_touch-action-none-css_touch-manual',
+  'pointerevent_touch-action-pan-x-css_touch-manual',
+  'pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual',
+  'pointerevent_touch-action-pan-x-pan-y_touch-manual',
+  'pointerevent_touch-action-pan-y-css_touch-manual',
+  'pointerevent_touch-action-span-test_touch-manual',
+  'pointerevent_touch-action-svg-test_touch-manual',
+  'pointerevent_touch-action-table-test_touch-manual',
+  // this one runs as a web-platform-test since it's not a manual test
+  //'pointerevent_touch-action-verification',
+];
+
+// Each entry in |subtests| is loaded in a new window. When loaded, it runs
+// the function returned by apzScriptInjector, which injects some helper JS
+// files into the vanilla unmodified W3C testcase, and simulates the necessary
+// user input to run the test.
+var subtests = [];
+for (var name of testnames) {
+  subtests.push({
+    'file': name + '.html',
+    'prefs': apz_touch_action_prefs,
+    'onload': apzScriptInjector(name),
+  });
+}
+
+if (isApzEnabled()) {
+  SimpleTest.waitForExplicitFinish();
+  window.onload = function() {
+    runSubtestsSeriallyInFreshWindows(subtests)
+    .then(SimpleTest.finish);
+  };
+}
+
+  </script>
+ </head>
+ <body>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/events/test/pointerevents/touch_action_helpers.js
@@ -0,0 +1,206 @@
+// Some common helpers
+
+function touchActionSetup(testDriver) {
+  add_completion_callback(subtestDone);
+  document.body.addEventListener('touchend', testDriver, { passive: true });
+}
+
+function touchScrollRight(aSelector = '#target0', aX = 20, aY = 20) {
+  var target = document.querySelector(aSelector);
+  return ok(synthesizeNativeTouchDrag(target, aX + 40, aY, -40, 0), "Synthesized horizontal drag");
+}
+
+function touchScrollDown(aSelector = '#target0', aX = 20, aY = 20) {
+  var target = document.querySelector(aSelector);
+  return ok(synthesizeNativeTouchDrag(target, aX, aY + 40, 0, -40), "Synthesized vertical drag");
+}
+
+function tapComplete() {
+  var button = document.getElementById('btnComplete');
+  return button.click();
+}
+
+// The main body functions to simulate the input events required for the named test
+
+function* pointerevent_touch_action_auto_css_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollDown();
+}
+
+function* pointerevent_touch_action_button_test_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollDown('#target0 > button');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > button');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_auto_child_none_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_none_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#target0 > div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_pan_x_child_pan_x_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_pan_x_child_pan_y_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_highest_parent_none_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#target0 > div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > div');
+}
+
+function* pointerevent_touch_action_inherit_parent_none_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_none_css_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_pan_x_css_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_pan_x_pan_y_pan_y_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0 > div div');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_pan_x_pan_y_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight();
+}
+
+function* pointerevent_touch_action_pan_y_css_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_span_test_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollDown('#testspan');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#testspan');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_svg_test_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollRight();
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollDown('#target0', 250, 250);
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#target0', 250, 250);
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+function* pointerevent_touch_action_table_test_touch_manual(testDriver) {
+  touchActionSetup(testDriver);
+
+  yield touchScrollDown('#row1');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollRight('#row1');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield setTimeout(testDriver, 2 * scrollReturnInterval);
+  yield touchScrollDown('#cell3');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield touchScrollRight('#cell3');
+  yield waitForApzFlushedRepaints(testDriver);
+  yield tapComplete();
+}
+
+// This the stuff that runs the appropriate body function above
+
+var test = eval(_ACTIVE_TEST_NAME.replace(/-/g, '_'));
+waitUntilApzStable().then(runContinuation(test));