Bug 1555210 - eTLD+1 matches for the same subdomain should appear before other subdomains. r=sfoster
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Fri, 07 Jun 2019 06:28:18 +0000
changeset 477772 1960eb24ea2bece7d509ed144341bd4dc35fe6da
parent 477771 b14d350405170852b8396de1331d4f4c2aa777c7
child 477773 a8e20517d31154bcbc582ceeeeef8f4be0b3f554
push id87347
push usermozilla@noorenberghe.ca
push dateFri, 07 Jun 2019 07:04:40 +0000
treeherderautoland@1960eb24ea2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs1555210
milestone69.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 1555210 - eTLD+1 matches for the same subdomain should appear before other subdomains. r=sfoster Differential Revision: https://phabricator.services.mozilla.com/D33746
toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
--- a/toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
+++ b/toolkit/components/passwordmgr/LoginAutoCompleteResult.jsm
@@ -35,17 +35,26 @@ XPCOMUtils.defineLazyPreferenceGetter(th
 
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   return LoginHelper.createLogger("LoginAutoCompleteResult");
 });
 XPCOMUtils.defineLazyGetter(this, "passwordMgrBundle", () => {
   return Services.strings.createBundle("chrome://passwordmgr/locale/passwordmgr.properties");
 });
 
-function loginSort(a, b) {
+function loginSort(formHostPort, a, b) {
+  let maybeHostPortA = LoginHelper.maybeGetHostPortForURL(a.origin);
+  let maybeHostPortB = LoginHelper.maybeGetHostPortForURL(b.origin);
+  if (formHostPort == maybeHostPortA && formHostPort != maybeHostPortB) {
+    return -1;
+  }
+  if (formHostPort != maybeHostPortA && formHostPort == maybeHostPortB) {
+    return 1;
+  }
+
   let userA = a.username.toLowerCase();
   let userB = b.username.toLowerCase();
 
   if (userA < userB) {
     return -1;
   }
 
   if (userA > userB) {
@@ -168,17 +177,17 @@ class LoginsFooterAutocompleteItem exten
     XPCOMUtils.defineLazyGetter(this, "label", () => {
       return getLocalizedString("viewSavedLogins.label");
     });
   }
 }
 
 
 // nsIAutoCompleteResult implementation
-function LoginAutoCompleteResult(aSearchString, matchingLogins, {
+function LoginAutoCompleteResult(aSearchString, matchingLogins, formHostPort, {
   generatedPassword,
   isSecure,
   messageManager,
   isPasswordField,
   hostname,
 }) {
   let hidingFooterOnPWFieldAutoOpened = false;
   function isFooterEnabled() {
@@ -212,17 +221,17 @@ function LoginAutoCompleteResult(aSearch
   this._rows = [];
 
   // Insecure field warning comes first if it applies and is enabled.
   if (!isSecure && LoginHelper.showInsecureFieldWarning) {
     this._rows.push(new InsecureLoginFormAutocompleteItem());
   }
 
   // Saved login items
-  let logins = matchingLogins.sort(loginSort);
+  let logins = matchingLogins.sort(loginSort.bind(null, formHostPort));
   let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "medium" });
   let duplicateUsernames = findDuplicates(matchingLogins);
   for (let login of logins) {
     let item = new LoginAutocompleteItem(login, isPasswordField, dateAndTimeFormatter,
                                          duplicateUsernames, messageManager);
     this._rows.push(item);
   }
 
@@ -373,19 +382,19 @@ LoginAutoComplete.prototype = {
       logins,
       messageManager,
     }) => {
       // If the search was canceled before we got our
       // results, don't bother reporting them.
       if (this._autoCompleteLookupPromise !== autoCompleteLookupPromise) {
         return;
       }
-
+      let formHostPort = LoginHelper.maybeGetHostPortForURL(aElement.ownerDocument.documentURI);
       this._autoCompleteLookupPromise = null;
-      let results = new LoginAutoCompleteResult(aSearchString, logins, {
+      let results = new LoginAutoCompleteResult(aSearchString, logins, formHostPort, {
         generatedPassword,
         messageManager,
         isSecure,
         isPasswordField,
         hostname,
       });
       aCallback.onSearchCompletion(results);
     };
--- a/toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
+++ b/toolkit/components/passwordmgr/test/unit/test_login_autocomplete_result.js
@@ -8,18 +8,18 @@ let matchingLogins = [];
 matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                     "", "emptypass1", "uname", "pword"));
 
 matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                     "tempuser1", "temppass1", "uname", "pword"));
 
 matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                     "testuser2", "testpass2", "uname", "pword"));
