tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_bug935876.html (15365B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <!--
      4 https://bugzilla.mozilla.org/show_bug.cgi?id=935876
      5 -->
      6 <head>
      7  <meta charset="utf-8">
      8  <title>Test for Bug 935876</title>
      9  <script src="/tests/SimpleTest/SimpleTest.js"></script>
     10  <script src="/tests/SimpleTest/EventUtils.js"></script>
     11  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
     12 </head>
     13 <body>
     14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=935876">Mozilla Bug 935876</a>
     15 <p id="display"></p>
     16 <div>
     17 <select id="listbox" size="3">
     18  <option selected>1</option>
     19  <option>2</option>
     20  <option>3</option>
     21  <option>4</option>
     22  <option>5</option>
     23  <option>6</option>
     24  <option>7</option>
     25 </select>
     26 <select id="multipleListbox" size="3" multiple>
     27  <option selected>1</option>
     28  <option>2</option>
     29  <option>3</option>
     30  <option>4</option>
     31  <option>5</option>
     32  <option>6</option>
     33  <option>7</option>
     34 </select>
     35 <select id="combobox">
     36  <option selected>1</option>
     37  <option>2</option>
     38  <option>3</option>
     39  <option>4</option>
     40  <option>5</option>
     41  <option>6</option>
     42  <option>7</option>
     43 </select>
     44 </div>
     45 <pre id="test">
     46 </pre>
     47 <script type="application/javascript">
     48 SimpleTest.waitForExplicitFinish();
     49 
     50 const kIsWin = navigator.platform.indexOf("Win") == 0;
     51 const kIsMac = navigator.platform.indexOf("Mac") == 0;
     52 const kIsAndroid = navigator.appVersion.indexOf("Android") != 0;
     53 
     54 function runTests()
     55 {
     56  var doPreventDefault = false;
     57  function onKeydown(aEvent)
     58  {
     59    if (doPreventDefault) {
     60      aEvent.preventDefault();
     61    }
     62  }
     63 
     64  var keyPressEventFired = false;
     65  function onKeypress(aEvent)
     66  {
     67    keyPressEventFired = true;
     68  }
     69 
     70  var keyDownEventConsumedByJS = false;
     71  var keyDownEventConsumed = false;
     72  function onkeydownInSystemEventGroup(aEvent)
     73  {
     74    keyDownEventConsumedByJS = aEvent.defaultPrevented;
     75    // If defaultPrevented is true via SpecialPowers, that means default was
     76    // prevented, possibly in a non-content-visible way (e.g. by a system
     77    // group handler).
     78    keyDownEventConsumed = SpecialPowers.wrap(aEvent).defaultPrevented;
     79  }
     80 
     81  function reset()
     82  {
     83    keyPressEventFired = false;
     84    keyDownEventConsumedByJS = false;
     85    keyDownEventConsumed = false;
     86  }
     87 
     88  function check(aExpectingKeydownConsumed, aIsPrintableKey, aDescription)
     89  {
     90    if (doPreventDefault) {
     91      ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription +
     92                              " if preventDefault() of keydown event was called");
     93      ok(keyDownEventConsumedByJS, "keydown event of " + aDescription +
     94                                   " should be consumed in content level if preventDefault() of keydown event is called");
     95      ok(keyDownEventConsumed, "keydown event of " + aDescription +
     96                               " should be consumed in system level if preventDefault() of keydown event is called");
     97    } else if (aExpectingKeydownConsumed) {
     98      ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription);
     99      ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
    100      ok(keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
    101    } else {
    102      if (aIsPrintableKey) {
    103        ok(keyPressEventFired, "keypress event should be fired for printable key, " + aDescription);
    104      } else {
    105        ok(!keyPressEventFired, "keypress event shouldn't be fired for non-printable key, " + aDescription);
    106      }
    107      ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
    108      ok(!keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
    109    }
    110  }
    111 
    112  var listbox = document.getElementById("listbox");
    113  listbox.addEventListener("keydown", onKeydown);
    114  listbox.addEventListener("keypress", onKeypress);
    115  SpecialPowers.wrap(listbox).addEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true });
    116 
    117  listbox.focus();
    118 
    119  [ false, true ].forEach(function (consume) {
    120    doPreventDefault = consume;
    121    for (var i = 0; i < listbox.options.length + 1; i++) {
    122      reset()
    123      synthesizeKey("KEY_ArrowDown");
    124      check(true, false, "DownArrow key on listbox #" + i);
    125    }
    126 
    127    for (var i = 0; i < listbox.options.length + 1; i++) {
    128      reset()
    129      synthesizeKey("KEY_ArrowUp");
    130      check(true, false, "'ArrowUp' key on listbox #" + i);
    131    }
    132 
    133    for (var i = 0; i < listbox.options.length + 1; i++) {
    134      reset()
    135      synthesizeKey("KEY_ArrowRight");
    136      check(true, false, "'ArrowRight' key on listbox #" + i);
    137    }
    138 
    139    for (var i = 0; i < listbox.options.length + 1; i++) {
    140      reset()
    141      synthesizeKey("KEY_ArrowLeft");
    142      check(true, false, "'ArrowLeft' key on listbox #" + i);
    143    }
    144 
    145    for (var i = 0; i < 4; i++) {
    146      reset()
    147      synthesizeKey("KEY_PageDown");
    148      check(true, false, "'PageDown' key on listbox #" + i);
    149    }
    150 
    151    for (var i = 0; i < 4; i++) {
    152      reset()
    153      synthesizeKey("KEY_PageUp");
    154      check(true, false, "'PageUp' key on listbox #" + i);
    155    }
    156 
    157    for (var i = 0; i < 2; i++) {
    158      reset()
    159      synthesizeKey("KEY_End");
    160      check(true, false, "'End' key on listbox #" + i);
    161    }
    162 
    163    for (var i = 0; i < 2; i++) {
    164      reset()
    165      synthesizeKey("KEY_Home");
    166      check(true, false, "'Home' key on listbox #" + i);
    167    }
    168 
    169    reset()
    170    synthesizeKey("KEY_Enter");
    171    check(false, true, "'Enter' key on listbox");
    172 
    173    reset()
    174    synthesizeKey("KEY_Escape");
    175    check(false, false, "'Escape' key on listbox");
    176 
    177    reset()
    178    synthesizeKey("KEY_F4");
    179    check(false, false, "F4 key on listbox");
    180 
    181    reset()
    182    sendString("a");
    183    check(false, true, "'A' key on listbox");
    184  });
    185 
    186  listbox.removeEventListener("keydown", onKeydown);
    187  listbox.removeEventListener("keypress", onKeypress);
    188  SpecialPowers.wrap(listbox).removeEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true });
    189 
    190 
    191  var multipleListbox = document.getElementById("multipleListbox");
    192  multipleListbox.addEventListener("keydown", onKeydown);
    193  multipleListbox.addEventListener("keypress", onKeypress);
    194  SpecialPowers.wrap(multipleListbox).addEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true });
    195 
    196  multipleListbox.focus();
    197 
    198  [ false, true ].forEach(function (consume) {
    199    doPreventDefault = consume;
    200    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
    201      reset()
    202      synthesizeKey("KEY_ArrowDown");
    203      check(true, false, "'ArrowDown' key on multiple listbox #" + i);
    204    }
    205 
    206    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
    207      reset()
    208      synthesizeKey("KEY_ArrowUp");
    209      check(true, false, "'ArrowUp' key on multiple listbox #" + i);
    210    }
    211 
    212    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
    213      reset()
    214      synthesizeKey("KEY_ArrowRight");
    215      check(true, false, "'ArrowRight' key on multiple listbox #" + i);
    216    }
    217 
    218    for (var i = 0; i < multipleListbox.options.length + 1; i++) {
    219      reset()
    220      synthesizeKey("KEY_ArrowLeft");
    221      check(true, false, "'ArrowLeft' key on multiple listbox #" + i);
    222    }
    223 
    224    for (var i = 0; i < 4; i++) {
    225      reset()
    226      synthesizeKey("KEY_PageDown");
    227      check(true, false, "'PageDown' key on multiple listbox #" + i);
    228    }
    229 
    230    for (var i = 0; i < 4; i++) {
    231      reset()
    232      synthesizeKey("KEY_PageUp");
    233      check(true, false, "'PageUp' key on multiple listbox #" + i);
    234    }
    235 
    236    for (var i = 0; i < 2; i++) {
    237      reset()
    238      synthesizeKey("KEY_End");
    239      check(true, false, "'End' key on multiple listbox #" + i);
    240    }
    241 
    242    for (var i = 0; i < 2; i++) {
    243      reset()
    244      synthesizeKey("KEY_Home");
    245      check(true, false, "'Home' key on multiple listbox #" + i);
    246    }
    247 
    248    reset()
    249    synthesizeKey("KEY_Enter");
    250    check(true, true, "'Enter' key on multiple listbox");
    251 
    252    reset()
    253    synthesizeKey("KEY_Escape");
    254    check(false, false, "'Escape' key on multiple listbox");
    255 
    256    reset()
    257    synthesizeKey("KEY_F4");
    258    check(false, false, "'F4' key on multiple listbox");
    259 
    260    reset()
    261    sendString("a");
    262    check(false, true, "'A' key on multiple listbox");
    263  });
    264 
    265  multipleListbox.removeEventListener("keydown", onKeydown);
    266  multipleListbox.removeEventListener("keypress", onKeypress);
    267  SpecialPowers.wrap(multipleListbox).removeEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true });
    268 
    269 
    270  var combobox = document.getElementById("combobox");
    271  combobox.addEventListener("keydown", onKeydown);
    272  combobox.addEventListener("keypress", onKeypress);
    273  SpecialPowers.wrap(combobox).addEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true });
    274 
    275  combobox.focus();
    276 
    277  [ false, true ].forEach(function (consume) {
    278    doPreventDefault = consume;
    279    if (!kIsMac) {
    280      for (var i = 0; i < combobox.options.length + 1; i++) {
    281        reset()
    282        synthesizeKey("KEY_ArrowDown");
    283        check(true, false, "'ArrowDown' key on combobox #" + i);
    284      }
    285 
    286      for (var i = 0; i < combobox.options.length + 1; i++) {
    287        reset()
    288        synthesizeKey("KEY_ArrowUp");
    289        check(true, false, "'ArrowUp' key on combobox #" + i);
    290      }
    291    } else {
    292      todo(false, "Make this test work on OSX");
    293    }
    294 
    295    for (var i = 0; i < combobox.options.length + 1; i++) {
    296      reset()
    297      synthesizeKey("KEY_ArrowRight");
    298      check(true, false, "'ArrowRight' key on combobox #" + i);
    299    }
    300 
    301    for (var i = 0; i < combobox.options.length + 1; i++) {
    302      reset()
    303      synthesizeKey("KEY_ArrowLeft");
    304      check(true, false, "'ArrowLeft' key on combobox #" + i);
    305    }
    306 
    307    for (var i = 0; i < 4; i++) {
    308      reset()
    309      synthesizeKey("KEY_PageDown");
    310      check(true, false, "'PageDown' key on combobox #" + i);
    311    }
    312 
    313    for (var i = 0; i < 4; i++) {
    314      reset()
    315      synthesizeKey("KEY_PageUp");
    316      check(true, false, "'PageUp' key on combobox #" + i);
    317    }
    318 
    319    for (var i = 0; i < 2; i++) {
    320      reset()
    321      synthesizeKey("KEY_End");
    322      check(true, false, "'End' key on combobox #" + i);
    323    }
    324 
    325    for (var i = 0; i < 2; i++) {
    326      reset()
    327      synthesizeKey("KEY_Home");
    328      check(true, false, "'Home' key on combobox #" + i);
    329    }
    330 
    331    reset()
    332    synthesizeKey("KEY_Enter");
    333    check(false, true, "'Enter' key on combobox");
    334 
    335    reset()
    336    synthesizeKey("KEY_Escape");
    337    check(false, false, "'Escape' key on combobox");
    338 
    339    if (!kIsWin) {
    340      reset()
    341      synthesizeKey("KEY_F4");
    342      check(false, false, "'F4' key on combobox");
    343    }
    344 
    345    reset()
    346    sendString("a");
    347    check(false, true, "'A' key on combobox");
    348  });
    349 
    350  function finish()
    351  {
    352    combobox.removeEventListener("keydown", onKeydown);
    353    combobox.removeEventListener("keypress", onKeypress);
    354    SpecialPowers.wrap(combobox).removeEventListener("keydown", onkeydownInSystemEventGroup, { mozSystemGroup: true });
    355    SimpleTest.finish();
    356  }
    357 
    358  // Mac uses native popup for dropdown.  Let's skip the tests for popup
    359  // since it's not handled in nsListControlFrame.
    360  // Similarly, Android doesn't use popup for dropdown.
    361  if (kIsMac || kIsAndroid) {
    362    finish();
    363    return;
    364  }
    365 
    366  function testDropDown(aCallback)
    367  {
    368    testOpenDropDown(function () {
    369      reset()
    370      synthesizeKey("KEY_ArrowDown", {altKey: true});
    371    }, function () {
    372      check(true, false, "Alt + DownArrow key on combobox at opening dropdown");
    373 
    374      for (var i = 0; i < combobox.options.length + 1; i++) {
    375        reset()
    376        synthesizeKey("KEY_ArrowDown");
    377        check(true, false, "'ArrowDown' key on combobox during dropdown open #" + i);
    378      }
    379 
    380      for (var i = 0; i < combobox.options.length + 1; i++) {
    381        reset()
    382        synthesizeKey("KEY_ArrowUp");
    383        check(true, false, "'ArrowUp' key on combobox during dropdown open #" + i);
    384      }
    385 
    386      for (var i = 0; i < combobox.options.length + 1; i++) {
    387        reset()
    388        synthesizeKey("KEY_ArrowRight");
    389        check(true, false, "'ArrowRight' key on combobox during dropdown open #" + i);
    390      }
    391 
    392      for (var i = 0; i < combobox.options.length + 1; i++) {
    393        reset()
    394        synthesizeKey("KEY_ArrowLeft");
    395        check(true, false, "'ArrowLeft' key on combobox during dropdown open #" + i);
    396      }
    397 
    398      for (var i = 0; i < 4; i++) {
    399        reset()
    400        synthesizeKey("KEY_PageDown");
    401        check(true, false, "'PageDown' key on combobox during dropdown open #" + i);
    402      }
    403 
    404      for (var i = 0; i < 4; i++) {
    405        reset()
    406        synthesizeKey("KEY_PageUp");
    407        check(true, false, "'PageUp' key on combobox during dropdown open #" + i);
    408      }
    409 
    410      for (var i = 0; i < 2; i++) {
    411        reset()
    412        synthesizeKey("KEY_End");
    413        check(true, false, "'End' key on combobox during dropdown open #" + i);
    414      }
    415 
    416      for (var i = 0; i < 2; i++) {
    417        reset()
    418        synthesizeKey("KEY_Home");
    419        check(true, false, "'Home' key on combobox during dropdown open #" + i);
    420      }
    421 
    422      testCloseDropDown(function () {
    423        reset()
    424        synthesizeKey("KEY_Enter");
    425      }, function () {
    426        testOpenDropDown(function () {
    427          check(true, true, "'Enter' key on combobox at closing dropdown");
    428 
    429          synthesizeKey("KEY_ArrowUp", {altKey: true});
    430        }, function () {
    431          check(true, false, "'Alt' + 'ArrowUp' key on combobox at opening dropdown");
    432 
    433          testCloseDropDown(function () {
    434            reset()
    435            synthesizeKey("KEY_Escape");
    436          }, function () {
    437            check(true, false, "'Escape' key on combobox at closing dropdown");
    438 
    439            // F4 key opens/closes dropdown only on Windows. So, other platforms
    440            // don't need to do anymore.
    441            if (!kIsWin) {
    442              aCallback();
    443              return;
    444            }
    445 
    446            testOpenDropDown(function () {
    447              reset()
    448              synthesizeKey("KEY_F4");
    449            }, function () {
    450              check(true, false, "'F4' key on combobox at opening dropdown on Windows");
    451 
    452              testCloseDropDown(function () {
    453                reset()
    454                synthesizeKey("KEY_F4");
    455              }, function () {
    456                check(true, false, "'F4' key on combobox at closing dropdown on Windows");
    457 
    458                aCallback();
    459                return;
    460              });
    461            });
    462          });
    463        });
    464      });
    465    });
    466  }
    467 
    468  doPreventDefault = false;
    469  testDropDown(function () {
    470    // Even if keydown event is consumed by JS, opening/closing dropdown
    471    // should work for a11y and security (e.g., cannot close dropdown causes
    472    // staying top-most window on the screen).  If it's blocked by JS, this
    473    // test would cause permanent timeout.
    474    doPreventDefault = true;
    475    testDropDown(finish);
    476  });
    477 }
    478 
    479 function testOpenDropDown(aTest, aOnOpenDropDown)
    480 {
    481  document.addEventListener("popupshowing", function (aEvent) {
    482    document.removeEventListener(aEvent.type, arguments.callee);
    483    setTimeout(aOnOpenDropDown, 0);
    484  });
    485  aTest();
    486 }
    487 
    488 function testCloseDropDown(aTest, aOnCloseDropDown)
    489 {
    490  document.addEventListener("popuphiding", function (aEvent) {
    491    document.removeEventListener(aEvent.type, arguments.callee);
    492    setTimeout(aOnCloseDropDown, 0)
    493  });
    494  aTest();
    495 }
    496 
    497 SimpleTest.waitForFocus(runTests);
    498 </script>
    499 </body>
    500 </html>