Bug 935876 part.2 Add new tests r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 29 Jan 2014 17:06:26 +0900
changeset 181734 1ab856ce8afe62e02be13f3044f3817e905264b6
parent 181733 3cbec86b24821ed69658931685c8ec99e1670d4a
child 181735 c5ba0255edf1018ae4225e7994e8f3b3f7ca4bb8
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs935876
milestone29.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 935876 part.2 Add new tests r=smaug
layout/forms/test/mochitest.ini
layout/forms/test/test_bug935876.html
testing/mochitest/b2g-desktop.json
--- a/layout/forms/test/mochitest.ini
+++ b/layout/forms/test/mochitest.ini
@@ -30,14 +30,15 @@ support-files =
 [test_bug595310.html]
 [test_bug620936.html]
 [test_bug644542.html]
 [test_bug672810.html]
 [test_bug704049.html]
 [test_bug717878_input_scroll.html]
 [test_bug869314.html]
 [test_bug903715.html]
+[test_bug935876.html]
 [test_bug957562.html]
 [test_bug960277.html]
 [test_listcontrol_search.html]
 [test_select_prevent_default.html]
 [test_textarea_resize.html]
 [test_bug961363.html]
new file mode 100644
--- /dev/null
+++ b/layout/forms/test/test_bug935876.html
@@ -0,0 +1,491 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=935876
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 935876</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=935876">Mozilla Bug 935876</a>
+<p id="display"></p>
+<div>
+<select id="listbox" size="3">
+  <option selected>1</option>
+  <option>2</option>
+  <option>3</option>
+  <option>4</option>
+  <option>5</option>
+  <option>6</option>
+  <option>7</option>
+</select>
+<select id="multipleListbox" size="3" multiple>
+  <option selected>1</option>
+  <option>2</option>
+  <option>3</option>
+  <option>4</option>
+  <option>5</option>
+  <option>6</option>
+  <option>7</option>
+</select>
+<select id="combobox">
+  <option selected>1</option>
+  <option>2</option>
+  <option>3</option>
+  <option>4</option>
+  <option>5</option>
+  <option>6</option>
+  <option>7</option>
+</select>
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+const kIsWin = navigator.platform.indexOf("Win") == 0;
+const kIsMac = navigator.platform.indexOf("Mac") == 0;
+const kIsAndroid = navigator.appVersion.indexOf("Android") != 0;
+
+function runTests()
+{
+  var doPreventDefault = false;
+  function onKeydown(aEvent)
+  {
+    if (doPreventDefault) {
+      aEvent.preventDefault();
+    }
+  }
+
+  var keyPressEventFired = false;
+  function onKeypress(aEvent)
+  {
+    keyPressEventFired = true;
+  }
+
+  var keyDownEventConsumedByJS = false;
+  var keyDownEventConsumed = false;
+  function onkeydownInSystemEventGroup(aEvent)
+  {
+    keyDownEventConsumedByJS = aEvent.defaultPrevented;
+    keyDownEventConsumed = aEvent.getPreventDefault();
+  }
+
+  function reset()
+  {
+    keyPressEventFired = false;
+    keyDownEventConsumedByJS = false;
+    keyDownEventConsumed = false;
+  }
+
+  function check(aExpectingKeydownConsumed, aDescription)
+  {
+    if (doPreventDefault) {
+      ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription +
+                              " if preventDefault() of keydown event was called");
+      ok(keyDownEventConsumedByJS, "keydown event of " + aDescription +
+                                   " should be consumed in content level if preventDefault() of keydown event is called");
+      ok(keyDownEventConsumed, "keydown event of " + aDescription +
+                               " should be consumed in system level if preventDefault() of keydown event is called");
+    } else if (aExpectingKeydownConsumed) {
+      ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription);
+      ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
+      ok(keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
+    } else {
+      ok(keyPressEventFired, "keypress event should be fired for " + aDescription);
+      ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
+      ok(!keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
+    }
+  }
+
+  var listbox = document.getElementById("listbox");
+  listbox.addEventListener("keydown", onKeydown, false);
+  listbox.addEventListener("keypress", onKeypress, false);
+  SpecialPowers.addSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false);
+
+  listbox.focus();
+
+  [ false, true ].forEach(function (consume) {
+    doPreventDefault = consume;
+    for (var i = 0; i < listbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_DOWN", {});
+      check(true, "DownArrow key on listbox #" + i);
+    }
+
+    for (var i = 0; i < listbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_UP", {});
+      check(true, "UpArrow key on listbox #" + i);
+    }
+
+    for (var i = 0; i < listbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_RIGHT", {});
+      check(true, "RightArrow key on listbox #" + i);
+    }
+
+    for (var i = 0; i < listbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_LEFT", {});
+      check(true, "LeftArrow key on listbox #" + i);
+    }
+
+    for (var i = 0; i < 4; i++) {
+      reset()
+      synthesizeKey("VK_PAGE_DOWN", {});
+      check(true, "PageDown key on listbox #" + i);
+    }
+
+    for (var i = 0; i < 4; i++) {
+      reset()
+      synthesizeKey("VK_PAGE_UP", {});
+      check(true, "PageUp key on listbox #" + i);
+    }
+
+    for (var i = 0; i < 2; i++) {
+      reset()
+      synthesizeKey("VK_END", {});
+      check(true, "End key on listbox #" + i);
+    }
+
+    for (var i = 0; i < 2; i++) {
+      reset()
+      synthesizeKey("VK_HOME", {});
+      check(true, "Home key on listbox #" + i);
+    }
+
+    reset()
+    synthesizeKey("VK_RETURN", {});
+    check(false, "Enter key on listbox");
+
+    reset()
+    synthesizeKey("VK_ESCAPE", {});
+    check(false, "Esc key on listbox");
+
+    reset()
+    synthesizeKey("VK_F4", {});
+    check(false, "F4 key on listbox");
+
+    reset()
+    synthesizeKey("a", {});
+    check(false, "'A' key on listbox");
+  });
+
+  listbox.removeEventListener("keydown", onKeydown, false);
+  listbox.removeEventListener("keypress", onKeypress, false);
+  SpecialPowers.removeSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false);
+
+
+
+  var multipleListbox = document.getElementById("multipleListbox");
+  multipleListbox.addEventListener("keydown", onKeydown, false);
+  multipleListbox.addEventListener("keypress", onKeypress, false);
+  SpecialPowers.addSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false);
+
+  multipleListbox.focus();
+
+  [ false, true ].forEach(function (consume) {
+    doPreventDefault = consume;
+    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_DOWN", {});
+      check(true, "DownArrow key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_UP", {});
+      check(true, "UpArrow key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_RIGHT", {});
+      check(true, "RightArrow key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_LEFT", {});
+      check(true, "LeftArrow key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < 4; i++) {
+      reset()
+      synthesizeKey("VK_PAGE_DOWN", {});
+      check(true, "PageDown key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < 4; i++) {
+      reset()
+      synthesizeKey("VK_PAGE_UP", {});
+      check(true, "PageUp key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < 2; i++) {
+      reset()
+      synthesizeKey("VK_END", {});
+      check(true, "End key on multiple listbox #" + i);
+    }
+
+    for (var i = 0; i < 2; i++) {
+      reset()
+      synthesizeKey("VK_HOME", {});
+      check(true, "Home key on multiple listbox #" + i);
+    }
+
+    reset()
+    synthesizeKey("VK_RETURN", {});
+    check(true, "Enter key on multiple listbox");
+
+    reset()
+    synthesizeKey("VK_ESCAPE", {});
+    check(false, "Esc key on multiple listbox");
+
+    reset()
+    synthesizeKey("VK_F4", {});
+    check(false, "F4 key on multiple listbox");
+
+    reset()
+    synthesizeKey("a", {});
+    check(false, "'A' key on multiple listbox");
+  });
+
+  multipleListbox.removeEventListener("keydown", onKeydown, false);
+  multipleListbox.removeEventListener("keypress", onKeypress, false);
+  SpecialPowers.removeSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false);
+
+
+
+  var combobox = document.getElementById("combobox");
+  combobox.addEventListener("keydown", onKeydown, false);
+  combobox.addEventListener("keypress", onKeypress, false);
+  SpecialPowers.addSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false);
+
+  combobox.focus();
+
+  [ false, true ].forEach(function (consume) {
+    doPreventDefault = consume;
+    for (var i = 0; i < combobox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_DOWN", {});
+      check(true, "DownArrow key on combobox #" + i);
+    }
+
+    for (var i = 0; i < combobox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_UP", {});
+      check(true, "UpArrow key on combobox #" + i);
+    }
+
+    for (var i = 0; i < combobox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_RIGHT", {});
+      check(true, "RightArrow key on combobox #" + i);
+    }
+
+    for (var i = 0; i < combobox.options.length + 1; i++) {
+      reset()
+      synthesizeKey("VK_LEFT", {});
+      check(true, "LeftArrow key on combobox #" + i);
+    }
+
+    for (var i = 0; i < 4; i++) {
+      reset()
+      synthesizeKey("VK_PAGE_DOWN", {});
+      check(true, "PageDown key on combobox #" + i);
+    }
+
+    for (var i = 0; i < 4; i++) {
+      reset()
+      synthesizeKey("VK_PAGE_UP", {});
+      check(true, "PageUp key on combobox #" + i);
+    }
+
+    for (var i = 0; i < 2; i++) {
+      reset()
+      synthesizeKey("VK_END", {});
+      check(true, "End key on combobox #" + i);
+    }
+
+    for (var i = 0; i < 2; i++) {
+      reset()
+      synthesizeKey("VK_HOME", {});
+      check(true, "Home key on combobox #" + i);
+    }
+
+    reset()
+    synthesizeKey("VK_RETURN", {});
+    check(true, "Enter key on combobox");
+
+    reset()
+    synthesizeKey("VK_ESCAPE", {});
+    check(true, "Esc key on combobox");
+
+    if (!kIsWin) {
+      reset()
+      synthesizeKey("VK_F4", {});
+      check(false, "F4 key on combobox");
+    }
+
+    reset()
+    synthesizeKey("a", {});
+    check(false, "'A' key on combobox");
+  });
+
+  function finish()
+  {
+    combobox.removeEventListener("keydown", onKeydown, false);
+    combobox.removeEventListener("keypress", onKeypress, false);
+    SpecialPowers.removeSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false);
+    SimpleTest.finish();
+  }
+
+  // Mac uses native popup for dropdown.  Let's skip the tests for popup
+  // since it's not handled in nsListControlFrame.
+  // Similarly, Android doesn't use popup for dropdown.
+  if (kIsMac || kIsAndroid) {
+    finish();
+    return;
+  }
+
+  function testDropDown(aCallback)
+  {
+    testOpenDropDown(function () {
+      reset()
+      synthesizeKey("VK_DOWN", { altKey: true });
+    }, function () {
+      check(true, "Alt + DownArrow key on combobox at opening dropdown");
+
+      for (var i = 0; i < combobox.options.length + 1; i++) {
+        reset()
+        synthesizeKey("VK_DOWN", {});
+        check(true, "DownArrow key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < combobox.options.length + 1; i++) {
+        reset()
+        synthesizeKey("VK_UP", {});
+        check(true, "UpArrow key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < combobox.options.length + 1; i++) {
+        reset()
+        synthesizeKey("VK_RIGHT", {});
+        check(true, "RightArrow key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < combobox.options.length + 1; i++) {
+        reset()
+        synthesizeKey("VK_LEFT", {});
+        check(true, "LeftArrow key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < 4; i++) {
+        reset()
+        synthesizeKey("VK_PAGE_DOWN", {});
+        check(true, "PageDown key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < 4; i++) {
+        reset()
+        synthesizeKey("VK_PAGE_UP", {});
+        check(true, "PageUp key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < 2; i++) {
+        reset()
+        synthesizeKey("VK_END", {});
+        check(true, "End key on combobox during dropdown open #" + i);
+      }
+
+      for (var i = 0; i < 2; i++) {
+        reset()
+        synthesizeKey("VK_HOME", {});
+        check(true, "Home key on combobox during dropdown open #" + i);
+      }
+
+      testCloseDropDown(function () {
+        reset()
+        synthesizeKey("VK_RETURN", {});
+      }, function () {
+        testOpenDropDown(function () {
+          check(true, "Enter key on combobox at closing dropdown");
+
+          synthesizeKey("VK_UP", { altKey: true });
+        }, function () {
+          check(true, "Alt + UpArrow key on combobox at opening dropdown");
+
+          testCloseDropDown(function () {
+            reset()
+            synthesizeKey("VK_ESCAPE", {});
+          }, function () {
+            check(true, "Esc key on combobox at closing dropdown");
+
+            // F4 key opens/closes dropdown only on Windows. So, other platforms
+            // don't need to do anymore.
+            if (!kIsWin) {
+              aCallback();
+              return;
+            }
+
+            testOpenDropDown(function () {
+              reset()
+              synthesizeKey("VK_F4", {});
+            }, function () {
+              check(true, "F4 key on combobox at opening dropdown on Windows");
+
+              testCloseDropDown(function () {
+                reset()
+                synthesizeKey("VK_F4", {});
+              }, function () {
+                check(true, "F4 key on combobox at closing dropdown on Windows");
+
+                aCallback();
+                return;
+              });
+            });
+          });
+        });
+      });
+    });
+  }
+
+  doPreventDefault = false;
+  testDropDown(function () {
+    // Even if keydown event is consumed by JS, opening/closing dropdown
+    // should work for a11y and security (e.g., cannot close dropdown causes
+    // staying top-most window on the screen).  If it's blocked by JS, this
+    // test would cause permanent timeout.
+    doPreventDefault = true;
+    testDropDown(finish);
+  });
+}
+
+function testOpenDropDown(aTest, aOnOpenDropDown)
+{
+  document.addEventListener("popupshowing", function (aEvent) {
+    document.removeEventListener(aEvent.type, arguments.callee, false);
+    setTimeout(aOnOpenDropDown, 0);
+  }, false);
+  aTest();
+}
+
+function testCloseDropDown(aTest, aOnCloseDropDown)
+{
+  document.addEventListener("popuphiding", function (aEvent) {
+    document.removeEventListener(aEvent.type, arguments.callee, false);
+    setTimeout(aOnCloseDropDown, 0)
+  }, false);
+  aTest();
+}
+
+SimpleTest.waitForFocus(runTests);
+</script>
+</body>
+</html>
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -385,16 +385,17 @@
     "layout/base/tests/test_bug629838.html":"depends on plugins support",
     "layout/base/tests/test_mozPaintCount.html":"depends on plugins support",
     "layout/forms/test/test_bug348236.html":"select form control popup",
     "layout/forms/test/test_bug446663.html":"needs copy support",
     "layout/forms/test/test_bug564115.html":"times out on window.open and focus event",
     "layout/forms/test/test_bug571352.html":"shift-click multi-select not working?",
     "layout/forms/test/test_textarea_resize.html":"resizing textarea not available in b2g",
     "layout/forms/test/test_bug903715.html":"select elements don't use an in-page popup in B2G",
+    "layout/forms/test/test_bug935876.html":"Esc key is consumed by another event handler only on desktop B2G",
     "layout/forms/test/test_listcontrol_search.html" : "select elements don't use an in-page popup in B2G",
     "layout/generic/test/test_bug392746.html":"ctrl mouse select not working in b2g",
     "layout/generic/test/test_bug470212.html":"shift mouse select not working in b2g",
     "layout/generic/test/test_bug514732.html":"times out, also on Android",
     "layout/generic/test/test_bug791616.html":"Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438",
     "layout/generic/test/test_invalidate_during_plugin_paint.html":"plugins not supported",
     "layout/generic/test/test_page_scroll_with_fixed_pos.html":"opened window too small?",
     "layout/generic/test/test_plugin_focus.html":"plugins not supported",