Bug 1339745 - Sort the profile results for autocomplete popup by last used time, r=lchang
MozReview-Commit-ID: 8IIbJB39LI0
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -106,16 +106,18 @@ AutofillProfileAutoCompleteSearch.protot
});
return;
}
this._getAddresses({info, searchString}).then((addresses) => {
if (this.forceStop) {
return;
}
+ // Sort addresses by timeLastUsed for showing the lastest used address at top.
+ addresses.sort((a, b) => b.timeLastUsed - a.timeLastUsed);
let allFieldNames = FormAutofillContent.getAllFieldNames(focusedInput);
let result = new ProfileAutoCompleteResult(searchString,
info.fieldName,
allFieldNames,
addresses,
{});
--- a/browser/extensions/formautofill/test/mochitest/formautofill_common.js
+++ b/browser/extensions/formautofill/test/mochitest/formautofill_common.js
@@ -1,15 +1,16 @@
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SimpleTest.js */
/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
/* eslint-disable no-unused-vars */
"use strict";
let formFillChromeScript;
+let expectingPopup = null;
function setInput(selector, value) {
let input = document.querySelector("input" + selector);
input.value = value;
input.focus();
// "identifyAutofillFields" is invoked asynchronously in "focusin" event. We
// should make sure fields are ready for popup before doing tests.
@@ -93,25 +94,48 @@ async function checkAddresses(expectedAd
formFillChromeScript.addMessageListener("FormAutofillTest:areAddressesMatching", function onChecked(data) {
formFillChromeScript.removeMessageListener("FormAutofillTest:areAddressesMatching", onChecked);
resolve(data);
});
});
}
+// Utils for registerPopupShownListener(in satchel_common.js) that handles dropdown popup
+// Please call "initPopupListener()" in your test and "await expectPopup()"
+// if you want to wait for dropdown menu displayed.
+function expectPopup() {
+ info("expecting a popup");
+ return new Promise(resolve => {
+ expectingPopup = resolve;
+ });
+}
+
+function popupShownListener() {
+ info("popup shown for test ");
+ if (expectingPopup) {
+ expectingPopup();
+ expectingPopup = null;
+ }
+}
+
+function initPopupListener() {
+ registerPopupShownListener(popupShownListener);
+}
+
function formAutoFillCommonSetup() {
let chromeURL = SimpleTest.getTestFileURL("formautofill_parent_utils.js");
formFillChromeScript = SpecialPowers.loadChromeScript(chromeURL);
formFillChromeScript.addMessageListener("onpopupshown", ({results}) => {
gLastAutoCompleteResults = results;
if (gPopupShownListener) {
gPopupShownListener({results});
}
});
SimpleTest.registerCleanupFunction(() => {
formFillChromeScript.sendAsyncMessage("cleanup");
formFillChromeScript.destroy();
+ expectingPopup = null;
});
}
formAutoFillCommonSetup();
--- a/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html
@@ -14,58 +14,42 @@ Form autofill test: autocomplete on an a
<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 MOCK_STORAGE = [{
organization: "Sesame Street",
"street-address": "123 Sesame Street.",
tel: "1-345-345-3456",
}, {
organization: "Mozilla",
"street-address": "331 E. Evelyn Avenue",
tel: "1-650-903-0800",
}];
-function expectPopup() {
- info("expecting a popup");
- return new Promise(resolve => {
- expectingPopup = resolve;
- });
-}
-
-function popupShownListener() {
- info("popup shown for test ");
- if (expectingPopup) {
- expectingPopup();
- expectingPopup = null;
- }
-}
+initPopupListener();
async function setupAddressStorage() {
await addAddress(MOCK_STORAGE[0]);
await addAddress(MOCK_STORAGE[1]);
}
add_task(async function check_autocomplete_on_autofocus_field() {
await setupAddressStorage();
doKey("down");
await expectPopup();
checkMenuEntries(MOCK_STORAGE.map(address =>
JSON.stringify({primary: address.organization, secondary: address["street-address"]})
));
});
-registerPopupShownListener(popupShownListener);
-
</script>
<p id="display"></p>
<div id="content">
<form id="form1">
<p>This is a basic form.</p>
--- a/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html
@@ -14,44 +14,28 @@ Form autofill test: simple form address
<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 MOCK_STORAGE = [{
organization: "Sesame Street",
"street-address": "123 Sesame Street.",
tel: "1-345-345-3456",
country: "US",
}, {
organization: "Mozilla",
"street-address": "331 E. Evelyn Avenue",
tel: "1-650-903-0800",
country: "US",
}];
-function expectPopup() {
- info("expecting a popup");
- return new Promise(resolve => {
- expectingPopup = resolve;
- });
-}
-
-function popupShownListener() {
- info("popup shown for test ");
- if (expectingPopup) {
- expectingPopup();
- expectingPopup = null;
- }
-}
-
function checkElementFilled(element, expectedvalue) {
return [
new Promise(resolve => {
element.addEventListener("input", function onInput() {
ok(true, "Checking " + element.name + " field fires input event");
resolve();
}, {once: true});
}),
@@ -95,16 +79,18 @@ async function setupAddressStorage() {
async function setupFormHistory() {
await updateFormHistory([
{op: "add", fieldname: "tel", value: "1-234-567-890"},
{op: "add", fieldname: "email", value: "foo@mozilla.com"},
]);
}
+initPopupListener();
+
// Form with history only.
add_task(async function history_only_menu_checking() {
await setupFormHistory();
await setInput("#tel", "");
doKey("down");
await expectPopup();
checkMenuEntries(["1-234-567-890"], false);
@@ -171,18 +157,16 @@ add_task(async function check_form_autof
await setInput("#tel", "");
doKey("down");
await expectPopup();
checkMenuEntries(MOCK_STORAGE.map(address =>
JSON.stringify({primary: address.tel, secondary: address["street-address"]})
));
});
-registerPopupShownListener(popupShownListener);
-
</script>
<p id="display"></p>
<div id="content">
<form id="form1">
<p>This is a basic form.</p>
--- a/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html
+++ b/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html
@@ -14,45 +14,29 @@ Form autofill test: preview and highligh
<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`);
@@ -97,16 +81,18 @@ function confirmAllFieldsFilled(address)
pendingPromises.push(new Promise(resolve => {
element.addEventListener("change", resolve, {once: true});
}));
}
return Promise.all(pendingPromises);
}
+initPopupListener();
+
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]);
});
@@ -148,18 +134,16 @@ add_task(async function check_filled_hig
// 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>
--- a/browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
+++ b/browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
@@ -24,17 +24,19 @@ let TEST_ADDRESSES = [{
"street-address": "123 Sesame Street.",
tel: "1-345-345-3456",
}, {
organization: "Mozilla",
"street-address": "331 E. Evelyn Avenue",
tel: "1-650-903-0800",
}];
-// Autofill the address from dropdown menu.
+initPopupListener();
+
+// Submit first address for saving.
add_task(async function check_storage_after_form_submitted() {
// We already verified the first time use case in browser test
await SpecialPowers.pushPrefEnv({
set: [["extensions.formautofill.firstTimeUse", false]],
});
for (let key in TEST_ADDRESSES[0]) {
await setInput("#" + key, TEST_ADDRESSES[0][key]);
@@ -45,16 +47,42 @@ add_task(async function check_storage_af
let expectedAddresses = TEST_ADDRESSES.slice(0, 1);
await onAddressChanged("add");
// Check if timesUsed is set correctly
expectedAddresses[0].timesUsed = 1;
let matching = await checkAddresses(expectedAddresses);
ok(matching, "Address saved as expected");
});
+// Submit another new address.
+add_task(async function check_storage_after_another_address_submitted() {
+ document.querySelector("form").reset();
+ for (let key in TEST_ADDRESSES[1]) {
+ await setInput("#" + key, TEST_ADDRESSES[1][key]);
+ }
+
+ clickOnElement("input[type=submit]");
+
+ // The 2nd test address should be on the top since it's the last used one.
+ let addressesInMenu = TEST_ADDRESSES.slice(1);
+ addressesInMenu.push(TEST_ADDRESSES[0]);
+
+ // let expectedAddresses = TEST_ADDRESSES.slice(0);
+ await onAddressChanged("add");
+ let matching = await checkAddresses(TEST_ADDRESSES);
+ ok(matching, "New address saved as expected");
+
+ await setInput("#organization", "");
+ doKey("down");
+ await expectPopup();
+ checkMenuEntries(addressesInMenu.map(address =>
+ JSON.stringify({primary: address.organization, secondary: address["street-address"]})
+ ));
+});
+
</script>
<div>
<form onsubmit="return false">
<p>This is a basic form for submitting test.</p>
<p><label>organization: <input id="organization" name="organization" autocomplete="organization" type="text"></label></p>
<p><label>streetAddress: <input id="street-address" name="street-address" autocomplete="street-address" type="text"></label></p>