-
-matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
+// subdomain:
+matchingLogins.push(new nsLoginInfo("http://sub.mochi.test:8888", "http://autocomplete:8888", null,
                                     "testuser3", "testpass3", "uname", "pword"));
 
 matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                     "zzzuser4", "zzzpass4", "uname", "pword"));
 
 add_task(async function setup() {
   // Get a profile so we have storage access and insert the logins to get unique GUIDs.
   do_get_profile();
@@ -50,26 +50,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -109,26 +109,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -146,26 +146,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -188,26 +188,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -225,26 +225,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -262,26 +262,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -299,26 +299,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -336,26 +336,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -373,26 +373,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -415,26 +415,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -452,26 +452,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -494,26 +494,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -531,26 +531,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -593,26 +593,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testuser2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testuser3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzuser4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -630,26 +630,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: false,
@@ -667,26 +667,26 @@ add_task(async function test_all_pattern
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
         value: "testpass2",
         label: "testuser2",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
-        value: "testpass3",
-        label: "testuser3",
-        style: "loginWithOrigin",
-        comment: { comment: "mochi.test:8888" },
-      }, {
         value: "zzzpass4",
         label: "zzzuser4",
         style: "loginWithOrigin",
         comment: { comment: "mochi.test:8888" },
       }, {
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
         value: "",
         label: "View Saved Logins",
         style: "loginsFooter",
         comment: "mochi.test",
       }],
     },
     {
       insecureFieldWarningEnabled: true,
@@ -730,32 +730,111 @@ add_task(async function test_all_pattern
       generatedPassword: "9ljgfd4shyktb45",
       insecureFieldWarningEnabled: true,
       isSecure: true,
       isPasswordField: true,
       matchingLogins: [],
       searchString: "9ljgfd4shyktb45",
       items: [],
     },
+    {
+      description: "secure username field on sub.mochi.test",
+      formHostPort: "sub.mochi.test:8888",
+      insecureFieldWarningEnabled: true,
+      isSecure: true,
+      isPasswordField: false,
+      matchingLogins,
+      items: [{
+        value: "testuser3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
+        value: "",
+        label: LABEL_NO_USERNAME,
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "tempuser1",
+        label: "tempuser1",
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "testuser2",
+        label: "testuser2",
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "zzzuser4",
+        label: "zzzuser4",
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "",
+        label: "View Saved Logins",
+        style: "loginsFooter",
+        comment: "mochi.test",
+      }],
+    },
+    {
+      description: "secure password field on sub.mochi.test",
+      formHostPort: "sub.mochi.test:8888",
+      insecureFieldWarningEnabled: true,
+      isSecure: true,
+      isPasswordField: true,
+      matchingLogins,
+      items: [{
+        value: "testpass3",
+        label: "testuser3",
+        style: "loginWithOrigin",
+        comment: { comment: "sub.mochi.test:8888" },
+      }, {
+        value: "emptypass1",
+        label: LABEL_NO_USERNAME,
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "temppass1",
+        label: "tempuser1",
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "testpass2",
+        label: "testuser2",
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "zzzpass4",
+        label: "zzzuser4",
+        style: "loginWithOrigin",
+        comment: { comment: "mochi.test:8888" },
+      }, {
+        value: "",
+        label: "View Saved Logins",
+        style: "loginsFooter",
+        comment: "mochi.test",
+      }],
+    },
   ];
 
   LoginHelper.createLogger("LoginAutoCompleteResult");
   Services.prefs.setBoolPref("signon.showAutoCompleteFooter", true);
   Services.prefs.setBoolPref("signon.showAutoCompleteOrigins", true);
 
   expectedResults.forEach(pattern => {
     info(JSON.stringify(pattern, null, 2));
     Services.prefs.setBoolPref(PREF_INSECURE_FIELD_WARNING_ENABLED,
                                pattern.insecureFieldWarningEnabled);
-    let actual = new LoginAutoCompleteResult(pattern.searchString || "", pattern.matchingLogins, {
-      hostname: "mochi.test",
-      generatedPassword: pattern.generatedPassword,
-      isSecure: pattern.isSecure,
-      isPasswordField: pattern.isPasswordField,
-    });
+    let actual = new LoginAutoCompleteResult(pattern.searchString || "", pattern.matchingLogins,
+                                             pattern.formHostPort || "mochi.test:8888", {
+                                               hostname: "mochi.test",
+                                               generatedPassword: pattern.generatedPassword,
+                                               isSecure: pattern.isSecure,
+                                               isPasswordField: pattern.isPasswordField,
+                                             });
     equal(actual.matchCount, pattern.items.length, "Check matching row count");
     pattern.items.forEach((item, index) => {
       equal(actual.getValueAt(index), item.value, `Value ${index}`);
       equal(actual.getLabelAt(index), item.label, `Label ${index}`);
       equal(actual.getStyleAt(index), item.style, `Style ${index}`);
       let actualComment = actual.getCommentAt(index);
       if (typeof(item.comment) == "object") {
         let parsedComment = JSON.parse(actualComment);