Bug 1300996 - Part 4: Add mochitest for form autofill preview and highlight. r=MattN, lchang
☠☠ backed out by 520ab29a56de ☠ ☠
authorRay Lin <ralin@mozilla.com>
Wed, 17 May 2017 17:56:55 +0800
changeset 413141 221b17bc902aa06c1f2800ce2c3ef7d7d24cba1f
parent 413140 71ef10fe925e44b0b3e3ad10efeab9931d7bf39e
child 413142 aafc907d2aaeae386c18fae09d0ecd88f6122b97
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN, lchang
bugs1300996
milestone55.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 1300996 - Part 4: Add mochitest for form autofill preview and highlight. r=MattN, lchang MozReview-Commit-ID: JLksdYY5cr1
browser/extensions/formautofill/test/mochitest/formautofill_common.js
browser/extensions/formautofill/test/mochitest/mochitest.ini
browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html
--- a/browser/extensions/formautofill/test/mochitest/formautofill_common.js
+++ b/browser/extensions/formautofill/test/mochitest/formautofill_common.js
@@ -12,17 +12,20 @@ function setInput(selector, value) {
   input.focus();
 
   // "identifyAutofillFields" is invoked asynchronously in "focusin" event. We
   // should make sure fields are ready for popup before doing tests.
   //
   // TODO: "setTimeout" is used here temporarily because there's no event to
   //       notify us of the state of "identifyAutofillFields" for now. We should
   //       figure out a better way after the heuristics land.
-  return new Promise(resolve => setTimeout(resolve));
+  SimpleTest.requestFlakyTimeout("Guarantee asynchronous identifyAutofillFields is invoked");
+  return new Promise(resolve => setTimeout(() => {
+    resolve(input);
+  }, 500));
 }
 
 function checkMenuEntries(expectedValues) {
   let actualValues = getMenuEntries();
 
   is(actualValues.length, expectedValues.length, " Checking length of expected menu");
   for (let i = 0; i < expectedValues.length; i++) {
     is(actualValues[i], expectedValues[i], " Checking menu entry #" + i);
--- a/browser/extensions/formautofill/test/mochitest/mochitest.ini
+++ b/browser/extensions/formautofill/test/mochitest/mochitest.ini
@@ -2,8 +2,9 @@
 support-files =
   ../../../../../toolkit/components/satchel/test/satchel_common.js
   ../../../../../toolkit/components/satchel/test/parent_utils.js
   formautofill_common.js
   formautofill_parent_utils.js
 
 [test_autofocus_form.html]
 [test_basic_autocomplete_form.html]
+[test_formautofill_preview_highlight.html]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html
@@ -0,0 +1,171 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test form autofill - preview and highlight</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="formautofill_common.js"></script>
+  <script type="text/javascript" src="satchel_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+Form autofill test: preview and highlight
+
+<script>
+/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
+/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
+/* import-globals-from formautofill_common.js */
+
+"use strict";
+
+let expectingPopup = null;
+let defaultTextColor;
+const MOCK_STORAGE = [{
+  organization: "Sesame Street",
+  "street-address": "123 Sesame Street.",
+  tel: "1-345-345-3456",
+}, {
+  organization: "Mozilla",
+  "street-address": "331 E. Evelyn Avenue",
+}, {
+  organization: "Tel org",
+  tel: "2-222-333-444",
+}];
+
+function expectPopup() {
+  info("expecting a popup");
+  return new Promise(resolve => {
+    expectingPopup = resolve;
+  });
+}
+
+function popupShownListener() {
+  info("popup shown for test ");
+  if (expectingPopup) {
+    expectingPopup();
+    expectingPopup = null;
+  }
+}
+
+// We could not get ManuallyManagedState of element now, so directly check if
+// filter and text color style are applied.
+function checkFieldPreview(elem, expectedText) {
+  const computedStyle = window.getComputedStyle(elem);
+  const isStyleApplied = computedStyle.getPropertyValue("filter") !== "none" &&
+                         computedStyle.getPropertyValue("color") !== defaultTextColor;
+
+  is(SpecialPowers.wrap(elem).previewValue, expectedText, `Checking #${elem.id} previewValue`);
+  is(isStyleApplied, !!expectedText, `Checking #${elem.id} preview style`);
+}
+
+function checkFilledFieldHighlight(elem, expectedValue) {
+  const computedStyle = window.getComputedStyle(elem);
+  const isStyleApplied = computedStyle.getPropertyValue("filter") !== "none" &&
+                         computedStyle.getPropertyValue("color") === defaultTextColor;
+
+  is(SpecialPowers.wrap(elem).previewValue, "", `Checking #${elem.id} filled previewValue`);
+  is(expectedValue, isStyleApplied, `Checking #${elem.id} filled style`);
+}
+
+function checkFormPreviewFields(previewingAddress) {
+  const inputs = document.querySelectorAll("input");
+
+  for (const input of inputs) {
+    const previewValue = previewingAddress && previewingAddress[input.id] || "";
+
+    checkFieldPreview(input, previewValue);
+  }
+}
+
+function checkFormFilledFields(address) {
+  const inputs = document.querySelectorAll("input");
+
+  for (const input of inputs) {
+    const isFilledByAutofill = !!address[input.id];
+
+    checkFilledFieldHighlight(input, isFilledByAutofill);
+  }
+}
+
+function confirmAllFieldsFilled(address) {
+  const pendingPromises = [];
+
+  for (const prop in address) {
+    const element = document.getElementById(prop);
+
+    pendingPromises.push(new Promise(resolve => {
+      element.addEventListener("change", resolve, {once: true});
+    }));
+  }
+
+  return Promise.all(pendingPromises);
+}
+
+add_task(async function setup_storage() {
+  defaultTextColor = window.getComputedStyle(document.querySelector("input")).getPropertyValue("color");
+
+  await addAddress(MOCK_STORAGE[0]);
+  await addAddress(MOCK_STORAGE[1]);
+  await addAddress(MOCK_STORAGE[2]);
+});
+
+add_task(async function check_preview() {
+  const focusedInput = await setInput("#organization", "");
+
+  doKey("down");
+  await expectPopup();
+  checkFormPreviewFields();
+
+  for (let i = 0; i < MOCK_STORAGE.length; i++) {
+    doKey("down");
+    await notifySelectedIndex(i);
+    checkFormPreviewFields(MOCK_STORAGE[i]);
+  }
+
+  doKey("down");
+  await notifySelectedIndex(-1);
+  checkFormPreviewFields();
+
+  focusedInput.blur();
+});
+
+add_task(async function check_filled_highlight() {
+  const focusedInput = await setInput("#organization", "");
+
+  doKey("down");
+  await expectPopup();
+
+  doKey("down");
+  await notifySelectedIndex(0);
+  const waitForFilled = confirmAllFieldsFilled(MOCK_STORAGE[0]);
+
+  // filled 1st address
+  doKey("return");
+  // blur to fire off change event from focusedInput
+  focusedInput.blur();
+  await waitForFilled;
+  checkFormFilledFields(MOCK_STORAGE[0]);
+});
+
+registerPopupShownListener(popupShownListener);
+
+</script>
+
+<p id="display"></p>
+
+<div id="content">
+
+  <form id="form1">
+    <p>This is a basic form.</p>
+    <p><label>organization: <input id="organization" autocomplete="organization"></label></p>
+    <p><label>streetAddress: <input id="street-address" autocomplete="street-address"></label></p>
+    <p><label>tel: <input id="tel" autocomplete="tel"></label></p>
+    <p><label>country: <input id="country" autocomplete="country"></label></p>
+  </form>
+
+</div>
+
+<pre id="test"></pre>
+</body>
+</html>