toolkit/components/satchel/test/test_form_autocomplete.html

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/components/satchel/test/test_form_autocomplete.html	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1053 @@
     1.4 +<!DOCTYPE HTML>
     1.5 +<html>
     1.6 +<head>
     1.7 +  <title>Test for Form History Autocomplete</title>
     1.8 +  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     1.9 +  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
    1.10 +  <script type="text/javascript" src="satchel_common.js"></script>
    1.11 +  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    1.12 +</head>
    1.13 +<body>
    1.14 +Form History test: form field autocomplete
    1.15 +<p id="display"></p>
    1.16 +
    1.17 +<!-- We presumably can't hide the content for this test. The large top padding is to allow
    1.18 +     listening for scrolls to occur. -->
    1.19 +<div id="content" style="padding-top: 20000px;">
    1.20 +
    1.21 +  <!-- normal, basic form -->
    1.22 +  <form id="form1" onsubmit="return false;">
    1.23 +    <input  type="text" name="field1">
    1.24 +    <button type="submit">Submit</button>
    1.25 +  </form>
    1.26 +
    1.27 +  <!-- normal, basic form (new fieldname) -->
    1.28 +  <form id="form2" onsubmit="return false;">
    1.29 +    <input  type="text" name="field2">
    1.30 +    <button type="submit">Submit</button>
    1.31 +  </form>
    1.32 +
    1.33 +  <!-- form with autocomplete=off on input -->
    1.34 +  <form id="form3" onsubmit="return false;">
    1.35 +    <input  type="text" name="field2" autocomplete="off">
    1.36 +    <button type="submit">Submit</button>
    1.37 +  </form>
    1.38 +
    1.39 +  <!-- form with autocomplete=off on form -->
    1.40 +  <form id="form4" autocomplete="off" onsubmit="return false;">
    1.41 +    <input  type="text" name="field2">
    1.42 +    <button type="submit">Submit</button>
    1.43 +  </form>
    1.44 +
    1.45 +  <!-- normal form for testing filtering -->
    1.46 +  <form id="form5" onsubmit="return false;">
    1.47 +    <input  type="text" name="field3">
    1.48 +    <button type="submit">Submit</button>
    1.49 +  </form>
    1.50 +
    1.51 +  <!-- normal form for testing word boundary filtering -->
    1.52 +  <form id="form6" onsubmit="return false;">
    1.53 +    <input  type="text" name="field4">
    1.54 +    <button type="submit">Submit</button>
    1.55 +  </form>
    1.56 +
    1.57 +  <!-- form with maxlength attribute on input -->
    1.58 +  <form id="form7" onsubmit="return false;">
    1.59 +    <input  type="text" name="field5" maxlength="10">
    1.60 +    <button type="submit">Submit</button>
    1.61 +  </form>
    1.62 +
    1.63 +  <!-- form with input type='email' -->
    1.64 +  <form id="form8" onsubmit="return false;">
    1.65 +    <input  type="email" name="field6">
    1.66 +    <button type="submit">Submit</button>
    1.67 +  </form>
    1.68 +
    1.69 +  <!-- form with input type='tel' -->
    1.70 +  <form id="form9" onsubmit="return false;">
    1.71 +    <input  type="tel" name="field7">
    1.72 +    <button type="submit">Submit</button>
    1.73 +  </form>
    1.74 +
    1.75 +  <!-- form with input type='url' -->
    1.76 +  <form id="form10" onsubmit="return false;">
    1.77 +    <input  type="url" name="field8">
    1.78 +    <button type="submit">Submit</button>
    1.79 +  </form>
    1.80 +
    1.81 +  <!-- form with input type='search' -->
    1.82 +  <form id="form11" onsubmit="return false;">
    1.83 +    <input  type="search" name="field9">
    1.84 +    <button type="submit">Submit</button>
    1.85 +  </form>
    1.86 +
    1.87 +  <!-- form with input type='number' -->
    1.88 +  <form id="form12" onsubmit="return false;">
    1.89 +    <input  type="number" name="field10">
    1.90 +    <button type="submit">Submit</button>
    1.91 +  </form>
    1.92 +
    1.93 +  <!-- normal, basic form (with fieldname='searchbar-history') -->
    1.94 +  <form id="form13" onsubmit="return false;">
    1.95 +    <input  type="text" name="searchbar-history">
    1.96 +    <button type="submit">Submit</button>
    1.97 +  </form>
    1.98 +
    1.99 +  <!-- form with input type='date' -->
   1.100 +  <form id="form14" onsubmit="return false;">
   1.101 +    <input  type="date" name="field11">
   1.102 +    <button type="submit">Submit</button>
   1.103 +  </form>
   1.104 +
   1.105 +  <!-- form with input type='time' -->
   1.106 +  <form id="form15" onsubmit="return false;">
   1.107 +    <input  type="time" name="field12">
   1.108 +    <button type="submit">Submit</button>
   1.109 +  </form>
   1.110 +
   1.111 +  <!-- form with input type='range' -->
   1.112 +  <form id="form16" onsubmit="return false;">
   1.113 +    <input  type="range" name="field13" max="64">
   1.114 +    <button type="submit">Submit</button>
   1.115 +  </form>
   1.116 +
   1.117 +  <!-- form with input type='color' -->
   1.118 +  <form id="form17" onsubmit="return false;">
   1.119 +    <input  type="color" name="field14">
   1.120 +    <button type="submit">Submit</button>
   1.121 +  </form>
   1.122 +
   1.123 +</div>
   1.124 +
   1.125 +<pre id="test">
   1.126 +<script class="testbody" type="text/javascript">
   1.127 +
   1.128 +/** Test for Form History autocomplete **/
   1.129 +
   1.130 +var input = $_(1, "field1");
   1.131 +const shiftModifier = Event.SHIFT_MASK;
   1.132 +
   1.133 +function setupFormHistory(aCallback) {
   1.134 +  updateFormHistory([
   1.135 +    { op : "remove" },
   1.136 +    { op : "add", fieldname : "field1", value : "value1" },
   1.137 +    { op : "add", fieldname : "field1", value : "value2" },
   1.138 +    { op : "add", fieldname : "field1", value : "value3" },
   1.139 +    { op : "add", fieldname : "field1", value : "value4" },
   1.140 +    { op : "add", fieldname : "field2", value : "value1" },
   1.141 +    { op : "add", fieldname : "field3", value : "a" },
   1.142 +    { op : "add", fieldname : "field3", value : "aa" },
   1.143 +    { op : "add", fieldname : "field3", value : "aaz" },
   1.144 +    { op : "add", fieldname : "field3", value : "aa\xe6" }, // 0xae == latin ae pair (0xc6 == AE)
   1.145 +    { op : "add", fieldname : "field3", value : "az" },
   1.146 +    { op : "add", fieldname : "field3", value : "z" },
   1.147 +    { op : "add", fieldname : "field4", value : "a\xe6" },
   1.148 +    { op : "add", fieldname : "field4", value : "aa a\xe6" },
   1.149 +    { op : "add", fieldname : "field4", value : "aba\xe6" },
   1.150 +    { op : "add", fieldname : "field4", value : "bc d\xe6" },
   1.151 +    { op : "add", fieldname : "field5", value : "1" },
   1.152 +    { op : "add", fieldname : "field5", value : "12" },
   1.153 +    { op : "add", fieldname : "field5", value : "123" },
   1.154 +    { op : "add", fieldname : "field5", value : "1234" },
   1.155 +    { op : "add", fieldname : "field6", value : "value" },
   1.156 +    { op : "add", fieldname : "field7", value : "value" },
   1.157 +    { op : "add", fieldname : "field8", value : "value" },
   1.158 +    { op : "add", fieldname : "field9", value : "value" },
   1.159 +    { op : "add", fieldname : "field10", value : "42" },
   1.160 +    { op : "add", fieldname : "field11", value : "2010-10-10" },
   1.161 +    { op : "add", fieldname : "field12", value : "21:21" },
   1.162 +    { op : "add", fieldname : "field13", value : "32" },  // not used, since type=range doesn't have a drop down menu
   1.163 +    { op : "add", fieldname : "field14", value : "#ffffff" }, // not used, since type=color doesn't have autocomplete currently
   1.164 +    { op : "add", fieldname : "searchbar-history", value : "blacklist test" },
   1.165 +  ], aCallback);
   1.166 +}
   1.167 +
   1.168 +// All these non-implemeted types might need autocomplete tests in the future.
   1.169 +var todoTypes = [ "datetime", "month", "week", "datetime-local" ];
   1.170 +var todoInput = document.createElement("input");
   1.171 +for (var type of todoTypes) {
   1.172 +  todoInput.type = type;
   1.173 +  todo_is(todoInput.type, type, type + " type shouldn't be implemented");
   1.174 +}
   1.175 +
   1.176 +
   1.177 +function setForm(value) {
   1.178 +  input.value = value;
   1.179 +  input.focus();
   1.180 +}
   1.181 +
   1.182 +var autocompleteMenu = getAutocompletePopup();
   1.183 +
   1.184 +// Restore the form to the default state.
   1.185 +function restoreForm() {
   1.186 +  setForm("");
   1.187 +}
   1.188 +
   1.189 +// Check for expected form data.
   1.190 +function checkForm(expectedValue) {
   1.191 +  var formID = input.parentNode.id;
   1.192 +  is(input.value, expectedValue, "Checking " + formID + " input");
   1.193 +}
   1.194 +
   1.195 +var testNum = 0;
   1.196 +var expectingPopup = false;
   1.197 +
   1.198 +function expectPopup()
   1.199 +{
   1.200 +  info("expecting popup for test " + testNum);
   1.201 +  expectingPopup = true;
   1.202 +}
   1.203 +
   1.204 +function popupShownListener()
   1.205 +{
   1.206 +  info("popup shown for test " + testNum);
   1.207 +  if (expectingPopup) {
   1.208 +    expectingPopup = false;
   1.209 +    SimpleTest.executeSoon(runTest);
   1.210 +  }
   1.211 +  else {
   1.212 +    ok(false, "Autocomplete popup not expected during test " + testNum);
   1.213 +  }
   1.214 +}
   1.215 +
   1.216 +SpecialPowers.addAutoCompletePopupEventListener(window, "popupshown", popupShownListener);
   1.217 +
   1.218 +/*
   1.219 + * Main section of test...
   1.220 + *
   1.221 + * This is a bit hacky, as many operations happen asynchronously.
   1.222 + * Various mechanisms call runTests as a result of operations:
   1.223 + *   - set expectingPopup to true, and the next test will occur when the autocomplete popup is shown
   1.224 + *   - call waitForMenuChange(x) to run the next test when the autocomplete popup to have x items in it 
   1.225 + *   - addEntry calls runs the test when an entry has been added
   1.226 + *   - some tests scroll the window. This is because the form fill controller happens to scroll
   1.227 + *     the field into view near the end of the search, and there isn't any other good notification
   1.228 + *     to listen to for when the search is complete.
   1.229 + *   - some items still use setTimeout
   1.230 + */
   1.231 +function runTest() {
   1.232 +  testNum++;
   1.233 +
   1.234 +  ok(true, "Starting test #" + testNum);
   1.235 +
   1.236 +  switch(testNum) {
   1.237 +    case 1:
   1.238 +        // Make sure initial form is empty.
   1.239 +        checkForm("");
   1.240 +        // Trigger autocomplete popup
   1.241 +        expectPopup();
   1.242 +        restoreForm();
   1.243 +        doKey("down");
   1.244 +        break;
   1.245 +
   1.246 +    case 2:
   1.247 +        checkMenuEntries(["value1", "value2", "value3", "value4"], testNum);
   1.248 +        // Check first entry
   1.249 +        doKey("down");
   1.250 +        checkForm(""); // value shouldn't update
   1.251 +        doKey("return"); // not "enter"!
   1.252 +        checkForm("value1");
   1.253 +
   1.254 +        // Trigger autocomplete popup
   1.255 +        expectPopup();
   1.256 +        restoreForm();
   1.257 +        doKey("down");
   1.258 +        break;
   1.259 +
   1.260 +    case 3:
   1.261 +        // Check second entry
   1.262 +        doKey("down");
   1.263 +        doKey("down");
   1.264 +        doKey("return"); // not "enter"!
   1.265 +        checkForm("value2");
   1.266 +
   1.267 +        // Trigger autocomplete popup
   1.268 +        expectPopup();
   1.269 +        restoreForm();
   1.270 +        doKey("down");
   1.271 +        break;
   1.272 +
   1.273 +    case 4:
   1.274 +        // Check third entry
   1.275 +        doKey("down");
   1.276 +        doKey("down");
   1.277 +        doKey("down");
   1.278 +        doKey("return");
   1.279 +        checkForm("value3");
   1.280 +
   1.281 +        // Trigger autocomplete popup
   1.282 +        expectPopup();
   1.283 +        restoreForm();
   1.284 +        doKey("down");
   1.285 +        break;
   1.286 +
   1.287 +    case 5:
   1.288 +        // Check fourth entry
   1.289 +        doKey("down");
   1.290 +        doKey("down");
   1.291 +        doKey("down");
   1.292 +        doKey("down");
   1.293 +        doKey("return");
   1.294 +        checkForm("value4");
   1.295 +
   1.296 +        // Trigger autocomplete popup
   1.297 +        expectPopup();
   1.298 +        restoreForm();
   1.299 +        doKey("down");
   1.300 +        break;
   1.301 +
   1.302 +    case 6:
   1.303 +        // Check first entry (wraparound)
   1.304 +        doKey("down");
   1.305 +        doKey("down");
   1.306 +        doKey("down");
   1.307 +        doKey("down");
   1.308 +        doKey("down"); // deselects
   1.309 +        doKey("down");
   1.310 +        doKey("return");
   1.311 +        checkForm("value1");
   1.312 +
   1.313 +        // Trigger autocomplete popup
   1.314 +        expectPopup();
   1.315 +        restoreForm();
   1.316 +        doKey("down");
   1.317 +        break;
   1.318 +
   1.319 +    case 7:
   1.320 +        // Check the last entry via arrow-up
   1.321 +        doKey("up");
   1.322 +        doKey("return");
   1.323 +        checkForm("value4");
   1.324 +
   1.325 +        // Trigger autocomplete popup
   1.326 +        expectPopup();
   1.327 +        restoreForm();
   1.328 +        doKey("down");
   1.329 +        break;
   1.330 +
   1.331 +    case 8:
   1.332 +        // Check the last entry via arrow-up
   1.333 +        doKey("down"); // select first entry
   1.334 +        doKey("up");   // selects nothing!
   1.335 +        doKey("up");   // select last entry
   1.336 +        doKey("return");
   1.337 +        checkForm("value4");
   1.338 +
   1.339 +        // Trigger autocomplete popup
   1.340 +        expectPopup();
   1.341 +        restoreForm();
   1.342 +        doKey("down");
   1.343 +        break;
   1.344 +
   1.345 +    case 9:
   1.346 +        // Check the last entry via arrow-up (wraparound)
   1.347 +        doKey("down");
   1.348 +        doKey("up"); // deselects
   1.349 +        doKey("up"); // last entry
   1.350 +        doKey("up");
   1.351 +        doKey("up");
   1.352 +        doKey("up"); // first entry
   1.353 +        doKey("up"); // deselects
   1.354 +        doKey("up"); // last entry
   1.355 +        doKey("return");
   1.356 +        checkForm("value4");
   1.357 +
   1.358 +        // Trigger autocomplete popup
   1.359 +        expectPopup();
   1.360 +        restoreForm();
   1.361 +        doKey("down");
   1.362 +        break;
   1.363 +
   1.364 +    case 10:
   1.365 +        // Set first entry w/o triggering autocomplete
   1.366 +        doKey("down");
   1.367 +        doKey("right");
   1.368 +        checkForm("value1");
   1.369 +
   1.370 +        // Trigger autocomplete popup
   1.371 +        expectPopup();
   1.372 +        restoreForm();
   1.373 +        doKey("down");
   1.374 +        break;
   1.375 +
   1.376 +    case 11:
   1.377 +        // Set first entry w/o triggering autocomplete
   1.378 +        doKey("down");
   1.379 +        doKey("left");
   1.380 +        checkForm("value1");
   1.381 +
   1.382 +        // Trigger autocomplete popup
   1.383 +        expectPopup();
   1.384 +        restoreForm();
   1.385 +        doKey("down");
   1.386 +        break;
   1.387 +
   1.388 +    case 12:
   1.389 +        // Check first entry (page up)
   1.390 +        doKey("down");
   1.391 +        doKey("down");
   1.392 +        doKey("page_up");
   1.393 +        doKey("return");
   1.394 +        checkForm("value1");
   1.395 +
   1.396 +        // Trigger autocomplete popup
   1.397 +        expectPopup();
   1.398 +        restoreForm();
   1.399 +        doKey("down");
   1.400 +        break;
   1.401 +
   1.402 +    case 13:
   1.403 +        // Check last entry (page down)
   1.404 +        doKey("down");
   1.405 +        doKey("page_down");
   1.406 +        doKey("return");
   1.407 +        checkForm("value4");
   1.408 +
   1.409 +        // Trigger autocomplete popup
   1.410 +        testNum = 49;
   1.411 +        expectPopup();
   1.412 +        restoreForm();
   1.413 +        doKey("down");
   1.414 +        break;
   1.415 +
   1.416 +    /* Test removing entries from the dropdown */
   1.417 +
   1.418 +    case 50:
   1.419 +        checkMenuEntries(["value1", "value2", "value3", "value4"], testNum);
   1.420 +        // Delete the first entry (of 4)
   1.421 +        setForm("value");
   1.422 +        doKey("down");
   1.423 +
   1.424 +        // On OS X, shift-backspace and shift-delete work, just delete does not.
   1.425 +        // On Win/Linux, shift-backspace does not work, delete and shift-delete do.
   1.426 +        if (SpecialPowers.OS == "Darwin")
   1.427 +          doKey("back_space", shiftModifier);
   1.428 +        else
   1.429 +          doKey("delete", shiftModifier);
   1.430 +
   1.431 +        // This tests that on OS X shift-backspace didn't delete the last character
   1.432 +        // in the input (bug 480262).
   1.433 +        waitForMenuChange(3);
   1.434 +        break;
   1.435 +
   1.436 +    case 51:
   1.437 +        checkForm("value");
   1.438 +        countEntries("field1", "value1",
   1.439 +          function (num) {
   1.440 +            ok(!num, testNum + " checking that f1/v1 was deleted");
   1.441 +            runTest();
   1.442 +          });
   1.443 +        break;
   1.444 +
   1.445 +    case 52:
   1.446 +        doKey("return");
   1.447 +        checkForm("value2");
   1.448 +
   1.449 +        // Trigger autocomplete popup
   1.450 +        expectPopup();
   1.451 +        restoreForm();
   1.452 +        doKey("down");
   1.453 +        break;
   1.454 +
   1.455 +    case 53:
   1.456 +        checkMenuEntries(["value2", "value3", "value4"], testNum);
   1.457 +        // Check the new first entry (of 3)
   1.458 +        doKey("down");
   1.459 +        doKey("return");
   1.460 +        checkForm("value2");
   1.461 +
   1.462 +        // Trigger autocomplete popup
   1.463 +        expectPopup();
   1.464 +        restoreForm();
   1.465 +        doKey("down");
   1.466 +        break;
   1.467 +
   1.468 +    case 54:
   1.469 +        // Delete the second entry (of 3)
   1.470 +        doKey("down");
   1.471 +        doKey("down");
   1.472 +        doKey("delete", shiftModifier);
   1.473 +        waitForMenuChange(2);
   1.474 +        break;
   1.475 +
   1.476 +    case 55:
   1.477 +        checkForm("");
   1.478 +        countEntries("field1", "value3",
   1.479 +          function (num) {
   1.480 +            ok(!num, testNum + " checking that f1/v3 was deleted");
   1.481 +            runTest();
   1.482 +          });
   1.483 +        break;
   1.484 +
   1.485 +    case 56:
   1.486 +        doKey("return");
   1.487 +        checkForm("value4")
   1.488 +
   1.489 +        // Trigger autocomplete popup
   1.490 +        expectPopup();
   1.491 +        restoreForm();
   1.492 +        doKey("down");
   1.493 +        break;
   1.494 +
   1.495 +    case 57:
   1.496 +        checkMenuEntries(["value2", "value4"], testNum);
   1.497 +        // Check the new first entry (of 2)
   1.498 +        doKey("down");
   1.499 +        doKey("return");
   1.500 +        checkForm("value2");
   1.501 +
   1.502 +        // Trigger autocomplete popup
   1.503 +        expectPopup();
   1.504 +        restoreForm();
   1.505 +        doKey("down");
   1.506 +        break;
   1.507 +
   1.508 +    case 58:
   1.509 +        // Delete the last entry (of 2)
   1.510 +        doKey("down");
   1.511 +        doKey("down");
   1.512 +        doKey("delete", shiftModifier);
   1.513 +        checkForm("");
   1.514 +        waitForMenuChange(1);
   1.515 +        break;
   1.516 +
   1.517 +    case 59:
   1.518 +        countEntries("field1", "value4",
   1.519 +          function (num) {
   1.520 +            ok(!num, testNum + " checking that f1/v4 was deleted");
   1.521 +            runTest();
   1.522 +          });
   1.523 +        break;
   1.524 +
   1.525 +    case 60:
   1.526 +        doKey("return");
   1.527 +        checkForm("value2");
   1.528 +
   1.529 +        // Trigger autocomplete popup
   1.530 +        expectPopup();
   1.531 +        restoreForm();
   1.532 +        doKey("down");
   1.533 +        break;
   1.534 +
   1.535 +    case 61:
   1.536 +        checkMenuEntries(["value2"], testNum);
   1.537 +        // Check the new first entry (of 1)
   1.538 +        doKey("down");
   1.539 +        doKey("return");
   1.540 +        checkForm("value2");
   1.541 +
   1.542 +        // Trigger autocomplete popup
   1.543 +        expectPopup();
   1.544 +        restoreForm();
   1.545 +        doKey("down");
   1.546 +        break;
   1.547 +
   1.548 +    case 62:
   1.549 +        // Delete the only remaining entry
   1.550 +        doKey("down");
   1.551 +        doKey("delete", shiftModifier);
   1.552 +        waitForMenuChange(0);
   1.553 +        break;
   1.554 +
   1.555 +    case 63:
   1.556 +        checkForm("");
   1.557 +        countEntries("field1", "value2",
   1.558 +          function (num) {
   1.559 +            ok(!num, testNum + " checking that f1/v2 was deleted");
   1.560 +            runTest();
   1.561 +          });
   1.562 +        break;
   1.563 +
   1.564 +    case 64:
   1.565 +        // Look at form 2, trigger autocomplete popup
   1.566 +        input = $_(2, "field2");
   1.567 +        testNum = 99;
   1.568 +        expectPopup();
   1.569 +        restoreForm();
   1.570 +        doKey("down");
   1.571 +        break;
   1.572 +
   1.573 +    /* Test entries with autocomplete=off */
   1.574 +
   1.575 +    case 100:
   1.576 +        // Select first entry
   1.577 +        doKey("down");
   1.578 +        doKey("return");
   1.579 +        checkForm("value1");
   1.580 +
   1.581 +        // Look at form 3, try to trigger autocomplete popup
   1.582 +        input = $_(3, "field2");
   1.583 +        restoreForm();
   1.584 +        // Sometimes, this will fail if scrollTo(0, 0) is called, so that doesn't
   1.585 +        // happen here. Fortunately, a different input is used from the last test,
   1.586 +        // so a scroll should still occur.
   1.587 +        doKey("down");
   1.588 +        waitForScroll();
   1.589 +        break;
   1.590 +
   1.591 +    case 101:
   1.592 +        // Ensure there's no autocomplete dropdown (autocomplete=off is present)
   1.593 +        doKey("down");
   1.594 +        doKey("return");
   1.595 +        checkForm("");
   1.596 +
   1.597 +        // Look at form 4, try to trigger autocomplete popup
   1.598 +        input = $_(4, "field2");
   1.599 +        restoreForm();
   1.600 +        doKey("down");
   1.601 +        waitForMenuChange(0);
   1.602 +        break;
   1.603 +
   1.604 +    case 102:
   1.605 +        // Ensure there's no autocomplete dropdown (autocomplete=off is present)
   1.606 +        doKey("down");
   1.607 +        doKey("return");
   1.608 +        checkForm("");
   1.609 +
   1.610 +        // Look at form 5, try to trigger autocomplete popup
   1.611 +        input = $_(5, "field3");
   1.612 +        restoreForm();
   1.613 +        testNum = 199;
   1.614 +        expectPopup();
   1.615 +        input.focus();
   1.616 +        sendChar("a");
   1.617 +        break;
   1.618 +
   1.619 +    /* Test filtering as characters are typed. */
   1.620 +
   1.621 +    case 200:
   1.622 +        checkMenuEntries(["a", "aa", "aaz", "aa\xe6", "az"], testNum);
   1.623 +        input.focus();
   1.624 +        sendChar("a");
   1.625 +        waitForMenuChange(3);
   1.626 +        break;
   1.627 +
   1.628 +    case 201:
   1.629 +        checkMenuEntries(["aa", "aaz", "aa\xe6"], testNum);
   1.630 +        input.focus();
   1.631 +        sendChar("\xc6");
   1.632 +        waitForMenuChange(1);
   1.633 +        break;
   1.634 +
   1.635 +    case 202:
   1.636 +        checkMenuEntries(["aa\xe6"], testNum);
   1.637 +        doKey("back_space");
   1.638 +        waitForMenuChange(3);
   1.639 +        break;
   1.640 +
   1.641 +    case 203:
   1.642 +        checkMenuEntries(["aa", "aaz", "aa\xe6"], testNum);
   1.643 +        doKey("back_space");
   1.644 +        waitForMenuChange(5);
   1.645 +        break;
   1.646 +
   1.647 +    case 204:
   1.648 +        checkMenuEntries(["a", "aa", "aaz", "aa\xe6", "az"], testNum);
   1.649 +        input.focus();
   1.650 +        sendChar("z");
   1.651 +        waitForMenuChange(2);
   1.652 +        break;
   1.653 +
   1.654 +    case 205:
   1.655 +        checkMenuEntries(["az", "aaz"], testNum);
   1.656 +        input.focus();
   1.657 +        doKey("left");
   1.658 +        expectPopup();
   1.659 +        sendChar("a");
   1.660 +        break;
   1.661 +
   1.662 +    case 206:
   1.663 +        checkMenuEntries(["aaz"], testNum);
   1.664 +        addEntry("field3", "aazq");
   1.665 +        break;
   1.666 +
   1.667 +    case 207:
   1.668 +        input.focus();
   1.669 +        doKey("right");
   1.670 +        sendChar("q");
   1.671 +        waitForMenuChange(0);
   1.672 +        break;
   1.673 +
   1.674 +    case 208:
   1.675 +        // check that results were cached
   1.676 +        checkMenuEntries([], testNum);
   1.677 +        addEntry("field3", "aazqq");
   1.678 +        break;
   1.679 +
   1.680 +    case 209:
   1.681 +        input.focus();
   1.682 +        window.scrollTo(0, 0);
   1.683 +        sendChar("q");
   1.684 +        waitForScroll();
   1.685 +        break;
   1.686 +
   1.687 +    case 210:
   1.688 +        // check that empty results were cached - bug 496466
   1.689 +        checkMenuEntries([], testNum);
   1.690 +        doKey("escape");
   1.691 +
   1.692 +        // Look at form 6, try to trigger autocomplete popup
   1.693 +        input = $_(6, "field4");
   1.694 +        restoreForm();
   1.695 +        testNum = 249;
   1.696 +        expectPopup();
   1.697 +        input.focus();
   1.698 +        sendChar("a");
   1.699 +        break;
   1.700 +
   1.701 +    /* Test substring matches and word boundary bonuses */
   1.702 +
   1.703 +    case 250:
   1.704 +        // alphabetical results for first character
   1.705 +        checkMenuEntries(["aa a\xe6", "aba\xe6", "a\xe6"], testNum);
   1.706 +        input.focus();
   1.707 +
   1.708 +        // for this test, hide the popup first as it contains the same number of menu 
   1.709 +
   1.710 +        sendChar("\xc6");
   1.711 +        waitForMenuChange(3, "a\xe6");
   1.712 +        break;
   1.713 +
   1.714 +    case 251:
   1.715 +        // prefix match comes first, then word boundary match
   1.716 +        // followed by substring match
   1.717 +        checkMenuEntries(["a\xe6", "aa a\xe6", "aba\xe6"], testNum);
   1.718 +
   1.719 +        restoreForm();
   1.720 +        input.focus();
   1.721 +        sendChar("b");
   1.722 +        waitForMenuChange(1, "bc d\xe6");
   1.723 +        break;
   1.724 +
   1.725 +    case 252:
   1.726 +        checkMenuEntries(["bc d\xe6"], testNum);
   1.727 +        input.focus();
   1.728 +        sendChar(" ");
   1.729 +        setTimeout(runTest, 300);
   1.730 +        break;
   1.731 +
   1.732 +    case 253:
   1.733 +        // check that trailing space has no effect after single char.
   1.734 +        checkMenuEntries(["bc d\xe6"], testNum);
   1.735 +        input.focus();
   1.736 +        sendChar("\xc6");
   1.737 +        waitForMenuChange(2);
   1.738 +        break;
   1.739 +
   1.740 +    case 254:
   1.741 +        // check multi-word substring matches
   1.742 +        checkMenuEntries(["bc d\xe6", "aba\xe6"]);
   1.743 +        input.focus();
   1.744 +        expectPopup();
   1.745 +        doKey("left");
   1.746 +        sendChar("d");
   1.747 +        break;
   1.748 +
   1.749 +    case 255:
   1.750 +        // check inserting in multi-word searches
   1.751 +        checkMenuEntries(["bc d\xe6"], testNum);
   1.752 +        input.focus();
   1.753 +        sendChar("z");
   1.754 +        waitForMenuChange(0);
   1.755 +        break;
   1.756 +
   1.757 +    case 256:
   1.758 +        checkMenuEntries([], testNum);
   1.759 +
   1.760 +        // Look at form 7, try to trigger autocomplete popup
   1.761 +        input = $_(7, "field5");
   1.762 +        testNum = 299;
   1.763 +        expectPopup();
   1.764 +        restoreForm();
   1.765 +        doKey("down");
   1.766 +        break;
   1.767 +
   1.768 +    case 300:
   1.769 +        checkMenuEntries(["1", "12", "123", "1234"], testNum);
   1.770 +        input.maxLength = 4;
   1.771 +        expectPopup();
   1.772 +        doKey("escape");
   1.773 +        doKey("down");
   1.774 +        break;
   1.775 +
   1.776 +    case 301:
   1.777 +        checkMenuEntries(["1", "12", "123", "1234"], testNum);
   1.778 +        input.maxLength = 3;
   1.779 +        expectPopup();
   1.780 +        doKey("escape");
   1.781 +        doKey("down");
   1.782 +        break;
   1.783 +
   1.784 +    case 302:
   1.785 +        checkMenuEntries(["1", "12", "123"], testNum);
   1.786 +        input.maxLength = 2;
   1.787 +        expectPopup();
   1.788 +        doKey("escape");
   1.789 +        doKey("down");
   1.790 +        break;
   1.791 +
   1.792 +    case 303:
   1.793 +        checkMenuEntries(["1", "12"], testNum);
   1.794 +        input.maxLength = 1;
   1.795 +        expectPopup();
   1.796 +        doKey("escape");
   1.797 +        doKey("down");
   1.798 +        break;
   1.799 +
   1.800 +    case 304:
   1.801 +        checkMenuEntries(["1"], testNum);
   1.802 +        input.maxLength = 0;
   1.803 +        doKey("escape");
   1.804 +        doKey("down");
   1.805 +        waitForMenuChange(0);
   1.806 +        break;
   1.807 +
   1.808 +    case 305:
   1.809 +        checkMenuEntries([], testNum);
   1.810 +        input.maxLength = 4;
   1.811 +
   1.812 +        // now again with a character typed
   1.813 +        input.focus();
   1.814 +        sendChar("1");
   1.815 +        expectPopup();
   1.816 +        doKey("escape");
   1.817 +        doKey("down");
   1.818 +        break;
   1.819 +
   1.820 +    case 306:
   1.821 +        checkMenuEntries(["1", "12", "123", "1234"], testNum);
   1.822 +        input.maxLength = 3;
   1.823 +        expectPopup();
   1.824 +        doKey("escape");
   1.825 +        doKey("down");
   1.826 +        break;
   1.827 +
   1.828 +    case 307:
   1.829 +        checkMenuEntries(["1", "12", "123"], testNum);
   1.830 +        input.maxLength = 2;
   1.831 +        expectPopup();
   1.832 +        doKey("escape");
   1.833 +        doKey("down");
   1.834 +        break;
   1.835 +
   1.836 +    case 308:
   1.837 +        checkMenuEntries(["1", "12"], testNum);
   1.838 +        input.maxLength = 1;
   1.839 +        expectPopup();
   1.840 +        doKey("escape");
   1.841 +        doKey("down");
   1.842 +        break;
   1.843 +
   1.844 +    case 309:
   1.845 +        checkMenuEntries(["1"], testNum);
   1.846 +        input.maxLength = 0;
   1.847 +        doKey("escape");
   1.848 +        doKey("down");
   1.849 +        waitForMenuChange(0);
   1.850 +        break;
   1.851 +
   1.852 +    case 310:
   1.853 +        checkMenuEntries([], testNum);
   1.854 +
   1.855 +        input = $_(8, "field6");
   1.856 +        testNum = 399;
   1.857 +        expectPopup();
   1.858 +        restoreForm();
   1.859 +        doKey("down");
   1.860 +        break;
   1.861 +
   1.862 +    case 400:
   1.863 +    case 401:
   1.864 +    case 402:
   1.865 +    case 403:
   1.866 +        checkMenuEntries(["value"], testNum);
   1.867 +        doKey("down");
   1.868 +        doKey("return");
   1.869 +        checkForm("value");
   1.870 +
   1.871 +        if (testNum == 400) {
   1.872 +          input = $_(9, "field7");
   1.873 +        } else if (testNum == 401) {
   1.874 +          input = $_(10, "field8");
   1.875 +        } else if (testNum == 402) {
   1.876 +          input = $_(11, "field9");
   1.877 +        } else if (testNum == 403) {
   1.878 +          input = $_(12, "field10");
   1.879 +        }
   1.880 +
   1.881 +        expectPopup();
   1.882 +        restoreForm();
   1.883 +        doKey("down");
   1.884 +        break;
   1.885 +
   1.886 +    case 404:
   1.887 +        checkMenuEntries(["42"], testNum);
   1.888 +        doKey("down");
   1.889 +        doKey("return");
   1.890 +        checkForm("42");
   1.891 +
   1.892 +        input = $_(14, "field11");
   1.893 +        restoreForm();
   1.894 +        expectPopup();
   1.895 +        doKey("down");
   1.896 +        break;
   1.897 +
   1.898 +    case 405:
   1.899 +        checkMenuEntries(["2010-10-10"]);
   1.900 +        doKey("down");
   1.901 +        doKey("return");
   1.902 +        checkForm("2010-10-10");
   1.903 +
   1.904 +        input = $_(15, "field12");
   1.905 +        restoreForm();
   1.906 +        expectPopup();
   1.907 +        doKey("down");
   1.908 +        break;
   1.909 +
   1.910 +    case 406:
   1.911 +        checkMenuEntries(["21:21"]);
   1.912 +        doKey("down");
   1.913 +        doKey("return");
   1.914 +        checkForm("21:21");
   1.915 +
   1.916 +        input = $_(16, "field13");
   1.917 +        restoreForm();
   1.918 +        doKey("down");
   1.919 +        waitForMenuChange(0);
   1.920 +        break;
   1.921 +
   1.922 +    case 407:
   1.923 +        checkMenuEntries([]); // type=range does not have a drop down menu
   1.924 +        doKey("down");
   1.925 +        doKey("return");
   1.926 +        checkForm("30"); // default (midway between minimum (0) and maximum (64)) - step
   1.927 +
   1.928 +        input = $_(17, "field14");
   1.929 +        restoreForm();
   1.930 +        waitForMenuChange(0);
   1.931 +        break;
   1.932 +
   1.933 +    case 408:
   1.934 +        checkMenuEntries([]); // type=color does not have a drop down menu
   1.935 +        checkForm("#000000"); // default color value
   1.936 +
   1.937 +        addEntry("field1", "value1");
   1.938 +        break;
   1.939 +
   1.940 +    case 409:
   1.941 +        input = $_(1, "field1");
   1.942 +        // Go to test 500.
   1.943 +        testNum = 499;
   1.944 +
   1.945 +        expectPopup();
   1.946 +        restoreForm();
   1.947 +        doKey("down");
   1.948 +        break;
   1.949 +
   1.950 +    // Check that the input event is fired.
   1.951 +    case 500:
   1.952 +      input.addEventListener("input", function(event) {
   1.953 +        input.removeEventListener("input", arguments.callee, false);
   1.954 +        ok(true, testNum + " oninput should have been received");
   1.955 +        ok(event.bubbles, testNum + " input event should bubble");
   1.956 +        ok(event.cancelable, testNum + " input event should be cancelable");
   1.957 +      }, false);
   1.958 +
   1.959 +      doKey("down");
   1.960 +      checkForm("");
   1.961 +      doKey("return");
   1.962 +      checkForm("value1");
   1.963 +      testNum = 599;
   1.964 +      setTimeout(runTest, 100);
   1.965 +      break;
   1.966 +
   1.967 +    case 600:
   1.968 +        // check we don't show autocomplete for searchbar-history
   1.969 +        input = $_(13, "searchbar-history");
   1.970 +
   1.971 +        // Trigger autocomplete popup
   1.972 +        checkForm("");
   1.973 +        restoreForm();
   1.974 +        doKey("down");
   1.975 +        waitForMenuChange(0);
   1.976 +        break;
   1.977 +
   1.978 +    case 601:
   1.979 +        checkMenuEntries([], testNum);
   1.980 +        SpecialPowers.removeAutoCompletePopupEventListener(window, "popupshown", popupShownListener);
   1.981 +        SimpleTest.finish();
   1.982 +        return;
   1.983 +
   1.984 +    default:
   1.985 +        ok(false, "Unexpected invocation of test #" + testNum);
   1.986 +        SpecialPowers.removeAutoCompletePopupEventListener(window, "popupshown", popupShownListener);
   1.987 +        SimpleTest.finish();
   1.988 +        return;
   1.989 +  }
   1.990 +}
   1.991 +
   1.992 +function addEntry(name, value)
   1.993 +{
   1.994 +  updateFormHistory({ op : "add", fieldname : name, value: value }, runTest);
   1.995 +}
   1.996 +
   1.997 +// Runs the next test when scroll event occurs
   1.998 +function waitForScroll()
   1.999 +{
  1.1000 +  addEventListener("scroll", function() {
  1.1001 +    if (!window.pageYOffset)
  1.1002 +      return;
  1.1003 +
  1.1004 +    removeEventListener("scroll", arguments.callee, false);
  1.1005 +    setTimeout(runTest, 50);
  1.1006 +  }, false);
  1.1007 +}
  1.1008 +
  1.1009 +function waitForMenuChange(expectedCount, expectedFirstValue)
  1.1010 +{
  1.1011 +  if (autocompleteMenu.tree.view.rowCount != expectedCount) {
  1.1012 +    SimpleTest.executeSoon(function () waitForMenuChange(expectedCount, expectedFirstValue));
  1.1013 +  }
  1.1014 +  else if (expectedFirstValue && autocompleteMenu.tree.view.rowCount > 1 &&
  1.1015 +           autocompleteMenu.tree.view.getValueAt(0, autocompleteMenu.tree.columns[0]) != expectedFirstValue) {
  1.1016 +    SimpleTest.executeSoon(function () waitForMenuChange(expectedCount, expectedFirstValue));
  1.1017 +  }
  1.1018 +  else {
  1.1019 +    runTest();
  1.1020 +  }
  1.1021 +}
  1.1022 +
  1.1023 +function checkMenuEntries(expectedValues, testNum) {
  1.1024 +    var actualValues = getMenuEntries();
  1.1025 +    is(actualValues.length, expectedValues.length, testNum + " Checking length of expected menu");
  1.1026 +    for (var i = 0; i < expectedValues.length; i++)
  1.1027 +        is(actualValues[i], expectedValues[i], testNum + " Checking menu entry #"+i);
  1.1028 +}
  1.1029 +
  1.1030 +function getMenuEntries() {
  1.1031 +    var entries = [];
  1.1032 +
  1.1033 +    // Could perhaps pull values directly from the controller, but it seems
  1.1034 +    // more reliable to test the values that are actually in the tree?
  1.1035 +    var column = autocompleteMenu.tree.columns[0];
  1.1036 +    var numRows = autocompleteMenu.tree.view.rowCount;
  1.1037 +    for (var i = 0; i < numRows; i++) {
  1.1038 +        entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
  1.1039 +    }
  1.1040 +    return entries;
  1.1041 +}
  1.1042 +
  1.1043 +function startTest() {
  1.1044 +    setupFormHistory(function() {
  1.1045 +        runTest();
  1.1046 +    });
  1.1047 +}
  1.1048 +
  1.1049 +window.onload = startTest;
  1.1050 +
  1.1051 +SimpleTest.waitForExplicitFinish();
  1.1052 +</script>
  1.1053 +</pre>
  1.1054 +</body>
  1.1055 +</html>
  1.1056 +

mercurial